cURL / Mailing Lists / curl-library / Single Mail

curl-library

curl_multi_perform generating same responses for all easy_handles inserted

From: Pa1 <paonethestar_at_gmail.com>
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