I did this
According to the documentation, CURLMOPT_TIMERFUNCTION return value can report an error back to libcurl.
I've returned -1 from this function upon error. The application simply sat idle, cycling on the event loop without any reports of a failed transfer - which makes sense since curl_multi_socket_action never gets subsequently called.
After checking the documentation for the adjacent CURLMOPT_SOCKETFUNCTION, it has no mention of the return value's semantics.
Returning -1 from the latter seemed to have the same effect.
Further inspection of the source code indicates the return value of these callbacks is always disregarded:
CURLMOPT_TIMERFUNCTION: 1 2
CURLMOPT_SOCKETFUNCTION: 1 2 3
I expected the following
The documentation is unclear about how the return values from these functions are handled.
Arguably, a reasonable interpretation would expect libcurl to take appropriate measures - e.g.: aborting the transfer for the easy handle in question.
At a minimum, the documentation should state that the values are ignored, with possible workarounds - e.g.: how to cancel the easy handle appropriately in the case of CURLMOPT_SOCKETFUNCTION; is it safe to remove the handle from within the callback?
Ideally, the return values should be inspected and handled appropriately.
It is common for CURLMOPT_TIMERFUNCTION to start a custom timer, as well as for CURLMOPT_SOCKETFUNCTION to (possibly) allocate and start a poller. If these procedures fail, the state of the asynchronous state machine is undefined / undocumented.
Some state machines rely on appropriate behavior in order to stop / free resources (e.g.: stop and free the poller upon CURL_POLL_REMOVE).
It is unclear which events are guaranteed to be delivered, even in the presence of errors, so that appropriate resource management can take place without additional custom machinery being implemented (e.g.: garbage collect pollers from dead requests; call curl_multi_socket_action with CURL_SOCKET_TIMEOUT from the event loop as a fallback for failed timer setup).
Likewise, it is unclear what's the appropriate follow up for the failed requests, or how to even detect if the request failed due to a callback returning -1.
Should one of these callbacks fail, thus having to report -1 back to libcurl, is it ever possible for the state machine to fall into some inconsistent state?
I'd love to be able to contribute a fix, but I currently don't have the time, nor expertise in libcurl's codebase to do so appropriately. The least I can do as a token of gratitude for this great library is a detailed bug report.
curl/libcurl version
Checked sources for latest head as of this reporting.
Observed on the following build:
curl 7.78.0-DEV (Linux) libcurl/7.78.0-DEV OpenSSL/1.1.1l zlib/1.2.11 c-ares/1.17.0
Release-Date: [unreleased]
Protocols: http https
Features: alt-svc AsynchDNS HSTS HTTPS-proxy IPv6 Largefile libz SSL UnixSockets
operating system
Seemingly not OS specific. Observed on Linux bst 5.14.0-4-amd64 #1 SMP Debian 5.14.16-1 (2021-11-03) x86_64 GNU/Linux.
I did this
According to the documentation,
CURLMOPT_TIMERFUNCTIONreturn value can report an error back tolibcurl.I've returned
-1from this function upon error. The application simply sat idle, cycling on the event loop without any reports of a failed transfer - which makes sense sincecurl_multi_socket_actionnever gets subsequently called.After checking the documentation for the adjacent
CURLMOPT_SOCKETFUNCTION, it has no mention of the return value's semantics.Returning
-1from the latter seemed to have the same effect.Further inspection of the source code indicates the return value of these callbacks is always disregarded:
CURLMOPT_TIMERFUNCTION: 1 2CURLMOPT_SOCKETFUNCTION: 1 2 3I expected the following
The documentation is unclear about how the return values from these functions are handled.
Arguably, a reasonable interpretation would expect
libcurlto take appropriate measures - e.g.: aborting the transfer for the easy handle in question.At a minimum, the documentation should state that the values are ignored, with possible workarounds - e.g.: how to cancel the easy handle appropriately in the case of
CURLMOPT_SOCKETFUNCTION; is it safe to remove the handle from within the callback?Ideally, the return values should be inspected and handled appropriately.
It is common for
CURLMOPT_TIMERFUNCTIONto start a custom timer, as well as forCURLMOPT_SOCKETFUNCTIONto (possibly) allocate and start a poller. If these procedures fail, the state of the asynchronous state machine is undefined / undocumented.Some state machines rely on appropriate behavior in order to stop / free resources (e.g.: stop and free the poller upon
CURL_POLL_REMOVE).It is unclear which events are guaranteed to be delivered, even in the presence of errors, so that appropriate resource management can take place without additional custom machinery being implemented (e.g.: garbage collect pollers from dead requests; call
curl_multi_socket_actionwithCURL_SOCKET_TIMEOUTfrom the event loop as a fallback for failed timer setup).Likewise, it is unclear what's the appropriate follow up for the failed requests, or how to even detect if the request failed due to a callback returning
-1.Should one of these callbacks fail, thus having to report
-1back tolibcurl, is it ever possible for the state machine to fall into some inconsistent state?I'd love to be able to contribute a fix, but I currently don't have the time, nor expertise in
libcurl's codebase to do so appropriately. The least I can do as a token of gratitude for this great library is a detailed bug report.curl/libcurl version
Checked sources for latest head as of this reporting.
Observed on the following build:
operating system
Seemingly not OS specific. Observed on
Linux bst 5.14.0-4-amd64 #1 SMP Debian 5.14.16-1 (2021-11-03) x86_64 GNU/Linux.