[Info-vax] Problems with multithreaded calls to libCURL

Arne Vajhøj arne at vajhoej.dk
Thu Mar 7 19:06:33 EST 2019


On 3/7/2019 6:09 PM, Jim Duff wrote:
> Versions:
> 
> OpenVMS 8.4 on IA64
> HP C V7.2-001:
> libCURL: 7.4.7
> 
> Nearly seven years ago, I wrote some code to utilise libCURL to perform
> FTP for a document routing system.  The code was single threaded, and it
> quickly became the event driven successor for what was then a polling
> system based on CIFS.
> 
> Today, the system ships hundreds of thousands of documents a day off the
> central ERP system.  All usually goes well, but there is at least one
> problem that can seriously impact document delivery times.  This occurs
> when an FTP server at a target machine is unavailable.
> 
> When this occurs, with the default setting of CURLOPT_CONNECTTIMEOUT, a
> 5 minute delay can occur as the library waits for the connection to
> complete.  Easy fix says I, just set CURLOPT_CONNECTIMEOUT to a smaller
> value with a call like
> 
> res = curl_easy_setopt (handle, CURLOPT_CONNECTTIMEOUT, 30L);
> 
> for a 30 second timeout.
> 
> Except this appears to have no effect.
> 
> After double checking that no later version of libCURL is currently
> available for OpenVMS, I embarked on multithreading the code so that
> there would be one worker thread per server and target directory
> combination.  That way, if an FTP server was unavailable, only documents
> destined for that server would be impacted by the connect timeout issue
> as only the affected thread(s) would stall.
> 
> To my consternation, on stress testing the multithreaded code, I'm
> occasionally getting an access violation in the depths of libCURL:
> 
> %SYSTEM-F-ACCVIO, access violation, reason mask=00, virtual
> address=000000000000
> 0028, PC=FFFFFFFF84088EB0, PS=0000001B
> %TRACE-F-TRACEBACK, symbolic stack dump follows
> image     module    routine               line      rel PC           abs PC
> LIBRTL  LIB$$UNWIND  restoreReg          22380 00000000000007A0
> FFFFFFFF84088EB0
> LIBRTL  LIB$$UNWIND  step_final_phase    25871 0000000000010652
> FFFFFFFF84098D62
> LIBRTL  LIB$$UNWIND  UC_step             24860 000000000000C682
> FFFFFFFF84094D92
> LIBRTL  LIB$$UNWIND  UC_currentContext
>                                           21987 0000000000000602
> FFFFFFFF84088D12
> LIBRTL  LIB$IPF_CALLING_STANDARD  lib$i64_get_curr_invo_context
>                                           19476 00000000000009A2
> FFFFFFFF8407FAB2
> DECC$SHR  C$SETJMP  sigsetjmp            17136 00000000000008B2
> FFFFFFFF84B6DBE2
> GNV$LIBCURL  hostip  Curl_resolv_timeout

> Enclosing the calls to curl_easy_perform () in a mutex makes the access
> violation go away, making me think that libCURL's claim to being thread
> safe is not so rock solid.
> 
> Reading https://curl.haxx.se/libcurl/c/threadsafe.html I see there are
> some exceptions to its thread safe claim, so I duly implemented them:
> 
> 1) don't share handles between threads.  I wasn't doing this in the
> first place.
> 2) I'm not using the share interface.
> 3) disable signals with CURLOPT_NOSIGNAL set to 1L
> 4) call curl_global_init () in the main thread before creating
> additional threads.
> 5) don't use CURLOPT_DNS_USE_GLOBAL_CACHE.  I wasn't.

If you need your problem solved as fast as possible, then
I suspect that the fastest way is to drop C and libcurl and
switch to something else: C and another FTP client library
(if you only need FTP then you do not need anything as
big as libcurl) or Python or Java.

I suspect that getting the current combo to work may
turn into a very long troubleshooting journey.

Arne




More information about the Info-vax mailing list