cURL / Mailing Lists / curl-library / Single Mail

curl-library

Hang in poll() when connection is interrupted on Linux

From: Aurélien <footplus_at_gmail.com>
Date: Wed, 17 Sep 2008 15:37:17 +0200

Hi everyone !
I searched the mailing-list archives and could not find a solution to the
problem I currently have, so i would appreciate if someone on this list
could give me a hint about what i'm doing wrong.

I'm using libcurl in a multi-threaded monitoring application that is using
cURL to make reports via HTTP. I read the documentation about threading and
libcurl, and deduced the following things:

 - cURL should be initialized and released via curl_global_*() functions,
when there's only the main thread running.
 - A cURL handle should not be used by more than one thread at a time.
 - If using HTTPs, proper locking functions should be installed in the
openssl library.

Maybe I already missed or misunderstood something here.

Anyway, after libcurl is initialized as advised via curl_global_*() function
- I'm using normal HTTP without authentication, so no need for openssl
stuff, my application's threads are using a single function that deals with
libcurl. This function makes a HTTP request and immediately returns the
result (content + return code) to the caller. It can be summarized in
pseudo-code as:

string fetchURL(string URL, string postdata)
{
    lock() // I'm using a pthread_mutex specific to this function.
    curl_easy_setopt(CURLOPT_WRITEFUNCTION...);
    curl_easy_setopt(CURLOPT_WRITEDATA...);
    curl_easy_setopt(CURLOPT_POSTFIELDS...);
    curl_easy_setopt(CURLOPT_HTTPHEADER...);
    curl_easy_setopt(CURLOPT_URL...);

    curl_easy_perform(...);
    ...
    unlock()
}

Each running thread can call this function at any time, hence the locking.
If you need any functional details about my application, feel free to ask.

My problem is that, if the connection to the server is lost (modem problem,
network cable unplugged, etc), sometimes the thread currently detaining the
lock never gets out of curl_easy_perform. I have compiled libcurl with
debugging information and got the following backtraces:

-- Thread holding the lock:
[Switching to thread 7 (Thread 0xb6c70b90 (LWP 4725))]#0 0xb7f15402 in
__kernel_vsyscall ()
(gdb) bt
#0 0xb7f15402 in __kernel_vsyscall ()
#1 0xb7d41c07 in poll () from /lib/tls/i686/cmov/libc.so.6
#2 0x080cddf9 in Curl_socket_ready (readfd=3, writefd=-1, timeout_ms=1000)
at select.c:218
#3 0x080e6667 in Transfer (conn=0x82cc428) at transfer.c:1805
#4 0x080e7073 in Curl_perform (data=0x82c3308) at transfer.c:2385
#5 0x080c7d43 in curl_easy_perform (curl=0x82c3308) at easy.c:520
#6 0x080578c6 in KHTTPRequest::fetchFileNow (this=0x82c2e80, url=0x82297c2,
postData=0x822ab5b,
    returnCode=0xb6c6fc3c) at src/lib/http.cpp:236

-- Other threads, blocked on the lock:
[Switching to thread 8 (Thread 0xb7471b90 (LWP 4724))]#0 0xb7f15402 in
__kernel_vsyscall ()
#0 0xb7f15402 in __kernel_vsyscall ()
#1 0xb7ef8589 in __lll_lock_wait () from /lib/tls/i686/cmov/libpthread.so.0
#2 0xb7ef3ba6 in _L_lock_95 () from /lib/tls/i686/cmov/libpthread.so.0
#3 0xb7ef358a in pthread_mutex_lock () from
/lib/tls/i686/cmov/libpthread.so.0
#4 0x08057524 in KHTTPRequest::fetchFileNow (this=0x82c2e80,
    url=0x82f097c, postData=0x82eff0c, returnCode=0xb7470ddc)
    at src/lib/http.h:122

Here, event after several minutes, the thread 7 is still stuck in poll().
The other threads, like the thread 8, are waiting for the mutex protecting
the cURL handle.

- I'm using cURL on Linux 2.6.24-19 on Ubuntu.
- The exact version of cURL is:
curl 7.18.2 (i686-pc-linux-gnu) libcurl/7.18.2 OpenSSL/0.9.8d zlib/1.2.3
c-ares/1.4.0
Protocols: tftp ftp telnet dict http file https ftps
Features: AsynchDNS Largefile NTLM SSL libz

Am I doing something wrong that can explain the situation ?

Thanks, and have a nice day.

-- 
Aurélien Guillaume
"I love deadlines. I like the whooshing sound they make as they fly by."
Received on 2008-09-17