mirror of
https://github.com/curl/curl.git
synced 2026-04-14 21:41:41 +03:00
multi: make the "general" list of easy handles a Curl_llist
Instead of having an especially "unique" linked list handler for the main list of easy handles within the multi handle, this now uses a regular Curl_llist for this as well. With this change, it is also clearer that every easy handle added to a multi handle belongs to one and only one out of three different lists: process - the general one for normal transfer processing pending - queued up waiting to get a connection (MSTATE_PENDING) msgsent - transfer completed (MSTATE_MSGSENT) An easy handle must therefore be removed from the current list before it gets added to another. Closes #14474
This commit is contained in:
parent
9e4a2187e7
commit
2c15ee4bdb
7 changed files with 112 additions and 135 deletions
10
lib/easy.c
10
lib/easy.c
|
|
@ -597,14 +597,20 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
|
|||
}
|
||||
else {
|
||||
/* here pollrc is > 0 */
|
||||
struct Curl_llist_element *e = multi->process.head;
|
||||
struct Curl_easy *data;
|
||||
DEBUGASSERT(e);
|
||||
data = e->ptr;
|
||||
DEBUGASSERT(data);
|
||||
|
||||
/* loop over the monitored sockets to see which ones had activity */
|
||||
for(i = 0; i< numfds; i++) {
|
||||
if(fds[i].revents) {
|
||||
/* socket activity, tell libcurl */
|
||||
int act = poll2cselect(fds[i].revents); /* convert */
|
||||
infof(multi->easyp,
|
||||
"call curl_multi_socket_action(socket "
|
||||
|
||||
/* sending infof "randomly" to the first easy handle */
|
||||
infof(data, "call curl_multi_socket_action(socket "
|
||||
"%" CURL_FORMAT_SOCKET_T ")", (curl_socket_t)fds[i].fd);
|
||||
mcode = curl_multi_socket_action(multi, fds[i].fd, act,
|
||||
&ev->running_handles);
|
||||
|
|
|
|||
180
lib/multi.c
180
lib/multi.c
|
|
@ -414,6 +414,7 @@ struct Curl_multi *Curl_multi_handle(size_t hashsize, /* socket hash */
|
|||
goto error;
|
||||
|
||||
Curl_llist_init(&multi->msglist, NULL);
|
||||
Curl_llist_init(&multi->process, NULL);
|
||||
Curl_llist_init(&multi->pending, NULL);
|
||||
Curl_llist_init(&multi->msgsent, NULL);
|
||||
|
||||
|
|
@ -466,49 +467,18 @@ static void multi_warn_debug(struct Curl_multi *multi, struct Curl_easy *data)
|
|||
#define multi_warn_debug(x,y) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
/* 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)
|
||||
{
|
||||
/* We add the new easy entry last in the list. */
|
||||
data->next = NULL; /* end of the line */
|
||||
if(multi->easyp) {
|
||||
struct Curl_easy *last = multi->easylp;
|
||||
last->next = data;
|
||||
data->prev = last;
|
||||
multi->easylp = data; /* the new last node */
|
||||
}
|
||||
else {
|
||||
/* first node, make prev NULL! */
|
||||
data->prev = NULL;
|
||||
multi->easylp = multi->easyp = data; /* both first and last */
|
||||
}
|
||||
/* add the easy handle to the process list */
|
||||
Curl_llist_append(&multi->process, data, &data->multi_queue);
|
||||
}
|
||||
|
||||
/* unlink the given easy handle from the linked list of easy handles */
|
||||
/* unlink the given easy handle from the process list */
|
||||
static void unlink_easy(struct Curl_multi *multi,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
/* make the previous node point to our next */
|
||||
if(data->prev)
|
||||
data->prev->next = data->next;
|
||||
else
|
||||
multi->easyp = data->next; /* point to first node */
|
||||
|
||||
/* make our next point to our previous node */
|
||||
if(data->next)
|
||||
data->next->prev = data->prev;
|
||||
else
|
||||
multi->easylp = data->prev; /* point to last node */
|
||||
|
||||
data->prev = data->next = NULL;
|
||||
Curl_llist_remove(&multi->process, &data->multi_queue, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -888,16 +858,15 @@ 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->multi_queue.ptr) {
|
||||
/* the handle is in a list, remove it from the right one */
|
||||
if(data->mstate == MSTATE_PENDING)
|
||||
Curl_llist_remove(&multi->pending, &data->connect_queue, NULL);
|
||||
Curl_llist_remove(&multi->pending, &data->multi_queue, NULL);
|
||||
else if(data->mstate == MSTATE_MSGSENT)
|
||||
Curl_llist_remove(&multi->msgsent, &data->multi_queue, NULL);
|
||||
else
|
||||
Curl_llist_remove(&multi->msgsent, &data->connect_queue, NULL);
|
||||
Curl_llist_remove(&multi->process, &data->multi_queue, NULL);
|
||||
}
|
||||
if(in_main_list(data))
|
||||
unlink_easy(multi, data);
|
||||
|
||||
if(data->dns.hostcachetype == HCACHE_MULTI) {
|
||||
/* stop using the multi handle's DNS cache, *after* the possible
|
||||
|
|
@ -1210,10 +1179,9 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
|
|||
/* Scan through all the easy handles to get the file descriptors set.
|
||||
Some easy handles may not have connected to the remote host yet,
|
||||
and then we must make sure that is done. */
|
||||
struct Curl_easy *data;
|
||||
int this_max_fd = -1;
|
||||
struct easy_pollset ps;
|
||||
unsigned int i;
|
||||
struct Curl_llist_element *e;
|
||||
(void)exc_fd_set; /* not used */
|
||||
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
|
|
@ -1223,7 +1191,10 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
|
|||
return CURLM_RECURSIVE_API_CALL;
|
||||
|
||||
memset(&ps, 0, sizeof(ps));
|
||||
for(data = multi->easyp; data; data = data->next) {
|
||||
for(e = multi->process.head; e; e = e->next) {
|
||||
struct Curl_easy *data = e->ptr;
|
||||
unsigned int i;
|
||||
|
||||
multi_getsock(data, &ps);
|
||||
|
||||
for(i = 0; i < ps.num; i++) {
|
||||
|
|
@ -1249,10 +1220,10 @@ CURLMcode curl_multi_waitfds(struct Curl_multi *multi,
|
|||
unsigned int size,
|
||||
unsigned int *fd_count)
|
||||
{
|
||||
struct Curl_easy *data;
|
||||
struct curl_waitfds cwfds;
|
||||
struct easy_pollset ps;
|
||||
CURLMcode result = CURLM_OK;
|
||||
struct Curl_llist_element *e;
|
||||
|
||||
if(!ufds)
|
||||
return CURLM_BAD_FUNCTION_ARGUMENT;
|
||||
|
|
@ -1265,7 +1236,8 @@ CURLMcode curl_multi_waitfds(struct Curl_multi *multi,
|
|||
|
||||
Curl_waitfds_init(&cwfds, ufds, size);
|
||||
memset(&ps, 0, sizeof(ps));
|
||||
for(data = multi->easyp; data; data = data->next) {
|
||||
for(e = multi->process.head; e; e = e->next) {
|
||||
struct Curl_easy *data = e->ptr;
|
||||
multi_getsock(data, &ps);
|
||||
if(Curl_waitfds_add_ps(&cwfds, &ps)) {
|
||||
result = CURLM_OUT_OF_MEMORY;
|
||||
|
|
@ -1310,7 +1282,6 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
|
|||
bool extrawait, /* when no socket, wait */
|
||||
bool use_wakeup)
|
||||
{
|
||||
struct Curl_easy *data;
|
||||
struct easy_pollset ps;
|
||||
size_t i;
|
||||
long timeout_internal;
|
||||
|
|
@ -1319,6 +1290,8 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
|
|||
struct curl_pollfds cpfds;
|
||||
unsigned int curl_nfds = 0; /* how many pfds are for curl transfers */
|
||||
CURLMcode result = CURLM_OK;
|
||||
struct Curl_llist_element *e;
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
WSANETWORKEVENTS wsa_events;
|
||||
DEBUGASSERT(multi->wsa_event != WSA_INVALID_EVENT);
|
||||
|
|
@ -1340,7 +1313,9 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
|
|||
memset(&ps, 0, sizeof(ps));
|
||||
|
||||
/* Add the curl handles to our pollfds first */
|
||||
for(data = multi->easyp; data; data = data->next) {
|
||||
for(e = multi->process.head; e; e = e->next) {
|
||||
struct Curl_easy *data = e->ptr;
|
||||
|
||||
multi_getsock(data, &ps);
|
||||
if(Curl_pollfds_add_ps(&cpfds, &ps)) {
|
||||
result = CURLM_OUT_OF_MEMORY;
|
||||
|
|
@ -1478,8 +1453,8 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
|
|||
/* Count up all our own sockets that had activity,
|
||||
and remove them from the event. */
|
||||
if(curl_nfds) {
|
||||
|
||||
for(data = multi->easyp; data; data = data->next) {
|
||||
for(e = multi->process.head; e && !result; e = e->next) {
|
||||
struct Curl_easy *data = e->ptr;
|
||||
multi_getsock(data, &ps);
|
||||
|
||||
for(i = 0; i < ps.num; i++) {
|
||||
|
|
@ -1972,11 +1947,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||
/* There was no connection available. We will go to the pending
|
||||
state and wait for an available connection. */
|
||||
multistate(data, MSTATE_PENDING);
|
||||
|
||||
/* add this handle to the list of connect-pending handles */
|
||||
Curl_llist_append(&multi->pending, data, &data->connect_queue);
|
||||
/* unlink from the main list */
|
||||
/* unlink from process list */
|
||||
unlink_easy(multi, data);
|
||||
/* add handle to pending list */
|
||||
Curl_llist_append(&multi->pending, data, &data->multi_queue);
|
||||
result = CURLE_OK;
|
||||
break;
|
||||
}
|
||||
|
|
@ -2687,10 +2661,10 @@ statemachine_end:
|
|||
}
|
||||
multistate(data, MSTATE_MSGSENT);
|
||||
|
||||
/* add this handle to the list of msgsent handles */
|
||||
Curl_llist_append(&multi->msgsent, data, &data->connect_queue);
|
||||
/* unlink from the main list */
|
||||
unlink_easy(multi, data);
|
||||
/* add this handle to the list of msgsent handles */
|
||||
Curl_llist_append(&multi->msgsent, data, &data->multi_queue);
|
||||
return CURLM_OK;
|
||||
}
|
||||
} while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
|
||||
|
|
@ -2702,10 +2676,11 @@ statemachine_end:
|
|||
|
||||
CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
|
||||
{
|
||||
struct Curl_easy *data;
|
||||
CURLMcode returncode = CURLM_OK;
|
||||
struct Curl_tree *t;
|
||||
struct curltime now = Curl_now();
|
||||
struct Curl_llist_element *e;
|
||||
struct Curl_llist_element *n = NULL;
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
|
|
@ -2715,26 +2690,23 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
|
|||
return CURLM_RECURSIVE_API_CALL;
|
||||
|
||||
sigpipe_init(&pipe_st);
|
||||
data = multi->easyp;
|
||||
if(data) {
|
||||
for(e = multi->process.head; e; e = n) {
|
||||
struct Curl_easy *data = e->ptr;
|
||||
CURLMcode result;
|
||||
/* 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;
|
||||
|
||||
/* the current node might be unlinked in multi_runsingle(), get the next
|
||||
pointer now */
|
||||
n = e->next;
|
||||
|
||||
if(data != multi->conn_cache.closure_handle) {
|
||||
/* connection cache handle is processed below */
|
||||
sigpipe_apply(data, &pipe_st);
|
||||
result = multi_runsingle(multi, &now, data);
|
||||
if(result)
|
||||
returncode = result;
|
||||
}
|
||||
|
||||
data = datanext; /* operate on next handle */
|
||||
} while(data);
|
||||
/* connection cache handle is processed below */
|
||||
sigpipe_apply(data, &pipe_st);
|
||||
result = multi_runsingle(multi, &now, data);
|
||||
if(result)
|
||||
returncode = result;
|
||||
}
|
||||
}
|
||||
|
||||
sigpipe_apply(multi->conn_cache.closure_handle, &pipe_st);
|
||||
|
|
@ -2756,7 +2728,7 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
|
|||
multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
|
||||
if(t) {
|
||||
/* the removed may have another timeout in queue */
|
||||
data = t->payload;
|
||||
struct Curl_easy *data = t->payload;
|
||||
if(data->mstate == MSTATE_PENDING) {
|
||||
bool stream_unused;
|
||||
CURLcode result_unused;
|
||||
|
|
@ -2779,38 +2751,45 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
|
|||
return returncode;
|
||||
}
|
||||
|
||||
/* unlink_all_msgsent_handles() detaches all those easy handles from this
|
||||
multi handle */
|
||||
/* unlink_all_msgsent_handles() moves all nodes back from the msgsent list to
|
||||
the process list */
|
||||
static void unlink_all_msgsent_handles(struct Curl_multi *multi)
|
||||
{
|
||||
struct Curl_llist_element *e = multi->msgsent.head;
|
||||
if(e) {
|
||||
struct Curl_llist_element *e;
|
||||
for(e = multi->msgsent.head; e; e = e->next) {
|
||||
struct Curl_easy *data = e->ptr;
|
||||
DEBUGASSERT(data->mstate == MSTATE_MSGSENT);
|
||||
data->multi = NULL;
|
||||
if(data) {
|
||||
DEBUGASSERT(data->mstate == MSTATE_MSGSENT);
|
||||
Curl_llist_remove(&multi->msgsent, &data->multi_queue, NULL);
|
||||
/* put it into the process list */
|
||||
link_easy(multi, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
|
||||
{
|
||||
struct Curl_easy *data;
|
||||
struct Curl_easy *nextdata;
|
||||
|
||||
if(GOOD_MULTI_HANDLE(multi)) {
|
||||
struct Curl_llist_element *e;
|
||||
struct Curl_llist_element *n;
|
||||
if(multi->in_callback)
|
||||
return CURLM_RECURSIVE_API_CALL;
|
||||
|
||||
multi->magic = 0; /* not good anymore */
|
||||
|
||||
/* move the pending and msgsent entries back to process
|
||||
so that there is just one list to iterate over */
|
||||
unlink_all_msgsent_handles(multi);
|
||||
process_pending_handles(multi);
|
||||
|
||||
/* First remove all remaining easy handles */
|
||||
data = multi->easyp;
|
||||
while(data) {
|
||||
for(e = multi->process.head; e; e = n) {
|
||||
struct Curl_easy *data = e->ptr;
|
||||
|
||||
if(!GOOD_EASY_HANDLE(data))
|
||||
return CURLM_BAD_HANDLE;
|
||||
|
||||
nextdata = data->next;
|
||||
n = e->next;
|
||||
if(!data->state.done && data->conn)
|
||||
/* if DONE was never called for this handle */
|
||||
(void)multi_done(data, CURLE_OK, TRUE);
|
||||
|
|
@ -2829,8 +2808,6 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
|
|||
if(data->psl == &multi->psl)
|
||||
data->psl = NULL;
|
||||
#endif
|
||||
|
||||
data = nextdata;
|
||||
}
|
||||
|
||||
/* Close all the connections in the connection cache */
|
||||
|
|
@ -3185,16 +3162,15 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
|||
SIGPIPE_VARIABLE(pipe_st);
|
||||
|
||||
if(checkall) {
|
||||
struct Curl_llist_element *e;
|
||||
/* *perform() deals with running_handles on its own */
|
||||
result = curl_multi_perform(multi, running_handles);
|
||||
|
||||
/* walk through each easy handle and do the socket state change magic
|
||||
and callbacks */
|
||||
if(result != CURLM_BAD_HANDLE) {
|
||||
data = multi->easyp;
|
||||
while(data && !result) {
|
||||
result = singlesocket(multi, data);
|
||||
data = data->next;
|
||||
for(e = multi->process.head; e && !result; e = e->next) {
|
||||
result = singlesocket(multi, e->ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3241,8 +3217,6 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
|||
to force the user to have to deal with timeouts as long as at least
|
||||
one connection in fact has traffic. */
|
||||
|
||||
data = NULL; /* set data to NULL again to avoid calling
|
||||
multi_runsingle() in case there is no need to */
|
||||
now = Curl_now(); /* get a newer time since the multi_runsingle() loop
|
||||
may have taken some time */
|
||||
}
|
||||
|
|
@ -3751,14 +3725,14 @@ static void move_pending_to_connect(struct Curl_multi *multi,
|
|||
{
|
||||
DEBUGASSERT(data->mstate == MSTATE_PENDING);
|
||||
|
||||
/* put it back into the main list */
|
||||
/* Remove this node from the pending list */
|
||||
Curl_llist_remove(&multi->pending, &data->multi_queue, NULL);
|
||||
|
||||
/* put it into the process list */
|
||||
link_easy(multi, data);
|
||||
|
||||
multistate(data, MSTATE_CONNECT);
|
||||
|
||||
/* Remove this node from the pending list */
|
||||
Curl_llist_remove(&multi->pending, &data->connect_queue, NULL);
|
||||
|
||||
/* Make sure that the handle will be processed soonish. */
|
||||
Curl_expire(data, 0, EXPIRE_RUN_NOW);
|
||||
}
|
||||
|
|
@ -3809,12 +3783,12 @@ struct Curl_easy **curl_multi_get_handles(struct Curl_multi *multi)
|
|||
(multi->num_easy + 1));
|
||||
if(a) {
|
||||
unsigned int i = 0;
|
||||
struct Curl_easy *e = multi->easyp;
|
||||
while(e) {
|
||||
struct Curl_llist_element *e;
|
||||
for(e = multi->process.head; e; e = e->next) {
|
||||
struct Curl_easy *data = e->ptr;
|
||||
DEBUGASSERT(i < multi->num_easy);
|
||||
if(!e->state.internal)
|
||||
a[i++] = e;
|
||||
e = e->next;
|
||||
if(!data->state.internal)
|
||||
a[i++] = data;
|
||||
}
|
||||
a[i] = NULL; /* last entry is a NULL */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,20 +86,16 @@ struct Curl_multi {
|
|||
this multi handle with an easy handle. Set this to CURL_MULTI_HANDLE. */
|
||||
unsigned int magic;
|
||||
|
||||
/* We have a doubly-linked list with easy handles */
|
||||
struct Curl_easy *easyp;
|
||||
struct Curl_easy *easylp; /* last node */
|
||||
|
||||
unsigned int num_easy; /* amount of entries in the linked list above. */
|
||||
unsigned int num_alive; /* amount of easy handles that are added but have
|
||||
not yet reached COMPLETE state */
|
||||
|
||||
struct Curl_llist msglist; /* a list of messages from completed transfers */
|
||||
|
||||
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 */
|
||||
/* Each added easy handle is in ONE of these three lists */
|
||||
struct Curl_llist process; /* not in PENDING or MSGSENT */
|
||||
struct Curl_llist pending; /* in PENDING */
|
||||
struct Curl_llist msgsent; /* in MSGSENT */
|
||||
|
||||
/* callback function and user data pointer for the *socket() API */
|
||||
curl_socket_callback socket_cb;
|
||||
|
|
|
|||
|
|
@ -1910,13 +1910,8 @@ struct Curl_easy {
|
|||
has no uniqueness guarantee for very large processings. */
|
||||
curl_off_t id;
|
||||
|
||||
/* first, two fields for the linked list of these */
|
||||
struct Curl_easy *next;
|
||||
struct Curl_easy *prev;
|
||||
|
||||
struct connectdata *conn;
|
||||
struct Curl_llist_element connect_queue; /* for the pending and msgsent
|
||||
lists */
|
||||
struct Curl_llist_element multi_queue; /* for multihandle list management */
|
||||
struct Curl_llist_element conn_queue; /* list per connectdata */
|
||||
|
||||
CURLMstate mstate; /* the handle's state */
|
||||
|
|
|
|||
|
|
@ -265,7 +265,6 @@ static struct Curl_easy *get_stream_easy(struct Curl_cfilter *cf,
|
|||
struct h3_stream_ctx **pstream)
|
||||
{
|
||||
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
||||
struct Curl_easy *sdata;
|
||||
struct h3_stream_ctx *stream;
|
||||
|
||||
(void)cf;
|
||||
|
|
@ -275,8 +274,10 @@ static struct Curl_easy *get_stream_easy(struct Curl_cfilter *cf,
|
|||
return data;
|
||||
}
|
||||
else {
|
||||
struct Curl_llist_element *e;
|
||||
DEBUGASSERT(data->multi);
|
||||
for(sdata = data->multi->easyp; sdata; sdata = sdata->next) {
|
||||
for(e = data->multi->process.head; e; e = e->next) {
|
||||
struct Curl_easy *sdata = e->ptr;
|
||||
if(sdata->conn != data->conn)
|
||||
continue;
|
||||
stream = H3_STREAM_CTX(ctx, sdata);
|
||||
|
|
|
|||
|
|
@ -655,7 +655,6 @@ static struct cf_osslq_stream *cf_osslq_get_qstream(struct Curl_cfilter *cf,
|
|||
{
|
||||
struct cf_osslq_ctx *ctx = cf->ctx;
|
||||
struct h3_stream_ctx *stream = H3_STREAM_CTX(ctx, data);
|
||||
struct Curl_easy *sdata;
|
||||
|
||||
if(stream && stream->s.id == stream_id) {
|
||||
return &stream->s;
|
||||
|
|
@ -670,8 +669,10 @@ static struct cf_osslq_stream *cf_osslq_get_qstream(struct Curl_cfilter *cf,
|
|||
return &ctx->h3.s_qpack_dec;
|
||||
}
|
||||
else {
|
||||
struct Curl_llist_element *e;
|
||||
DEBUGASSERT(data->multi);
|
||||
for(sdata = data->multi->easyp; sdata; sdata = sdata->next) {
|
||||
for(e = data->multi->process.head; e; e = e->next) {
|
||||
struct Curl_easy *sdata = e->ptr;
|
||||
if(sdata->conn != data->conn)
|
||||
continue;
|
||||
stream = H3_STREAM_CTX(ctx, sdata);
|
||||
|
|
@ -1422,11 +1423,12 @@ static CURLcode cf_progress_ingress(struct Curl_cfilter *cf,
|
|||
}
|
||||
|
||||
if(ctx->h3.conn) {
|
||||
struct Curl_easy *sdata;
|
||||
struct Curl_llist_element *e;
|
||||
struct h3_stream_ctx *stream;
|
||||
/* PULL all open streams */
|
||||
DEBUGASSERT(data->multi);
|
||||
for(sdata = data->multi->easyp; sdata; sdata = sdata->next) {
|
||||
for(e = data->multi->process.head; e; e = e->next) {
|
||||
struct Curl_easy *sdata = e->ptr;
|
||||
if(sdata->conn == data->conn && CURL_WANT_RECV(sdata)) {
|
||||
stream = H3_STREAM_CTX(ctx, sdata);
|
||||
if(stream && !stream->closed &&
|
||||
|
|
@ -1449,11 +1451,12 @@ static CURLcode cf_osslq_check_and_unblock(struct Curl_cfilter *cf,
|
|||
struct Curl_easy *data)
|
||||
{
|
||||
struct cf_osslq_ctx *ctx = cf->ctx;
|
||||
struct Curl_easy *sdata;
|
||||
struct h3_stream_ctx *stream;
|
||||
|
||||
if(ctx->h3.conn) {
|
||||
for(sdata = data->multi->easyp; sdata; sdata = sdata->next) {
|
||||
struct Curl_llist_element *e;
|
||||
for(e = data->multi->process.head; e; e = e->next) {
|
||||
struct Curl_easy *sdata = e->ptr;
|
||||
if(sdata->conn == data->conn) {
|
||||
stream = H3_STREAM_CTX(ctx, sdata);
|
||||
if(stream && stream->s.ssl && stream->s.send_blocked &&
|
||||
|
|
|
|||
|
|
@ -177,13 +177,13 @@ static void check_resumes(struct Curl_cfilter *cf,
|
|||
struct Curl_easy *data)
|
||||
{
|
||||
struct cf_quiche_ctx *ctx = cf->ctx;
|
||||
struct Curl_easy *sdata;
|
||||
struct stream_ctx *stream;
|
||||
struct Curl_llist_element *e;
|
||||
|
||||
DEBUGASSERT(data->multi);
|
||||
for(sdata = data->multi->easyp; sdata; sdata = sdata->next) {
|
||||
for(e = data->multi->process.head; e; e = e->next) {
|
||||
struct Curl_easy *sdata = e->ptr;
|
||||
if(sdata->conn == data->conn) {
|
||||
stream = H3_STREAM_CTX(ctx, sdata);
|
||||
struct stream_ctx *stream = H3_STREAM_CTX(ctx, sdata);
|
||||
if(stream && stream->quic_flow_blocked) {
|
||||
stream->quic_flow_blocked = FALSE;
|
||||
Curl_expire(data, 0, EXPIRE_RUN_NOW);
|
||||
|
|
@ -268,7 +268,6 @@ static struct Curl_easy *get_stream_easy(struct Curl_cfilter *cf,
|
|||
struct stream_ctx **pstream)
|
||||
{
|
||||
struct cf_quiche_ctx *ctx = cf->ctx;
|
||||
struct Curl_easy *sdata;
|
||||
struct stream_ctx *stream;
|
||||
|
||||
(void)cf;
|
||||
|
|
@ -278,8 +277,10 @@ static struct Curl_easy *get_stream_easy(struct Curl_cfilter *cf,
|
|||
return data;
|
||||
}
|
||||
else {
|
||||
struct Curl_llist_element *e;
|
||||
DEBUGASSERT(data->multi);
|
||||
for(sdata = data->multi->easyp; sdata; sdata = sdata->next) {
|
||||
for(e = data->multi->process.head; e; e = e->next) {
|
||||
struct Curl_easy *sdata = e->ptr;
|
||||
if(sdata->conn != data->conn)
|
||||
continue;
|
||||
stream = H3_STREAM_CTX(ctx, sdata);
|
||||
|
|
@ -296,11 +297,12 @@ static struct Curl_easy *get_stream_easy(struct Curl_cfilter *cf,
|
|||
static void cf_quiche_expire_conn_closed(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_easy *sdata;
|
||||
struct Curl_llist_element *e;
|
||||
|
||||
DEBUGASSERT(data->multi);
|
||||
CURL_TRC_CF(data, cf, "conn closed, expire all transfers");
|
||||
for(sdata = data->multi->easyp; sdata; sdata = sdata->next) {
|
||||
for(e = data->multi->process.head; e; e = e->next) {
|
||||
struct Curl_easy *sdata = e->ptr;
|
||||
if(sdata == data || sdata->conn != data->conn)
|
||||
continue;
|
||||
CURL_TRC_CF(sdata, cf, "conn closed, expire transfer");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue