cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Unclear docs on curl_multi_socket_action and CURLM_CALL_MULTI_SOCKET

From: Daniel Stenberg <daniel_at_haxx.se>
Date: Wed, 9 Jul 2008 23:42:19 +0200 (CEST)

On Wed, 9 Jul 2008, Josef Drexler wrote:

> 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.

We appreciate all the help we can get in improving these things!

Any particular references that caught your eye as bad or misleading?

> 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?

I think the most correct thing to do for us is to prevent that return code
from ever being returned from curl_multi_socket_action().

Assuming you're using a rather recent libcurl version, I don't think you need
to call it again at all - but it would of course be good and useful to really
verify this and document it. And remove the ability for the return code to
happen.

If you're using a somewhat older version, I think you should call it again
with parameters you'd use for a timeout.

> 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?

That's a bug that I've fixed. I thought that was already done in 7.18.2?

> 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?

Nah, but it should work fine.

> Does this not cause unnecessary work by having to check what it is that timed
> out or what sockets are active now?

It'll ignore all sockets and only check for timeouts, but that's a very swift
operation even when there is a large amount of timouts in use.

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

It doesn't, but that's mostly just because I found it easier to just ignore
that rather than to keep track and cleanup. I figured an extra time-out call
(when the timer expires) will be very cheap.

> 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?

Without handles the timeout should be cancelled yes. It's really pointless to
keep it ticking then since it can't do anything on expiry.

> 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

They do? What differences are those?

> 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.

That sounds like an attempt to an optimization of yours, not a necessary
difference. I don't really see how libcurl encourages a race condition to
occur by its behavior.

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

Yes I agree it would be better with a more consistent behavior (and it would
also be easier to document in a more clear way), but that would require
further internal changes and considerations to make sure that would be the
case all over. For example we currently don't use the socket callbacks from
c-ares (that I _believe_ would enable CURL_POLL_REMOVE before close) but
instead poll it for its status and thus we don't know about it closing its
handle(s) until after the fact.

-- 
  / daniel.haxx.se
Received on 2008-07-09