curl-library
Multi Thread problem
Date: Fri, 20 Sep 2002 17:52:41 +0530
Hi,
I have one function which gets content from the web with CURL by
passing the URL to it. I am attaching the code below.
The problem is that this function is called by a number of threads (15
threads to be precise). The whole code runs fine for some time, but then
when there are say 5 requests at the same time to a same URL, and when it
tries to retrive the content simultaneously, sometime in between i get a
seg_fault. I have put VERBOSE and here is where it gives me a seg_fault
always....By default i am giving a timeout of 60 secs. I dont know what cud
be the problem. I have tried all combination of increasing the timeout from
5 secs to 60 secs. Also i have tried it with 5 threads to 13 threads but the
crash is erratic. As u see from the VERBOSE below....when two or more
threads have simultaneously got the content....my program goes down.
Please throw some light. I am working on Solaris 8.
* Connected to 66.13.8.101 (66.13.8.101)
> GET /servlet/ICC?msisdn=919845114579&message=CRICKET HTTP/1.1
Host: 66.13.8.101:8080
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
* Connected to 66.13.8.101 (66.13.8.101)
> GET /servlet/ICC?msisdn=919845156838&message=BUZZ%20C HTTP/1.1
Host: 66.13.8.101:8080
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
* Connection (#0) left alive
---------------> Result of the CURL PERFORM is 0
------>After CURL Perform
* Closing live connection (#0)
The code is below ****************
CURL_MEM get_url_content_from_web(unsigned char * url_to_be_fetched, int
timeout, int answer)
{
CURL *curl_handle;
CURLcode res;
char * http_header=NULL;
char * http_body=NULL;
struct MemoryStruct chunk;
CURL_MEM curl_mem;
char http[20];
int status;
chunk.memory=NULL; /* we expect realloc(NULL, size) to work */
chunk.size = 0; /* no data at this point */
printf("URL to be retrieved by CURL is %s\n",url_to_be_fetched);
// init the curl session
curl_handle = curl_easy_init();
// specify URL to get
curl_easy_setopt(curl_handle, CURLOPT_URL, url_to_be_fetched);
// Set option for HTTP Headers
curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, TRUE);
curl_easy_setopt(curl_handle, CURLOPT_HEADER, TRUE);
//Set follow-up if the page is redirected
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 2);
//Set conn. timeout
curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT, timeout);
// WMCB collects the URL content into a buffer
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
// we pass our 'chunk' struct to the callback function
curl_easy_setopt(curl_handle, CURLOPT_FILE, (void *)&chunk);
// get it!
printf("------>Before CURL Perform\n");
res = curl_easy_perform(curl_handle);
printf("---------------> Result of the CURL PERFORM is %d\n",res);
printf("------>After CURL Perform\n");
curl_mem.err_no = res;
if(res != 0)//Could be some CURL error
{
chunk.memory = (unsigned char *) malloc (ERROR_SIZE);
bzero(chunk.memory,ERROR_SIZE);
strcpy(chunk.memory,curl_error_codes(res));
chunk.size = strlen(chunk.memory);
goto END;
}
//If no SMS response is asked or the chunk has nothing
if((answer == 0) || (strlen(chunk.memory) == 0) || (chunk.size == 0))
{
chunk.memory = (unsigned char *) malloc (DB_NUM_SIZE);
bzero(chunk.memory,DB_NUM_SIZE);
strcpy(chunk.memory,"ok");
chunk.size = strlen(chunk.memory);
goto END;
}
//printf("Chunk size is %d\nChunk content is
(%s)\n\n",chunk.size,chunk.memory);
http_header = (char *) malloc (HEADER_SIZE);
bzero(http_header, HEADER_SIZE);
STRIP_HEAD:
sscanf(chunk.memory, "%[^\r\n]", http_header);
printf("#### HTTP HEADER (%s)\n", http_header);
http_body = (char *)strstr(chunk.memory, "\r\n\r\n");
if(http_body == NULL) {
chunk.memory = (unsigned char *) malloc (DB_NUM_SIZE);
bzero(chunk.memory,DB_NUM_SIZE);
strcpy(chunk.memory,"ok");
chunk.size = strlen(chunk.memory);
} else {
sscanf(http_header,"%s %d",http,&status);
printf("Header is %s and status is %d\n",http,status);
if(status >= 301 && status <= 304) {
printf("The header status is ########### %d ############\n",status);
chunk.memory = (unsigned char *) malloc (strlen(http_body)+1);
bzero(chunk.memory, strlen(http_body)+1);
strcpy(chunk.memory, http_body+strlen("\r\n\r\n"));
chunk.size = strlen(chunk.memory);
goto STRIP_HEAD;
} else if(status == 200) { //Success
chunk.memory = (unsigned char *) malloc (strlen(http_body)+1);
bzero(chunk.memory, strlen(http_body)+1);
strcpy(chunk.memory, http_body+strlen("\r\n\r\n"));
chunk.size = strlen(chunk.memory);
printf("#### HTTP BODY (Chunk) size (%d) and content (%s)\n", chunk.size,
chunk.memory);
if(chunk.size == 0) {
chunk.memory = (unsigned char *) malloc (strlen("ok")+1);
bzero(chunk.memory, strlen("ok")+1);
strcpy(chunk.memory,"ok");
chunk.size = strlen(chunk.memory);
}
} else if(status >= 1 && status <= 52) { //CURL Errors
chunk.memory = (unsigned char *) malloc (ERROR_SIZE);
bzero(chunk.memory,ERROR_SIZE);
strcpy(chunk.memory,curl_error_codes(status));
chunk.size = strlen(chunk.memory);
} else {
chunk.memory = (unsigned char *) malloc (strlen(http_header)+1);
bzero(chunk.memory,strlen(http_header)+1);
strcpy(chunk.memory, http_header);
chunk.size = strlen(chunk.memory);
}
}
END:
printf("Copying chunk.memory and chunk.size\n");
curl_mem.mems.memory = chunk.memory;
curl_mem.mems.size = chunk.size;
//Trying to cleanup curl at the end
curl_easy_cleanup(curl_handle);
return(curl_mem);
}
Additional Functions called from above
unsigned char * curl_error_codes(int);
struct MemoryStruct {
unsigned char *memory;
size_t size;
};
typedef struct CURL_MEM CURL_MEM;
struct CURL_MEM {
int err_no;
struct MemoryStruct mems;
};
size_t WriteMemoryCallback(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;
}
Thank you,
Chirag
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
Received on 2002-09-20