aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Fandrich <dan@coneharvesters.com>2017-08-29 00:30:30 +0200
committerDan Fandrich <dan@coneharvesters.com>2017-08-29 00:35:19 +0200
commitdf29455dbce7f75f61339067c6f6ac43a9ff3fd7 (patch)
treef746abb7ecb2eb88c497bf859f4e9873646d5150
parentedcb1ef60fdbbd3d78d9c9265f1ce63360e87d7b (diff)
asyn-thread: Fixed cleanup after OOM
destroy_async_data() assumes that if the flag "done" is not set yet, the thread itself will clean up once the request is complete. But if an error (generally OOM) occurs before the thread even has a chance to start, it will never get a chance to clean up and memory will be leaked. By clearing "done" only just before starting the thread, the correct cleanup sequence will happen in all cases.
-rw-r--r--lib/asyn-thread.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
index c9f443167..a86772965 100644
--- a/lib/asyn-thread.c
+++ b/lib/asyn-thread.c
@@ -210,6 +210,10 @@ int init_thread_sync_data(struct thread_data * td,
tsd->td = td;
tsd->port = port;
+ /* Treat the request as done until the thread actually starts so any early
+ * cleanup gets done properly.
+ */
+ tsd->done = 1;
#ifdef HAVE_GETADDRINFO
DEBUGASSERT(hints);
tsd->hints = *hints;
@@ -403,6 +407,9 @@ static bool init_resolve_thread(struct connectdata *conn,
if(!conn->async.hostname)
goto err_exit;
+ /* The thread will set this to 1 when complete. */
+ td->tsd.done = 0;
+
#ifdef HAVE_GETADDRINFO
td->thread_hnd = Curl_thread_create(getaddrinfo_thread, &td->tsd);
#else
@@ -410,6 +417,8 @@ static bool init_resolve_thread(struct connectdata *conn,
#endif
if(!td->thread_hnd) {
+ /* The thread never started, so mark it as done here for proper cleanup. */
+ td->tsd.done = 1;
err = errno;
goto err_exit;
}