diff options
author | Daniel Stenberg <daniel@haxx.se> | 2022-01-16 23:00:09 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2022-01-17 16:44:45 +0100 |
commit | 340bb1905f88b13655e89760ca6f4f2d02dc011a (patch) | |
tree | 7f4e4a574a87a2c4c6dafe6c25ca4a1fc90271f8 | |
parent | a3d2eeab01c709c85e125f8afa498326783312ce (diff) | |
download | curl-340bb1905f88b13655e89760ca6f4f2d02dc011a.tar.gz |
multi: set in_callback for multi interface callbacks
This makes most libcurl functions return error if called from within a
callback using the same multi handle. For example timer or socket
callbacks calling curl_multi_socket_action.
Reported-by: updatede on github
Fixes #8282
Closes #8286
-rw-r--r-- | lib/multi.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/lib/multi.c b/lib/multi.c index f8dcc63b4..c2a8a6b09 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -1759,6 +1759,10 @@ CURLcode Curl_preconnect(struct Curl_easy *data) return CURLE_OK; } +static void set_in_callback(struct Curl_multi *multi, bool value) +{ + multi->in_callback = value; +} static CURLMcode multi_runsingle(struct Curl_multi *multi, struct curltime *nowp, @@ -2872,8 +2876,10 @@ static CURLMcode singlesocket(struct Curl_multi *multi, continue; if(multi->socket_cb) { + set_in_callback(multi, TRUE); rc = multi->socket_cb(data, s, comboaction, multi->socket_userp, entry->socketp); + set_in_callback(multi, FALSE); if(rc == -1) { multi->dead = TRUE; return CURLM_ABORTED_BY_CALLBACK; @@ -2914,8 +2920,10 @@ static CURLMcode singlesocket(struct Curl_multi *multi, entry->readers--; if(!entry->users) { if(multi->socket_cb) { + set_in_callback(multi, TRUE); rc = multi->socket_cb(data, s, CURL_POLL_REMOVE, multi->socket_userp, entry->socketp); + set_in_callback(multi, FALSE); if(rc == -1) { multi->dead = TRUE; return CURLM_ABORTED_BY_CALLBACK; @@ -2969,9 +2977,12 @@ void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s) if(entry) { int rc = 0; - if(multi->socket_cb) + if(multi->socket_cb) { + set_in_callback(multi, TRUE); rc = multi->socket_cb(data, s, CURL_POLL_REMOVE, multi->socket_userp, entry->socketp); + set_in_callback(multi, FALSE); + } /* now remove it from the socket hash */ sh_delentry(entry, &multi->sockhash, s); @@ -3343,7 +3354,9 @@ CURLMcode Curl_update_timer(struct Curl_multi *multi) multi->timer_lastcall = none; /* there's no timeout now but there was one previously, tell the app to disable it */ + set_in_callback(multi, TRUE); rc = multi->timer_cb(multi, -1, multi->timer_userp); + set_in_callback(multi, FALSE); if(rc == -1) { multi->dead = TRUE; return CURLM_ABORTED_BY_CALLBACK; @@ -3362,7 +3375,9 @@ CURLMcode Curl_update_timer(struct Curl_multi *multi) multi->timer_lastcall = multi->timetree->key; + set_in_callback(multi, TRUE); rc = multi->timer_cb(multi, timeout_ms, multi->timer_userp); + set_in_callback(multi, FALSE); if(rc == -1) { multi->dead = TRUE; return CURLM_ABORTED_BY_CALLBACK; |