curl-library
Memory leak using multi handle
Date: Mon, 27 Jun 2016 13:17:06 +0000
Hello,
I am using libcurl 7.44.0 with ssh enabled and am experiencing a memory
leak within libcurl when performing sftp upload/download.
My design uses a singleton C++ class running in a single thread to
perform libcurl upload/download functions. My code works for
uploading/downloading several files simultaneously. The only issue I am
experiencing is the memory leak. I have verified there are no leaks in
my code.
I verified no memory leaks occur when no files are transferred. That
may make me seem like captain obvious, but wanted to confirm I am
calling curl_global_init/cleanup properly.
The attached memdebug trace is what I am seeing after transferring
(upload) one file.
Below is pseudo-code that accurately captures my libcurl calls in
sequence.
To initiate a transfer an easy handle is setup, added to a multi handle
(allocated if need be), and a one time timer is started. When the timer
expires it call myCurlMultiPerform (essentially a wrapper for your
multi perform example). If the the transfer is not complete, then the
timer is re-started. When the the transfer is complete myProcessMsgs()
is called. If the message is done, then cleanup is performed and the
transfer is considered terminated.
/*
* pseudo-code call sequence
*/
curl_global_init(CURL_GLOBAL_ALL);
multiHandle = curl_multi_init();
easyHandle = curl_easy_init();
curl_multi_add_handle(multiHandle, easyHandle);
/* do upload */
curl_easy_setopt(client->easyHandle, CURLOPT_INTERFACE, intfc);
curl_easy_setopt(client->easyHandle, CURLOPT_URL, url);
curl_easy_setopt(client->easyHandle, CURLOPT_CONNECTTIMEOUT, 30);
curl_easy_setopt(client->easyHandle, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(client->easyHandle, CURLOPT_READDATA, fd);
/* start timer to call myCurlMultiPerform() */
start_onetime_timer();
...
myCurlMultiPerform()
{
curl_multi_fdset(multiHandle, &fdread, &fdwrite, &fdexcep, &maxfd);
select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); // 1 sec to
curl_multi_perform(multiHandle, &activeTransfers);
if (activeTransfers == 0)
myProcessMsgs(); // done
else
start_onetime_timer(); // not done
}
myTimeoutHandler()
{
myCurlMultiPerform();
}
myProcessMsgs()
{
while ((msg = curl_multi_info_read(multiHandle, &msgsLeft)))
{
if (msg->msg == CURLMSG_DONE)
{
if (msg->data.result == CURLE_OK)
// success
else
// error
myCurlCleanup();
}
}
}
myCurlCleanup()
{
curl_multi_remove_handle(multiHandle, easyHandle);
curl_easy_cleanup(easyHandle);
curl_multi_cleanup(multiHandle);
curl_global_cleanup();
exit(0);
}
--
Regards,
Dan Donahue
-------------------------------------------------------------------
List admin: https://cool.haxx.se/list/listinfo/curl-library
Etiquette: https://curl.haxx.se/mail/etiquette.html
- text/plain attachment: curl_memdebug_1ft.txt