Robert Iakobashvili made curl_multi_remove_handle() a lot faster when many
authorDaniel Stenberg <daniel@haxx.se>
Sun, 1 Apr 2007 08:24:23 +0000 (08:24 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Sun, 1 Apr 2007 08:24:23 +0000 (08:24 +0000)
easy handles are added to a multi handle, by avoiding the looping over all
the handles to find which one to remove.

CHANGES
lib/multi.c
lib/urldata.h

diff --git a/CHANGES b/CHANGES
index e084e3a..7d4cf8f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,10 @@
                                   Changelog
 
 Daniel S (1 April 2007)
+- Robert Iakobashvili made curl_multi_remove_handle() a lot faster when many
+  easy handles are added to a multi handle, by avoiding the looping over all
+  the handles to find which one to remove.
+
 - Matt Kraai provided a patch that makes curl build on QNX 6 fine again.
 
 Daniel S (31 March 2007)
index ec9fd33..54037b3 100644 (file)
@@ -413,6 +413,9 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
   easy->easy_handle = easy_handle;
   multistate(easy, CURLM_STATE_INIT);
 
+  /* set the back pointer to one_easy to assist in removal */
+  easy->easy_handle->multi_pos =  easy;
+
   /* for multi interface connections, we share DNS cache automatically if the
      easy handle's one is currently private. */
   if (easy->easy_handle->dns.hostcache &&
@@ -516,13 +519,8 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
   if(!GOOD_EASY_HANDLE(curl_handle))
     return CURLM_BAD_EASY_HANDLE;
 
-  /* scan through the list and remove the 'curl_handle' */
-  easy = multi->easy.next;
-  while(easy != &multi->easy) {
-    if(easy->easy_handle == (struct SessionHandle *)curl_handle)
-      break;
-    easy=easy->next;
-  }
+  /* pick-up from the 'curl_handle' the kept position in the list */
+  easy = ((struct SessionHandle *)curl_handle)->multi_pos;
 
   if(easy) {
     bool premature = (bool)(easy->state != CURLM_STATE_COMPLETED);
@@ -626,6 +624,9 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
 
     easy->easy_handle->set.one_easy = NULL; /* detached */
 
+    /* Null the position in the controlling structure */
+    easy->easy_handle->multi_pos = NULL;
+
     /* NOTE NOTE NOTE
        We do not touch the easy handle here! */
     if (easy->msg)
index 2e13f60..879f369 100644 (file)
@@ -1342,6 +1342,9 @@ struct SessionHandle {
   struct Names dns;
   struct Curl_multi *multi;    /* if non-NULL, points to the multi handle
                                   struct to which this "belongs" */
+  struct Curl_one_easy *multi_pos; /* if non-NULL, points to the its position
+                                      in multi controlling structure to assist
+                                      in removal. */
   struct Curl_share *share;    /* Share, handles global variable mutexing */
   struct HandleData reqdata;   /* Request-specific data */
   struct UserDefined set;      /* values set by the libcurl user */