[GB.NET.CURL]
* BUG: Fix memory leaks when asynchronous clients are pending when quitting the program. git-svn-id: svn://localhost/gambas/trunk@5392 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
parent
76709ee739
commit
4512fa0c1d
4 changed files with 79 additions and 40 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue