cURL / Mailing Lists / curl-library / Single Mail

curl-library

Multithreaded Issues

From: Rob Mason <rmason_at_archivas.com>
Date: Mon, 23 Aug 2004 14:18:50 -0400

Hi folks, I'm having some problems using curl in a multithreaded
environment when mixing operation types and was wondering if anyone has
seen anything similar. Here's the scenario:

If I run multithreaded PUTs or GETs alone I can run cleanly forever with
as many threads as I like (tried up to 500). As soon as I mix GETs with
PUTs I start getting what appears to be corruption between the two
streams in terms of the responses and behavior.

My application does a global init and global cleanup only once at
startup and shutdown respectively. Each thread, for every PUT or GET,
gets a new curl handle (via curl_easy_init), does its bit, then does a
curl_easy_cleanup to release the handle. All data structures used for
moving data are local to the threads.

Since I could well be doing something wrong within the operations I'll
lay out the PUT and GET cases below. Any help would be appreciated. I'm
running on Red Hat 9 with 2.4.25 Kernel, I'm currently running
curl-7.9.8-5 but have seen the same issues with curl 7.12.1. I'm writing
in C.

Any help would be appreciated.
Thanks,
Rob

-----

PUT flow:
   CURL *curl;
   char writeBuffer[BIG_BUFFER_SIZE];
   long responseCode;
   
   curl = curl_easy_init();
   
   if (curl)
   {
      char curlErrorBuffer[CURL_ERROR_SIZE];
      curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curlErrorBuffer);
      curl_easy_setopt(curl, CURLOPT_READFUNCTION,
read_memory_callback);
      curl_easy_setopt(curl, CURLOPT_UPLOAD, true) ;
      curl_easy_setopt(curl, CURLOPT_DNS_USE_GLOBAL_CACHE, false) ;
      curl_easy_setopt(curl, CURLOPT_URL, destinationAddress);
      curl_easy_setopt(curl, CURLOPT_READDATA, writeBuffer);
      curl_easy_setopt(curl, CURLOPT_INFILESIZE, fileSize);
      res = curl_easy_perform(curl);

      if (res != CURLE_OK)
      {
         curl_easy_cleanup(curl);
         return(-1);
      }
      else
      {
         res = curl_easy_getinfo(curl,
CURLINFO_HTTP_CODE,&responseCode);
         if (res != CURLE_OK)
         {
            curl_easy_cleanup(curl);
          return(-1);
         }
         
         if ((responseCode != 201) && (responseCode != 200))
         {
            curl_easy_cleanup(curl);
            return(-1);
         }
         
         curl_easy_cleanup(curl);
      }
   }

GET flow:
   CURL *curl;
   char readBuffer[BIG_BUFFER_SIZE];
   
   curl = curl_easy_init();
   
   if (curl)
   {
      char curlErrorBuffer[CURL_ERROR_SIZE];
      curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curlErrorBuffer);
     
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,write_memory_callback);
      curl_easy_setopt(curl, CURLOPT_WRITEDATA, readBuffer);
      curl_easy_setopt(curl, CURLOPT_URL, destinationAddress);
      curl_easy_setopt(curl, CURLOPT_UPLOAD, false) ;
      curl_easy_setopt(curl, CURLOPT_DNS_USE_GLOBAL_CACHE, false) ;
      curl_easy_setopt(curl, CURLOPT_HTTPGET, true);

      res = curl_easy_perform(curl);
      
      if (res != CURLE_OK)
      {
         curl_easy_cleanup(curl);
         return(-1);
      }
      else
      {
         res = curl_easy_getinfo(curl,
CURLINFO_HTTP_CODE,&responseCode);
         
         if (res != CURLE_OK)
         {
            curl_easy_cleanup(curl);
            return(-1);
         }
         
         if (responseCode != 200)
         {
            curl_easy_cleanup(curl);
            return(-1);
         }
      }
      
      curl_easy_cleanup(curl);
   }
   
Received on 2004-08-23