From 6c6e4710b570eccdbae87fa9bd8df2f4940ac76d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 1 Apr 2007 08:24:23 +0000 Subject: [PATCH] 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. --- CHANGES | 4 ++++ lib/multi.c | 15 ++++++++------- lib/urldata.h | 3 +++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index e084e3a..7d4cf8f 100644 --- 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) diff --git a/lib/multi.c b/lib/multi.c index ec9fd33..54037b3 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -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) diff --git a/lib/urldata.h b/lib/urldata.h index 2e13f60..879f369 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -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 */ -- 2.7.4