cURL / Mailing Lists / curl-library / Single Mail

curl-library

Best way to issue member-callback after curl_multi_info_read returns CURLMSG_DONE

From: Daniel Sewtz <daniel.sewtz_at_ciric.de>
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