cURL / Mailing Lists / curl-library / Single Mail

curl-library

CURLOPT_TIMEOUT and SIGALRM

From: Ward, David <David.Ward_at_factiva.com>
Date: Fri, 24 Jan 2003 07:09:58 -0500

I'm using curl library 7.9.2 on solaris 7 in a C++ pthread application and
I'm not seeing the expected behaviour regarding CURLOPT_TIMEOUT and it
dependence on SIGALRM in a multithreaded environment. As the documentation
indicates a problem using the timeout with threads I want to demonstrate the
problem. I'm disabling signals on my threads but the timeout option still
appears to work - is the timeout really using SIGALRM? I cant set the
CURLOPT_NOSIGNAL option available in later versions of curl. Can anyone
shed any light on what is going on here?

I've listed an example client program below. The server simply accepts the
http request but never responds so that curl must timeout. When I run this
code, curl successfully timeouts after the expected time.

extern "C"
{
#include "curl/curl.h"
#include "curl/easy.h"
#include <stdlib.h>
}

#include <iostream.h>
#include <pthread.h>
#include <signal.h>

struct MemoryStruct
{
      char* memory;
      size_t size;
};

size_t writeChunk(void* ptr, size_t size, size_t nmemb, void* data)
{
   
   register int realsize = size * nmemb;
   struct MemoryStruct* mem = (struct MemoryStruct*)data;

   mem->memory = (char*)realloc(mem->memory, mem->size + realsize + 1);
   if (mem->memory)
   {
      memcpy(&(mem->memory[mem->size]), ptr, realsize);
      mem->size += realsize;
      mem->memory[mem->size] = 0;
   }
   return realsize;
}

extern "C"
{
void* work(void* pTimeout)
{
   sigset_t sigset;
   sigemptyset(&sigset);
   sigaddset(&sigset, SIGALRM);

   pthread_sigmask(SIG_BLOCK, &sigset, NULL);

   int timeout = *(int*)pTimeout;
   char url[500];

   strcpy(url, "http://**.*.**.**/GET /NAP?RIC=RTR.L&FORMAT=XML HTTP/1.1");
   
   struct MemoryStruct chunk;
   chunk.memory = NULL;
   chunk.size = 0;

   CURL* pCurl = curl_easy_init();
   if (!pCurl)
   {
      cout << "Error : Failed to initialise curl" << endl;
      return NULL;
   }

   CURLcode cCode;
   cCode = curl_easy_setopt(pCurl, CURLOPT_URL, url);
   cCode = curl_easy_setopt(pCurl, CURLOPT_VERBOSE, true);
   cCode = curl_easy_setopt(pCurl, CURLOPT_NOPROGRESS, true);
   cCode = curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, writeChunk);
   cCode = curl_easy_setopt(pCurl, CURLOPT_FILE, (void*)&chunk);
   cCode = curl_easy_setopt(pCurl, CURLOPT_HEADER, true);
   cout << "Setting timeout " << timeout << endl;
   cCode = curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, timeout);
   char errorBuffer[300];
   cCode = curl_easy_setopt(pCurl, CURLOPT_ERRORBUFFER, errorBuffer);
   
   cCode = curl_easy_perform(pCurl);

   curl_easy_cleanup(pCurl);

   if (cCode != 0)
   {
      cout << "Timeout " << timeout << " Error : curl : "
           << errorBuffer << endl;
   }
   else
   {
      cout << "curl success : timeout " << timeout << endl;
   }

   return NULL;
}
}

int main(int argc, char *argv[])
{
   pthread_t thr;
   pthread_t thr1;
   pthread_t thr2;
   pthread_t thr3;
   pthread_t thr4;
   int timeout = 30;
   int timeout1 = 60;
   int timeout2 = 90;
   int timeout3 = 120;
   int timeout4 = 150;

   sigset_t sigset;
   sigemptyset(&sigset);
   sigaddset(&sigset, SIGALRM);

   pthread_sigmask(SIG_BLOCK, &sigset, NULL);

   cout << "Creating thread 3" << endl;
   pthread_create(&thr3,
                  NULL,
                  work,
                  (void*)&timeout3);
   
   cout << "Creating thread " << endl;
   pthread_create(&thr,
                  NULL,
                  work,
                  (void*)&timeout);

   cout << "Creating thread 4" << endl;
   pthread_create(&thr4,
                  NULL,
                  work,
                  (void*)&timeout4);

   cout << "Creating thread 2" << endl;
   pthread_create(&thr2,
                  NULL,
                  work,
                  (void*)&timeout2);

   cout << "Creating thread 1" << endl;
   pthread_create(&thr1,
                  NULL,
                  work,
                  (void*)&timeout1);

   cout << "joining thread 3" << endl;
   pthread_join(thr3, NULL);
   cout << "joining thread " << endl;
   pthread_join(thr, NULL);
   cout << "joining thread 4" << endl;
   pthread_join(thr4, NULL);
   cout << "joining thread 2" << endl;
   pthread_join(thr2, NULL);
   cout << "joining thread 1" << endl;
   pthread_join(thr1, NULL);
 
   return 0;
}

-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com
Received on 2003-01-24