cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: curl_multi_socket_action and speed limits

From: Daniel Stenberg <daniel_at_haxx.se>
Date: Wed, 9 Sep 2009 20:34:36 +0200 (CEST)

On Mon, 7 Sep 2009, Dimitar Dimitrov wrote:

>> Right, but it should also set a timeout so that after a given time it
>> should call your timer callback, you call libcurl and it should put the
>> socket back in the game again. If not, it bugs.
>
> And I think it shouldn't remove the socket in first place, but set a zero
> event mask.

libcurl could (or should) of course use the CURL_POLL_NONE value for the
socket instead of CURL_POLL_REMOVE when this happens. The problem is that the
logic that deals with sockets for the multi interface doesn't have the state
awareness enough to know that the socket vanished for the "too fast" reason,
it just sees that the socket is no longer in use, so it will tell the app it
is removed. And then when the socket appears again it will tell the app about
it again.

I consider this more of an area that could use some love and optimization
rather than an actual bug.

The bug is rather that the socket is not again put back into use properly, as
you describe below.

>> Can you see why the timeout doesn't trigger, or if it does trigger why it
>> doesn't put the socket back in the game correctly?
>
> The initial timeout is too large and I don't see anywhere new timeout
> set. Sketch of the execution of this last call to ..._socket_action:
>
> - curl_multi_socket_action
> - multi_socket
> - multi_runsingle
> = changes state to TOOFAST

Ah, note how the comment in the code just above this state change says:

"TODO: Call Curl_expire() with the time left until we're targeted to be below
the speed limit again."

Since it doesn't do that... it won't work! ;-(

> - singlesocket
> - multi_getsock
> = state is TOOFAST, it doesn't return any sockets
> = sees socket as removed
> = calls user callback with REMOVE
> - sh_delentry(multi->sockhash, s) [multi.c:1804]
> = remove the socket from the easy handle? [multi.c:1810]

If the timeout would trigger and the code would run the multi_runsingle()
function when in the TOOFAST state, it should then detect that it is now below
the bar and it should switch state back to PERFORM again and things are fine.

If it instead is still above the speed limit, it needs to set the timeout to
expire again at a later time.

-- 
  / daniel.haxx.se
Received on 2009-09-09