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 information about the shutdown connections */
unsigned int Curl_cpool_add_waitfds(struct cpool *cpool,
struct curl_waitfds *cwfds)
struct Curl_waitfds *cwfds)
{
unsigned int need = 0;
@ -979,6 +980,46 @@ unsigned int Curl_cpool_add_waitfds(struct cpool *cpool,
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)
{
struct Curl_easy *data = cpool->idata;

View File

@ -31,7 +31,7 @@
struct connectdata;
struct Curl_easy;
struct curl_pollfds;
struct curl_waitfds;
struct Curl_waitfds;
struct Curl_multi;
struct Curl_share;
@ -184,7 +184,11 @@ void Curl_cpool_do_locked(struct Curl_easy *data,
CURLcode Curl_cpool_add_pollfds(struct cpool *connc,
struct curl_pollfds *cpfds);
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,

View File

@ -1168,6 +1168,7 @@ CURLMcode curl_multi_fdset(CURLM *m,
int this_max_fd = -1;
struct Curl_llist_node *e;
struct Curl_multi *multi = m;
unsigned int i;
(void)exc_fd_set; /* not used */
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)) {
struct Curl_easy *data = Curl_node_elem(e);
unsigned int i;
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;
return CURLM_OK;
@ -1212,7 +1214,7 @@ CURLMcode curl_multi_waitfds(CURLM *m,
unsigned int size,
unsigned int *fd_count)
{
struct curl_waitfds cwfds;
struct Curl_waitfds cwfds;
CURLMcode result = CURLM_OK;
struct Curl_llist_node *e;
struct Curl_multi *multi = m;

View File

@ -488,7 +488,7 @@ CURLcode Curl_pollfds_add_ps(struct curl_pollfds *cpfds,
return CURLE_OK;
}
void Curl_waitfds_init(struct curl_waitfds *cwfds,
void Curl_waitfds_init(struct Curl_waitfds *cwfds,
struct curl_waitfd *static_wfds,
unsigned int static_count)
{
@ -499,7 +499,7 @@ void Curl_waitfds_init(struct curl_waitfds *cwfds,
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)
{
int i;
@ -524,7 +524,7 @@ static unsigned int cwfds_add_sock(struct curl_waitfds *cwfds,
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)
{
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,
curl_socket_t sock, short events);
struct curl_waitfds {
struct Curl_waitfds {
struct curl_waitfd *wfds;
unsigned int n;
unsigned int count;
};
void Curl_waitfds_init(struct curl_waitfds *cwfds,
void Curl_waitfds_init(struct Curl_waitfds *cwfds,
struct curl_waitfd *static_wfds,
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);
#endif /* HEADER_CURL_SELECT_H */