diff --git a/gb.net.curl/src/CCurl.c b/gb.net.curl/src/CCurl.c index 9dc6e7ac6..6c779dd47 100644 --- a/gb.net.curl/src/CCurl.c +++ b/gb.net.curl/src/CCurl.c @@ -38,11 +38,40 @@ #include "CCurl.h" #include "CProxy.h" +DECLARE_EVENT(EVENT_FINISHED); +DECLARE_EVENT(EVENT_ERROR); +DECLARE_EVENT(EVENT_CONNECT); +DECLARE_EVENT(EVENT_READ); -DECLARE_EVENT (EVENT_FINISHED); -DECLARE_EVENT (EVENT_ERROR); -DECLARE_EVENT (EVENT_CONNECT); -DECLARE_EVENT (EVENT_READ); +static CCURL *_async_list = NULL; + +static void add_to_async_list(CCURL *_object) +{ + if (THIS->in_list) + return; + + #ifdef DEBUG + fprintf(stderr, "add_to_async_list: %p\n", THIS); + #endif + + GB.List.Add(&_async_list, THIS, &THIS->list); + THIS->in_list = TRUE; + GB.Ref(THIS); +} + +static void remove_from_async_list(CCURL *_object) +{ + if (!THIS->in_list) + return; + + #ifdef DEBUG + fprintf(stderr, "remove_from_async_list: %p\n", THIS); + #endif + + GB.List.Remove(&_async_list, THIS, &THIS->list); + THIS->in_list = FALSE; + GB.Unref(POINTER(&_object)); +} /***************************************************** CURLM : a pointer to use curl_multi interface, @@ -198,9 +227,6 @@ void CURL_manage_error(void *_object, int error) THIS_STATUS = (- (1000 + error)); break; } - - if (THIS->async) - GB.Unref(POINTER(&_object)); } void CURL_init_stream(void *_object) @@ -262,29 +288,34 @@ static void CCURL_post_curl(intptr_t data) void CURL_stop(void *_object) { + if (THIS_STATUS == NET_INACTIVE) + return; + + if (THIS_CURL) + { + #if DEBUG + fprintf(stderr, "-- CURL_stop: [%p] curl_multi_remove_handle(%p)\n", THIS, THIS_CURL); + #endif + curl_multi_remove_handle(CCURL_multicurl,THIS_CURL); + #if DEBUG + fprintf(stderr, "-- CURL_stop: [%p] curl_easy_cleanup(%p)\n", THIS, THIS_CURL); + #endif + curl_easy_cleanup(THIS_CURL); + THIS_CURL = NULL; + } + if (THIS_FILE) { fclose(THIS_FILE); THIS_FILE = NULL; } - if (THIS_CURL) - { - #if DEBUG - fprintf(stderr, "-- [%p] curl_multi_remove_handle(%p)\n", THIS, THIS_CURL); - #endif - curl_multi_remove_handle(CCURL_multicurl,THIS_CURL); - #if DEBUG - fprintf(stderr, "-- [%p] curl_easycleanup(%p)\n", THIS, THIS_CURL); - #endif - curl_easy_cleanup(THIS_CURL); - THIS_CURL = NULL; - } - THIS_STATUS = NET_INACTIVE; + + remove_from_async_list(THIS); } -static void Curl_init_post(void) +static void init_post(void) { if (CCURL_pipe[0]!=-1) return; @@ -301,9 +332,9 @@ static void Curl_init_post(void) void CURL_start_post(void *_object) { - Curl_init_post(); + init_post(); curl_multi_add_handle(CCURL_multicurl, THIS_CURL); - GB.Ref(THIS); + add_to_async_list(THIS); } bool CURL_check_active(void *_object) @@ -471,19 +502,10 @@ BEGIN_METHOD_VOID(Curl_free) fprintf(stderr, "Curl_free: %p\n", THIS); #endif + CURL_stop(THIS); + GB.FreeString(&THIS_URL); - if (THIS_FILE) - fclose(THIS_FILE); - - if (THIS_CURL) - { - #if DEBUG - fprintf(stderr, "-- [%p] curl_easy_cleanup(%p)\n", THIS, THIS_CURL); - #endif - curl_easy_cleanup(THIS_CURL); - } - CURL_user_clear(&THIS->user); CURL_proxy_clear(&THIS->proxy.proxy); @@ -500,9 +522,24 @@ END_METHOD BEGIN_METHOD_VOID(Curl_exit) + CCURL *curl, *next; + + #if DEBUG + fprintf(stderr, "-- CURL_exit: clear async list\n"); + #endif + + curl = _async_list; + while (curl) + { + next = curl->list.next; + remove_from_async_list(curl); + curl = next; + } + #if DEBUG fprintf(stderr, "-- curl_multi_cleanup()\n"); #endif + curl_multi_cleanup(CCURL_multicurl); END_METHOD diff --git a/gb.net.curl/src/CCurl.h b/gb.net.curl/src/CCurl.h index 00b2cd7ab..52572b2f3 100644 --- a/gb.net.curl/src/CCurl.h +++ b/gb.net.curl/src/CCurl.h @@ -58,17 +58,19 @@ typedef struct { GB_BASE ob; GB_STREAM stream; + GB_LIST list; // List of async curl objects int status; CURL *curl; char *url; FILE *file; CPROXY proxy; CURL_USER user; - bool async; int timeout; int method; // 0->Get, 1->Put - bool debug; char *data; + unsigned async : 1; + unsigned in_list : 1; + unsigned debug : 1; } CCURL; diff --git a/gb.net.curl/src/CFtpClient.c b/gb.net.curl/src/CFtpClient.c index c73a5b862..c254c63ff 100644 --- a/gb.net.curl/src/CFtpClient.c +++ b/gb.net.curl/src/CFtpClient.c @@ -116,7 +116,7 @@ static void ftp_initialize_curl_handle(void *_object) curl_easy_setopt(THIS_CURL, CURLOPT_TIMEOUT,THIS->timeout); } - curl_easy_setopt(THIS_CURL, CURLOPT_VERBOSE, THIS->debug); + curl_easy_setopt(THIS_CURL, CURLOPT_VERBOSE, (bool)THIS->debug); curl_easy_setopt(THIS_CURL, CURLOPT_PRIVATE,(char*)_object); CURL_proxy_set(&THIS->proxy.proxy,THIS_CURL); @@ -280,7 +280,7 @@ END_METHOD BEGIN_METHOD_VOID(FtpClient_free) - CURL_stop(_object); + //CURL_stop(_object); ftp_reset(THIS_FTP); END_METHOD diff --git a/gb.net.curl/src/CHttpClient.c b/gb.net.curl/src/CHttpClient.c index 666db934d..a162264d5 100644 --- a/gb.net.curl/src/CHttpClient.c +++ b/gb.net.curl/src/CHttpClient.c @@ -188,7 +188,7 @@ static void http_initialize_curl_handle(void *_object, GB_ARRAY custom_headers) curl_easy_setopt(THIS_CURL, CURLOPT_TIMEOUT,THIS->timeout); } - curl_easy_setopt(THIS_CURL, CURLOPT_VERBOSE, THIS->debug); + curl_easy_setopt(THIS_CURL, CURLOPT_VERBOSE, (bool)THIS->debug); curl_easy_setopt(THIS_CURL, CURLOPT_PRIVATE,(char*)_object); curl_easy_setopt(THIS_CURL, CURLOPT_USERAGENT, THIS_HTTP->sUserAgent); curl_easy_setopt(THIS_CURL, CURLOPT_ENCODING, THIS_HTTP->encoding); @@ -502,7 +502,7 @@ END_METHOD BEGIN_METHOD_VOID(HttpClient_free) - CURL_stop(_object); + //CURL_stop(_object); http_reset(THIS); GB.FreeString(&THIS_HTTP->sUserAgent);