cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re[2]: libcurl win32 multi-thread problem

From: Razvan <defconhaya_at_gmail.com>
Date: Tue, 19 Sep 2006 21:40:29 +0300

Hello Dan,

Tuesday, September 19, 2006, 8:35:30 PM, you wrote:

> On Tue, Sep 19, 2006 at 05:30:09PM +0300, Razvan wrote:
>> Hello people !
>>
>> I have an multi threaded application that must upload from each thread a file
>> to an ftp server.
>> The problem is that only one thread is uploading and the speed never reaches
>> 60kb/s in the same LAN.

> I'm not positive I know the source of this particular problem, but the source
> code is full of errors. I'm assuming you're already doing the right thing
> to build and link with a thread-safe C library.

>> here is the function called from each thread:
>>
>>
>>
>> int ftp_upload(char* username, char* password, char* address, char* remote_dir,
>> char* local_file, char* upload_as )
>> {
>> FILE * hd_src ;
>> CURL* curl_handler;
>> CURLcode res;
>> char* REMOTE_URL;
>> int hd ;
>> struct stat file_info;
>>
>> char* buf_1; //[] = "RNFR " UPLOAD_FILE_AS;
>> char* buf_2; //[] = "RNTO " RENAME_FILE_TO;
>>
>> curl_global_init(CURL_GLOBAL_ALL);

> curl_global_init must *not* be called once from each thread--it's not thread
> safe.

>> curl_handler = curl_easy_init();
>> curl_easy_setopt(curl_handler, CURLOPT_NOSIGNAL, TRUE) ;
>>
>> hd = open(local_file, O_RDONLY) ;
>> fstat(hd, &file_info);
>> close(hd) ;

> It's unnecessary to open and close the file here. Just use stat instead
> of fstat. Or use fstat(fileno(hd_src), &file_info) after the fopen in
> the next line.

>>
>> hd_src = fopen(local_file, "rb");

> You're not checking the return code from this function.

>>
>> buf_1=(char*)malloc(strlen("RNFR .temp")+strlen(upload_as));

> This buffer is too small by one. The sprintf will overflow the buffer.

oops

>> buf_2=(char*)malloc(strlen(upload_as)+10);
>> sprintf(buf_1,"RNFR %s.temp",upload_as);
>> sprintf(buf_2,"RNTO %s.xxx",upload_as);
>> curl_easy_setopt(curl_handler, CURLOPT_UPLOAD, TRUE) ;
>>
>> REMOTE_URL=(char*)malloc(strlen(username)+strlen(password)+strlen(address)
>> +strlen(remote_dir)+strlen(upload_as)+11);

> This buffer is also at least 1 too small.
oops

>> sprintf(REMOTE_URL," ftp://%s:%s@%s/%s/
>> %s",username,password,address,remote_dir,upload_as);

> Why the space at the beginning of the URL?

oops again

>> curl_easy_setopt(curl_handler,CURLOPT_URL, REMOTE_URL);
>>
>> curl_easy_setopt(curl_handler, CURLOPT_READDATA, hd_src);

> Are you using libcurl as a DLL? If so then then you must heed the
> documentation and you "MUST use a CURLOPT_READFUNCTION".
I'm using static linked.

>>
>> curl_easy_setopt(curl_handler,
>> CURLOPT_INFILESIZE_LARGE,(curl_off_t)
>> file_info.st_size);
>>
>> res = curl_easy_perform(curl_handler);
>> curl_easy_cleanup(curl_handler);
>> curl_global_cleanup();

> Also not thread safe. This might be your problem, in fact. If the first
> thread to complete calls curl_global_cleanup(), it's going to stomp on all
> the other threads.

>>
>> fclose(hd_src); /* close the local file */
>>
>> return res;
>> }

> You need to spend more time in the man pages.

>>>> Dan

Thank you Dan for your time and for your good suggestions/advices !

-- 
Best regards,
 Razvan                            mailto:defconhaya_at_gmail.com
Received on 2006-09-19