cURL / Mailing Lists / curl-library / Single Mail

curl-library

CURLM_CALL_MULTI_PERFORM and curl_multi_socket

From: Nathan E. Moore <nate_at_redtetrahedron.org>
Date: Sat, 31 May 2008 09:37:13 -0400

1) Run hiperfifo.c
2) Pipe in lots of urls. I've been using 20 every 2 seconds
3) hiperfifo.c quits with "ERROR: event_cb: curl_multi_socket returns
CURLM_BAD_SOCKET"

This happen when CURLM_CALL_MULTI_PERFORM is returned from
curl_multi_socket (or curl_multi_socket_action) after a call to the socket
callback removing the current socket. The sequence is something like:
  1) curl_multi_socket(fd=1)
    a) socket_callback(fd=1, what=CURL_POLL_REMOVE)
  1) returns with CURLM_CALL_MULTI_PERFORM
  2) curl_multi_socket(fd=1)
  2) returns CURLM_BAD_SOCKET

This is during the PERFORM => DONE state transition, when you hit the code
by the commment "after the transfer is done, go DONE" in multi_runsingle.
Then the end of multi_runsingle set a timeout for the current easy handle
to be 10ms. Most of the time this timeout is handled before control
returns from curl_multi_socket. When it is not you get this error. But
this could happen anywhere you get a remove followed by a
CURLM_CALL_MULTI_PERFORM, but I don't know if there are any other locations
following that pattern.

I think the solution for this is to change the example to call
curl_multi_socket_action(CURL_SOCKET_TIMEOUT) when CURLM_CALL_MULTI_PERFORM
is returned. But I'm not sure about this, the docs about the return value
from socket action are not very clear about what parameters you should use
after a CURLM_CALL_MULTI_PERFORM. And some comments in multi.c seem to
indicate that you can ignore CALL_MULTI_PERFORM if you respond timeouts. If
this is the correct solution, the example and man pages should be updated
to make this clear.

Nathan Moore
Received on 2008-05-31