From d7c75c3608d6002cfb46a2612efa507d9a8ba66e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 20 Mar 2023 12:51:05 +0100 Subject: [PATCH] Revert "multi: remove PENDING + MSGSENT handles from the main linked list" This reverts commit f6d6f3ce01e377932f1ce7c24ee34d45a36950b8. The commits caused issues in the 8.0.0 release. Needs a retake. Upstream-commit: cf1eebc68a28cb18bffde5a0a0d2f02bf7b183ec Signed-off-by: Kamil Dudka --- lib/multi.c | 73 +++++++++++++++++++---------------------------- lib/multihandle.h | 2 -- lib/urldata.h | 3 +- 3 files changed, 31 insertions(+), 47 deletions(-) diff --git a/lib/multi.c b/lib/multi.c index 0967500d0..731b2598f 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -383,10 +383,12 @@ static void sh_init(struct Curl_hash *hash, int hashsize) * Called when a transfer is completed. Adds the given msg pointer to * the list kept in the multi handle. */ -static void multi_addmsg(struct Curl_multi *multi, struct Curl_message *msg) +static CURLMcode multi_addmsg(struct Curl_multi *multi, + struct Curl_message *msg) { Curl_llist_insert_next(&multi->msglist, multi->msglist.tail, msg, &msg->list); + return CURLM_OK; } struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ @@ -409,7 +411,6 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ Curl_llist_init(&multi->msglist, NULL); Curl_llist_init(&multi->pending, NULL); - Curl_llist_init(&multi->msgsent, NULL); multi->multiplexing = TRUE; @@ -455,14 +456,6 @@ struct Curl_multi *curl_multi_init(void) CURL_DNS_HASH_SIZE); } -/* returns TRUE if the easy handle is supposed to be present in the main link - list */ -static bool in_main_list(struct Curl_easy *data) -{ - return ((data->mstate != MSTATE_PENDING) && - (data->mstate != MSTATE_MSGSENT)); -} - static void link_easy(struct Curl_multi *multi, struct Curl_easy *data) { @@ -496,8 +489,6 @@ static void unlink_easy(struct Curl_multi *multi, data->next->prev = data->prev; else multi->easylp = data->prev; /* point to last node */ - - data->prev = data->next = NULL; } @@ -857,16 +848,10 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, called. Do it after multi_done() in case that sets another time! */ Curl_expire_clear(data); - if(data->connect_queue.ptr) { - /* the handle is in the pending or msgsent lists, so go ahead and remove - it */ - if(data->mstate == MSTATE_PENDING) - Curl_llist_remove(&multi->pending, &data->connect_queue, NULL); - else - Curl_llist_remove(&multi->msgsent, &data->connect_queue, NULL); - } - if(in_main_list(data)) - unlink_easy(multi, data); + if(data->connect_queue.ptr) + /* the handle was in the pending list waiting for an available connection, + so go ahead and remove it */ + Curl_llist_remove(&multi->pending, &data->connect_queue, NULL); if(data->dns.hostcachetype == HCACHE_MULTI) { /* stop using the multi handle's DNS cache, *after* the possible @@ -927,6 +912,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, /* make sure there's no pending message in the queue sent from this easy handle */ + for(e = multi->msglist.head; e; e = e->next) { struct Curl_message *msg = e->ptr; @@ -937,6 +923,19 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, } } + /* Remove from the pending list if it is there. Otherwise this will + remain on the pending list forever due to the state change. */ + for(e = multi->pending.head; e; e = e->next) { + struct Curl_easy *curr_data = e->ptr; + + if(curr_data == data) { + Curl_llist_remove(&multi->pending, e, NULL); + break; + } + } + + unlink_easy(multi, data); + /* NOTE NOTE NOTE We do not touch the easy handle here! */ multi->num_easy--; /* one less to care about now */ @@ -1944,6 +1943,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } break; + case MSTATE_PENDING: + /* We will stay here until there is a connection available. Then + we try again in the MSTATE_CONNECT state. */ + break; + case MSTATE_CONNECT: /* Connect. We want to get a connection identifier filled in. */ /* init this transfer. */ @@ -1967,8 +1971,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* add this handle to the list of connect-pending handles */ Curl_llist_insert_next(&multi->pending, multi->pending.tail, data, &data->connect_queue); - /* unlink from the main list */ - unlink_easy(multi, data); result = CURLE_OK; break; } @@ -2595,11 +2597,9 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, case MSTATE_COMPLETED: break; - case MSTATE_PENDING: case MSTATE_MSGSENT: - /* handles in these states should NOT be in this list */ - DEBUGASSERT(0); - break; + data->result = result; + return CURLM_OK; /* do nothing */ default: return CURLM_INTERNAL_ERROR; @@ -2687,17 +2687,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, msg->extmsg.easy_handle = data; msg->extmsg.data.result = result; - multi_addmsg(multi, msg); + rc = multi_addmsg(multi, msg); DEBUGASSERT(!data->conn); } multistate(data, MSTATE_MSGSENT); - - /* add this handle to the list of msgsent handles */ - Curl_llist_insert_next(&multi->msgsent, multi->msgsent.tail, data, - &data->connect_queue); - /* unlink from the main list */ - unlink_easy(multi, data); - return CURLM_OK; } } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE)); @@ -2728,9 +2721,6 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles) /* Do the loop and only alter the signal ignore state if the next handle has a different NO_SIGNAL state than the previous */ do { - /* the current node might be unlinked in multi_runsingle(), get the next - pointer now */ - struct Curl_easy *datanext = data->next; if(data->set.no_signal != nosig) { sigpipe_restore(&pipe_st); sigpipe_ignore(data, &pipe_st); @@ -2739,7 +2729,7 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles) result = multi_runsingle(multi, &now, data); if(result) returncode = result; - data = datanext; /* operate on next handle */ + data = data->next; /* operate on next handle */ } while(data); sigpipe_restore(&pipe_st); } @@ -3720,9 +3710,6 @@ static void process_pending_handles(struct Curl_multi *multi) DEBUGASSERT(data->mstate == MSTATE_PENDING); - /* put it back into the main list */ - link_easy(multi, data); - multistate(data, MSTATE_CONNECT); /* Remove this node from the list */ diff --git a/lib/multihandle.h b/lib/multihandle.h index 5b16bb605..6cda65d44 100644 --- a/lib/multihandle.h +++ b/lib/multihandle.h @@ -101,8 +101,6 @@ struct Curl_multi { struct Curl_llist pending; /* Curl_easys that are in the MSTATE_PENDING state */ - struct Curl_llist msgsent; /* Curl_easys that are in the - MSTATE_MSGSENT state */ /* callback function and user data pointer for the *socket() API */ curl_socket_callback socket_cb; diff --git a/lib/urldata.h b/lib/urldata.h index 4e07bcd60..8b54518d2 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -1894,8 +1894,7 @@ struct Curl_easy { struct Curl_easy *prev; struct connectdata *conn; - struct Curl_llist_element connect_queue; /* for the pending and msgsent - lists */ + struct Curl_llist_element connect_queue; struct Curl_llist_element conn_queue; /* list per connectdata */ CURLMstate mstate; /* the handle's state */ -- 2.40.0