curl-library
curl_multi_perform generating same responses for all easy_handles inserted
Date: Mon, 2 May 2011 01:18:04 +0530
Hi,
I'm bit new to curl multi interface. I'm using this to make Webservice calls
on HTTP in parallel (if not truly). But in my case, outputs (responses)
getting jumbled between the curl handles and also, some times some junk
strings as output.
My requirement is - we have a queue where the requests keep getting polled
through main program. And we have child thread which will be processing this
queue as it sees any element in it. This processing is being done through
multi-interface.
You can see my code below mentioned. Though my requirement should be very
normal use case for this lib, any help would be greatly appreciated.
//Code starts
CURLM* mcurl = curl_multi_init();
map<CURL*,curlEasyObj*> curl_map;
CURLMsg *msg;
long L = -1;
unsigned int C=0;
int maxfd, msgQ, stillRunning = -1;
fd_set fdRead, fdWrite, fdError;
struct timeval timev;
while(true)
{
int num_handles = 0;
//for(int i=0;i<maxParallel;i++)
while(!MainObj->getRequestQueue()->isEmpty())
{
curlEasyObj* pCurl =
MainObj->getRequestQueue()->dequeue();
CURL *curl = pCurl->getCurlHandle();
curl_map.insert(pair<CURL*,curlEasyObj*>(curl,pCurl));
curl_multi_add_handle(mcurl, curl);
num_handles++;
}
stillRunning = num_handles;
while (stillRunning)
{
int oldStillRunning = stillRunning;
CURLMcode performRet;
do {
performRet = curl_multi_perform(mcurl, &stillRunning);
}while(performRet == CURLM_CALL_MULTI_PERFORM || oldStillRunning ==
stillRunning);
if (stillRunning)
{
FD_ZERO(&fdRead);
FD_ZERO(&fdWrite);
FD_ZERO(&fdError);
if (curl_multi_fdset(mcurl, &fdRead, &fdWrite, &fdError,
&maxfd)) {
fprintf(stderr, "fdError: curl_multi_fdset\n");
//return IFAILURE;
stillRunning = 0; //temporarily
break;
}
if (L == -1)
L = 100;
if (maxfd == -1)
{
#ifdef WIN32
Sleep(L);
#else
sleep(L / 1000);
#endif
}
else {
timev.tv_sec = L/1000;
timev.tv_usec = (L%1000)*1000;
if (0 > select(maxfd+1, &fdRead, &fdWrite, &fdError,
&timev)) {
//TODO: error
fprintf(stderr, "fdError: select(%i,,,,%li): %i:
%s\n",
maxfd+1, L, errno, strerror(errno));
//return IFAILURE;
stillRunning = 0; //temporarily
break;
}
}
}
while ((msg = curl_multi_info_read(mcurl, &msgQ)))
{
if (msg->msg == CURLMSG_DONE)
{
curlEasyObj* mpCurl = curl_map[msg->easy_handle];
const char* pResponse = mpCurl->getResponseBuffer();
// cleanup
curl_map.erase(msg->easy_handle);
curl_multi_remove_handle(mcurl, msg->easy_handle);
//curl_easy_cleanup(e);
}
else {
fprintf(stderr, "fdError: CURLMsg (%d)\n", msg->msg);
}
while(!MainObj->getRequestQueue()->isEmpty() && !stop)
{
curlEasyObj* npCurl =
MainObj->getRequestQueue()->dequeue();
CURL *ncurl = npCurl->getCurlHandle();
curl_map.insert(pair<CURL*,curlEasyObj*>(ncurl,npCurl));
curl_multi_add_handle(mcurl, ncurl);
stillRunning++;
}
}
}
}
curl_multi_cleanup(mcurl);
//Code ends
MainObj has the queue containing the curlEasyObjs which are wrappers to
curl_easy_handle.
My simple webservice takes input string and responds by appending "Hello!"
to the same string.
If my inputs are:
1. <string> Test1</string>
2. <string> Test2</string>
3. <string> Test3</string>
4. <string> Test4</string>
the expected outputs should be: (order can be changed)
1. <string>Hello! Test1</string>
2. <string>Hello! Test2</string>
3. <string>Hello! Test3</string>
4. <string>Hello! Test4</string>
But, currently output is :
1. <string>Hello! Test4</string>
2. <string>Hello! Test4</string>
3. <string>Hello! Test4</string>
4. <string>Hello! Test4</string>
or some times first response gets junk strings.
Any insight in this issue would be greatly appreciated.
Thanks,
Pavan
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2011-05-01