After https://github.com/curl/curl/commit/a58b50f ("transfer: Curl_sendrecv() and event related improvements") for issue #14561, socket callbacks can be triggered during curl_multi_cleanup() calls.
In our project that uses curl_multi, we noticed this because our socket callback function attempted to manipulate some members of a C++ class that wraps curl_multi. Because that particular object was being destructed, this resulted in trouble. (Pure virtual functions being called, and/or annoying segfaults.) We have now worked around this by calling curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, NULL) just before calling curl_multi_cleanup(), but we are wondering if this new behavior is as expected? It is easy to demonstrate the behavior, by changing the standard multi-event example from the documentation, as follows: diff --git a/docs/examples/multi-event.c b/docs/examples/multi-event.c index 450ac7871..78a56a26d 100644 --- a/docs/examples/multi-event.c +++ b/docs/examples/multi-event.c @@ -181,6 +181,8 @@ static int handle_socket(CURL *easy, curl_socket_t s, int action, void *userp, (void)easy; (void)userp; + fprintf(stderr, "handle_socket: easy=%p, s=%d, action=%d\n", easy, s, action); + switch(action) { case CURL_POLL_IN: case CURL_POLL_OUT: @@ -240,7 +242,9 @@ int main(int argc, char **argv) event_base_dispatch(base); + fprintf(stderr, "calling curl_multi_cleanup\n"); curl_multi_cleanup(curl_handle); + fprintf(stderr, "called curl_multi_cleanup\n"); event_free(timeout); event_base_free(base); If you build this modified multi-event example, and link it against curl-8_9_1-236-g432f2fd9a (so just before the a58b50f commit), the output looks something like: $ ./multi-event-curl-8_9_1-236-g432f2fd9a https://curl.se/ Added download https://curl.se/ -> 1.download handle_socket: easy=0x5586918cd7a0, s=9, action=1 handle_socket: easy=0x5586918cd7a0, s=9, action=4 handle_socket: easy=0x5586918cd7a0, s=9, action=2 handle_socket: easy=0x5586918cd7a0, s=9, action=1 handle_socket: easy=0x5586918cd7a0, s=9, action=4 https://curl.se/ DONE calling curl_multi_cleanup called curl_multi_cleanup But link it against curl-8_9_1-237-ga58b50fca (or later!), and the output becomes: $ ./multi-event-curl-8_9_1-237-ga58b50fca https://curl.se/ Added download https://curl.se/ -> 1.download handle_socket: easy=0x55fa15be87a0, s=9, action=1 handle_socket: easy=0x55fa15be87a0, s=9, action=4 handle_socket: easy=0x55fa15be87a0, s=9, action=2 handle_socket: easy=0x55fa15be87a0, s=9, action=1 handle_socket: easy=0x55fa15be87a0, s=9, action=4 https://curl.se/ DONE calling curl_multi_cleanup handle_socket: easy=0x55fa15be72e0, s=9, action=1 handle_socket: easy=0x55fa15be72e0, s=9, action=4 called curl_multi_cleanup You can see that handle_socket() is now being called _during_ the curl_multi_cleanup() call, whereas that did not happen before. As far as we can determine, these callbacks occur because a58b50fca introduces an extra internal handle in conncache.c, which gets triggered with a CURL_POLL_IN event, followed by a CURL_POLL_REMOVE. The question is whether that was intentional or not? -Dimitry -- Unsubscribe: https://lists.haxx.se/mailman/listinfo/curl-library Etiquette: https://curl.se/mail/etiquette.html