cURL / Mailing Lists / curl-library / Single Mail

curl-library

Unclear docs on curl_multi_socket_action and CURLM_CALL_MULTI_SOCKET

From: Josef Drexler <josef_at_ttdpatch.net>
Date: Wed, 9 Jul 2008 23:05:36 +0200

I've been working on using the curl_multi_socket_action interface for
rtorrent, and I found the docs (which often still describe the
deprecated curl_multi_socket rather than curl_multi_socket_action) a
bit sparse on details. So here are my questions.

1. CURLM_CALL_MULTI_SOCKET return value

When this is returned, what should be the arguments for the next
call? The same socket? The same event mask? Socket and/or event mask
cleared?

Apparently there are cases where CURLM_CALL_MULTI_SOCKET is returned
after the socket in question has been removed and closed. In that
case the arguments for the next call MUST be different or it'll
return with CURLM_BAD_SOCKET. But what should they be?

Currently I pass CURL_SOCKET_TIMEOUT and a mask of 0 in the following
calls, regardless of what happened to the socket. Is this the
intended behaviour? Does this not cause unnecessary work by having to
check what it is that timed out or what sockets are active now?
Perhaps there should be a CURL_SOCKET_CONTINUE value to use in this
case.

By the way, the docs don't mention CURLM_CALL_MULTI_SOCKET at all.
While it is technically identical to CURLM_CALL_PERFORM, for reasons
of symmetry and the principle of least surprise it should perhaps be
what is documented as return value for curl_multi_socket_action
instead of CURLM_CALL_PERFORM.

2. Clearing the timeout

It seems libcurl does not cancel the timeouts it has specified via
the timeout callback.

Can or should it be cancelled when all handles are finished, or not?
Or should it be cancelled when all sockets have been removed? Or
should it just be kept and have it call curl_multi_socket_action even
though there are no more handles?

3. Removing closed sockets

It seems libcurl sometimes closes the socket *before* generating the
CURL_POLL_REMOVE, and sometimes *after* it. Since both cases need to
be handled differently, I need to waste a stat() call or similar to
find out if the descriptor is valid. For instance, when the socket is
already closed, the syscalls to remove it from the poll interface
will fail. This also opens a race condition where other code (or
another thread) might open() some resource and receive the same FD as
the now-closed socket, without a way of telling that the events now
set on that FD in the kernel should NOT be removed.

It would be a lot better if libcurl never closed sockets before
generating a CURL_POLL_REMOVE.

-- 
Josef Drexler
josef_at_ttdpatch.net
Received on 2008-07-09