curl_multi_fdset: include the shutdown connections in the set

They were previously missing.

Follow-up from c9b95c0bb3

Fixes #15156
Reported-by: Christopher Dannemiller
Closes #16049
This commit is contained in:
Daniel Stenberg 2025-01-19 11:16:56 +01:00
parent c80715169c
commit 7c2b325004
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
5 changed files with 58 additions and 11 deletions

View File

@ -953,8 +953,9 @@ CURLcode Curl_cpool_add_pollfds(struct cpool *cpool,
return result; return result;
} }
/* return information about the shutdown connections */
unsigned int Curl_cpool_add_waitfds(struct cpool *cpool, unsigned int Curl_cpool_add_waitfds(struct cpool *cpool,
struct curl_waitfds *cwfds) struct Curl_waitfds *cwfds)
{ {
unsigned int need = 0; unsigned int need = 0;
@ -979,6 +980,46 @@ unsigned int Curl_cpool_add_waitfds(struct cpool *cpool,
return need; return need;
} }
/* return fd_set info about the shutdown connections */
void Curl_cpool_setfds(struct cpool *cpool,
fd_set *read_fd_set, fd_set *write_fd_set,
int *maxfd)
{
CPOOL_LOCK(cpool);
if(Curl_llist_head(&cpool->shutdowns)) {
struct Curl_llist_node *e;
for(e = Curl_llist_head(&cpool->shutdowns); e;
e = Curl_node_next(e)) {
struct easy_pollset ps;
unsigned int i;
struct connectdata *conn = Curl_node_elem(e);
memset(&ps, 0, sizeof(ps));
Curl_attach_connection(cpool->idata, conn);
Curl_conn_adjust_pollset(cpool->idata, &ps);
Curl_detach_connection(cpool->idata);
for(i = 0; i < ps.num; i++) {
#if defined(__DJGPP__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warith-conversion"
#endif
if(ps.actions[i] & CURL_POLL_IN)
FD_SET(ps.sockets[i], read_fd_set);
if(ps.actions[i] & CURL_POLL_OUT)
FD_SET(ps.sockets[i], write_fd_set);
#if defined(__DJGPP__)
#pragma GCC diagnostic pop
#endif
if((ps.actions[i] & (CURL_POLL_OUT | CURL_POLL_IN)) &&
((int)ps.sockets[i] > *maxfd))
*maxfd = (int)ps.sockets[i];
}
}
}
CPOOL_UNLOCK(cpool);
}
static void cpool_perform(struct cpool *cpool) static void cpool_perform(struct cpool *cpool)
{ {
struct Curl_easy *data = cpool->idata; struct Curl_easy *data = cpool->idata;

View File

@ -31,7 +31,7 @@
struct connectdata; struct connectdata;
struct Curl_easy; struct Curl_easy;
struct curl_pollfds; struct curl_pollfds;
struct curl_waitfds; struct Curl_waitfds;
struct Curl_multi; struct Curl_multi;
struct Curl_share; struct Curl_share;
@ -184,7 +184,11 @@ void Curl_cpool_do_locked(struct Curl_easy *data,
CURLcode Curl_cpool_add_pollfds(struct cpool *connc, CURLcode Curl_cpool_add_pollfds(struct cpool *connc,
struct curl_pollfds *cpfds); struct curl_pollfds *cpfds);
unsigned int Curl_cpool_add_waitfds(struct cpool *connc, unsigned int Curl_cpool_add_waitfds(struct cpool *connc,
struct curl_waitfds *cwfds); struct Curl_waitfds *cwfds);
void Curl_cpool_setfds(struct cpool *cpool,
fd_set *read_fd_set, fd_set *write_fd_set,
int *maxfd);
/** /**
* Perform maintenance on connections in the pool. Specifically, * Perform maintenance on connections in the pool. Specifically,

View File

@ -1168,6 +1168,7 @@ CURLMcode curl_multi_fdset(CURLM *m,
int this_max_fd = -1; int this_max_fd = -1;
struct Curl_llist_node *e; struct Curl_llist_node *e;
struct Curl_multi *multi = m; struct Curl_multi *multi = m;
unsigned int i;
(void)exc_fd_set; /* not used */ (void)exc_fd_set; /* not used */
if(!GOOD_MULTI_HANDLE(multi)) if(!GOOD_MULTI_HANDLE(multi))
@ -1178,7 +1179,6 @@ CURLMcode curl_multi_fdset(CURLM *m,
for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) { for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) {
struct Curl_easy *data = Curl_node_elem(e); struct Curl_easy *data = Curl_node_elem(e);
unsigned int i;
multi_getsock(data, &data->last_poll); multi_getsock(data, &data->last_poll);
@ -1202,6 +1202,8 @@ CURLMcode curl_multi_fdset(CURLM *m,
} }
} }
Curl_cpool_setfds(&multi->cpool, read_fd_set, write_fd_set, &this_max_fd);
*max_fd = this_max_fd; *max_fd = this_max_fd;
return CURLM_OK; return CURLM_OK;
@ -1212,7 +1214,7 @@ CURLMcode curl_multi_waitfds(CURLM *m,
unsigned int size, unsigned int size,
unsigned int *fd_count) unsigned int *fd_count)
{ {
struct curl_waitfds cwfds; struct Curl_waitfds cwfds;
CURLMcode result = CURLM_OK; CURLMcode result = CURLM_OK;
struct Curl_llist_node *e; struct Curl_llist_node *e;
struct Curl_multi *multi = m; struct Curl_multi *multi = m;

View File

@ -488,7 +488,7 @@ CURLcode Curl_pollfds_add_ps(struct curl_pollfds *cpfds,
return CURLE_OK; return CURLE_OK;
} }
void Curl_waitfds_init(struct curl_waitfds *cwfds, void Curl_waitfds_init(struct Curl_waitfds *cwfds,
struct curl_waitfd *static_wfds, struct curl_waitfd *static_wfds,
unsigned int static_count) unsigned int static_count)
{ {
@ -499,7 +499,7 @@ void Curl_waitfds_init(struct curl_waitfds *cwfds,
cwfds->count = static_count; cwfds->count = static_count;
} }
static unsigned int cwfds_add_sock(struct curl_waitfds *cwfds, static unsigned int cwfds_add_sock(struct Curl_waitfds *cwfds,
curl_socket_t sock, short events) curl_socket_t sock, short events)
{ {
int i; int i;
@ -524,7 +524,7 @@ static unsigned int cwfds_add_sock(struct curl_waitfds *cwfds,
return 1; return 1;
} }
unsigned int Curl_waitfds_add_ps(struct curl_waitfds *cwfds, unsigned int Curl_waitfds_add_ps(struct Curl_waitfds *cwfds,
struct easy_pollset *ps) struct easy_pollset *ps)
{ {
size_t i; size_t i;

View File

@ -130,17 +130,17 @@ CURLcode Curl_pollfds_add_ps(struct curl_pollfds *cpfds,
CURLcode Curl_pollfds_add_sock(struct curl_pollfds *cpfds, CURLcode Curl_pollfds_add_sock(struct curl_pollfds *cpfds,
curl_socket_t sock, short events); curl_socket_t sock, short events);
struct curl_waitfds { struct Curl_waitfds {
struct curl_waitfd *wfds; struct curl_waitfd *wfds;
unsigned int n; unsigned int n;
unsigned int count; unsigned int count;
}; };
void Curl_waitfds_init(struct curl_waitfds *cwfds, void Curl_waitfds_init(struct Curl_waitfds *cwfds,
struct curl_waitfd *static_wfds, struct curl_waitfd *static_wfds,
unsigned int static_count); unsigned int static_count);
unsigned int Curl_waitfds_add_ps(struct curl_waitfds *cwfds, unsigned int Curl_waitfds_add_ps(struct Curl_waitfds *cwfds,
struct easy_pollset *ps); struct easy_pollset *ps);
#endif /* HEADER_CURL_SELECT_H */ #endif /* HEADER_CURL_SELECT_H */