summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2022-01-16 23:00:09 +0100
committerDaniel Stenberg <daniel@haxx.se>2022-01-17 16:44:45 +0100
commit340bb1905f88b13655e89760ca6f4f2d02dc011a (patch)
tree7f4e4a574a87a2c4c6dafe6c25ca4a1fc90271f8
parenta3d2eeab01c709c85e125f8afa498326783312ce (diff)
downloadcurl-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.c19
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;