multi_remove_handle: keep the timeout list until after disconnect
authorDaniel Stenberg <daniel@haxx.se>
Tue, 23 Feb 2016 12:05:41 +0000 (13:05 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 23 Feb 2016 12:08:11 +0000 (13:08 +0100)
The internal Curl_done() function uses Curl_expire() at times and that
uses the timeout list. Better clean up the list once we're done using
it. This caused a segfault.

Reported-by: 蔡文凱
Bug: https://curl.haxx.se/mail/lib-2016-02/0097.html

lib/multi.c

index 069412d4e88ccb4962fd306d624638ac2e60739c..ad7d21fea9b104e2e48a9f20e3b563d7f7068e1c 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -537,12 +537,6 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
      curl_easy_cleanup is called. */
   Curl_expire(data, 0);
 
-  /* destroy the timeout list that is held in the easy handle */
-  if(data->state.timeoutlist) {
-    Curl_llist_destroy(data->state.timeoutlist, NULL);
-    data->state.timeoutlist = NULL;
-  }
-
   if(data->dns.hostcachetype == HCACHE_MULTI) {
     /* stop using the multi handle's DNS cache */
     data->dns.hostcache = NULL;
@@ -569,6 +563,13 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
 
   Curl_wildcard_dtor(&data->wildcard);
 
+  /* destroy the timeout list that is held in the easy handle, do this *after*
+     Curl_done() as that may actuall call Curl_expire that uses this */
+  if(data->state.timeoutlist) {
+    Curl_llist_destroy(data->state.timeoutlist, NULL);
+    data->state.timeoutlist = NULL;
+  }
+
   /* as this was using a shared connection cache we clear the pointer to that
      since we're not part of that multi handle anymore */
   data->state.conn_cache = NULL;