diff options
author | Daniel Stenberg <daniel@haxx.se> | 2021-12-10 12:46:16 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2021-12-10 17:02:04 +0100 |
commit | e43ad4b47442c99c95f76675a17e608610231871 (patch) | |
tree | 1d006818f5437e5b23a76923d201a4e2c48b9d16 /lib | |
parent | 439aa502115e2129db71d0b2d5441eb3790e2cd3 (diff) | |
download | curl-e43ad4b47442c99c95f76675a17e608610231871.tar.gz |
multi: cleanup the socket hash when destroying itbagder/sockhash-destroy
Since each socket hash entry may themselves have a hash table in them,
the destroying of the socket hash needs to make sure all the subhashes
are also correctly destroyed to avoid leaking memory.
Fixes #8129
Closes #8131
Diffstat (limited to 'lib')
-rw-r--r-- | lib/multi.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/lib/multi.c b/lib/multi.c index c34780f73..2bda97223 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -243,6 +243,26 @@ static void trhash_dtor(void *nada) (void)nada; } +/* + * The sockhash has its own separate subhash in each entry that need to be + * safely destroyed first. + */ +static void sockhash_destroy(struct Curl_hash *h) +{ + struct Curl_hash_iterator iter; + struct Curl_hash_element *he; + + DEBUGASSERT(h); + Curl_hash_start_iterate(h, &iter); + he = Curl_hash_next_element(&iter); + while(he) { + struct Curl_sh_entry *sh = (struct Curl_sh_entry *)he->ptr; + Curl_hash_destroy(&sh->transfers); + he = Curl_hash_next_element(&iter); + } + Curl_hash_destroy(h); +} + /* make sure this socket is present in the hash for this handle */ static struct Curl_sh_entry *sh_addentry(struct Curl_hash *sh, @@ -405,7 +425,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ error: - Curl_hash_destroy(&multi->sockhash); + sockhash_destroy(&multi->sockhash); Curl_hash_destroy(&multi->hostcache); Curl_conncache_destroy(&multi->conn_cache); Curl_llist_destroy(&multi->msglist, NULL); @@ -554,7 +574,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, #if 0 /* Debug-function, used like this: * - * Curl_hash_print(multi->sockhash, debug_print_sock_hash); + * Curl_hash_print(&multi->sockhash, debug_print_sock_hash); * * Enable the hash print function first by editing hash.c */ @@ -562,8 +582,8 @@ static void debug_print_sock_hash(void *p) { struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p; - fprintf(stderr, " [easy %p/magic %x/socket %d]", - (void *)sh->data, sh->data->magic, (int)sh->socket); + fprintf(stderr, " [readers %u][writers %u]", + sh->readers, sh->writers); } #endif @@ -576,7 +596,8 @@ static CURLcode multi_done(struct Curl_easy *data, struct connectdata *conn = data->conn; unsigned int i; - DEBUGF(infof(data, "multi_done")); + DEBUGF(infof(data, "multi_done: status: %d prem: %d done: %d", + (int)status, (int)premature, data->state.done)); if(data->state.done) /* Stop if multi_done() has already been called */ @@ -2694,7 +2715,7 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi) /* Close all the connections in the connection cache */ Curl_conncache_close_all_connections(&multi->conn_cache); - Curl_hash_destroy(&multi->sockhash); + sockhash_destroy(&multi->sockhash); Curl_conncache_destroy(&multi->conn_cache); Curl_llist_destroy(&multi->msglist, NULL); Curl_llist_destroy(&multi->pending, NULL); |