curl-library
Best way to issue member-callback after curl_multi_info_read returns CURLMSG_DONE
Date: Mon, 18 Nov 2013 12:09:13 +0000
I'm looking for the best way to call a user provided callback function, once an easy_handle has been finished by multi_perform running in its own thread.
Since all the data I need is already set in the WRITEFUNCTION and WRITEDATA options of the easy_handle, I want to use these, instead of performing some kind of lookup.
Is there a way to retrieve those pointers, or manually execute the writefunction with different WRITEDATA pointer?
(In the default libcurl C-Interface, I'm using C/C++ without additional libcurl bindings.)
My Ideas are:
- Implement a curl_easy_getopt function or
- implement a curl_easy_call_writefunction(void* overrideWriteDataPtr) or
- Add a void* UserPtr to curl_multi_add_handle, which will be a visible member of CURLMsg* or
- Is there some kind of option to use with union{ void* whatever ...}; in CURLMsg that I am missing?
Since I'm planning to update libcurl to new versions, I would prefer a solution that doesn't require changes to its source.
Thank you for any ideas and feedback.
With Best Regards
Daniel
Here is a bit of pseudo code, that I hope will clarify what I want to do:
---------------------------------------------------------------------------------
//GLOBAL
HttpWorkerThread, HttpWorkerMutex, CurlMultiHandle
Struct HTTPRequest{
createHttpRequestNonBlocking(url, callback...){
CurlEasyHandle = curl_easy_init(), setopts: url, writefunction, writedata=this
Lock(HttpWorkerMutex);
Interrupt(HttpWorkerThread Select);
curl_multi_add_handle(CurlMultiHandle, curl_handle);
Unlock(HttpWorkerMutex);
}
static writefunction(...){
... (collect data in dynamic memory structure)
}
// THIS IS WHAT I WANT TO CALL
// memberfunction:
Void onFinishedMemberCallback(...){
//use collected data, callback owner and cleanup
}
// THIS IS ALL I CAN CALL
Static Void onFinishedOrOtherEventCallback(..., CURL* easy_handle){
//THIS IS WHAT I NEED:
Void* pWriteData;
curl_easy_getopt(easy_handle, CURLOPT_WRITEDATA, pWriteData);
HTTPRequest* req = (HTTPRequest*) pWriteData;
req->onFinishedMemberCallback(...);
}
};
HttpWorkerThread: work()
{
CurlMultiHandle = = curl_multi_init();
Setup fdset...
curl_multi_fdset(CurlMultiHandle, &fdread, &fdwrite, &fdexcep, &maxfd);
curl_multi_perform(CurlMultiHandle, &g_NumActiveRequests);
do{
Lock(HttpWorkerMutex);
//select with infinite timeout, only interrupted by data or by Interrupt from createRequest call
rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
curl_multi_perform(CurlMultiHandle, &pending);
Unlock(HttpWorkerMutex);
if (pending changed){
curl_multi_info_read( g_curlMulti, &nChanges)
iterate changes:
if (cur == CURLMSG_DONE)
// CALL THE FINISHED CALLBACK
HTTPRequest::onFinishedOrOtherEventCallback(...,msg->easy_handle);
}
} while(thread should run);
curl_multi_cleanup (CurlMultiHandle);
}
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2013-11-18