cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: [PATCH] Callback to abort libcurl when receiving a signal

From: Pierre Ynard <linkfanel_at_yahoo.fr>
Date: Tue, 4 Mar 2008 10:35:23 +0100

> With this I understand that the app might want/need to abort all
> libcurl operations currently in progress regain control and finally
> call curl_multi_cleanup / curl_easy_cleanup / curl_global_cleanup for
> proper tearing down or restarting of the app / daemon.

Indeed.

> Suppose you had no possibility of seeing libcurl internals, and that
> you only had access to libcurl's public API. How would you express the
> needs you have relative to the existing API in plain English ?

The need is to regain control of the process flow when it is stuck in
the middle of a function call well-known to block for some amount of
time. With classic system calls, any signal will interrupt the call and
it will return with EINTR. Often, basic pieces of library functions may
be set to non-blocking mode, so that they never block, thus there is no
need to worry about interrupting them. More elaborated library
functions, such as libcurl's easy interface and curl_easy_perform(), do
handle blocking, and never return until the operation either completes
or fails. Hence the need to interupt them in some cases.

> What will happen if SIGHUP / SIGTERM triggers when openssl / gnutls /
> openldap / kerberos / libssh2 / etc code is being executed by libcurl
> ? Will it make any real difference ? Will libcurl also get the signal
> and be able to abort immediately ? Just curious.

I haven't used every one of these APIs, but I do know for example that
when the underlying socket is non-blocking, openssl library calls never
block. It is my understanding that libcurl is designed so that it aims
to be the same with other libraries, and to only ever block when calling
poll()/select() in the code of select.c. The signal will be received,
and since calls to underlying libraries should not block, it should
only take a few milliseconds before they complete and the process flow
returns to poll()/select() in select.c, where it will gracefully abort
instead of blocking for seconds, doing nothing.

You could also use the multi interface and manage the polling and
blocking yourself, but it is overkill just for signal handling, and a
waste when there is only one transfer at the same time. Since the easy
interface takes the responsibility of polling for IO and blocking until
the transfer completes, it would be nice if it would also, on the other
hand, provide a way to be interrupted if needed.

-- 
Pierre Ynard
"Une âme dans un corps, c'est comme un dessin sur une feuille de papier."
Received on 2008-03-04