cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: libcurl win32 multi-thread problem

From: Razvan <defconhaya_at_gmail.com>
Date: Wed, 20 Sep 2006 10:36:45 +0300

On 9/19/06, Dan Fandrich <dan_at_coneharvesters.com> 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.
>
> > 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.
>
> > 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?
>
> > 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".
>
> >
> > 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
> --
> http://www.MoveAnnouncer.com The web change of address
> service
> Let webmasters know that your web site has moved
>

I've rewritten whole function and now every thread makes an upload but the
speed problem still remains.
It never reaches 60kb/s (both ftp
server and my program run on same computer).

-- 
Cu respect Razvan
Received on 2006-09-20