mirror of
https://github.com/curl/curl.git
synced 2026-07-28 02:53:07 +03:00
multi: fix curl_multi_waitfds reporting of fd_count
- Make curl_multi_waitfds consistent with the documentation. Issue Addressed: - The documentation of curl_multi_waitfds indicates that users should be able to call curl_multi_waitfds with a NULL ufds. However, before this change, the function would return CURLM_BAD_FUNCTION_ARGUMENT. - Additionally, the documentation suggests that users can use this function to determine the number of file descriptors (fds) needed. However, the function would stop counting fds if the supplied fds were exhausted. Changes Made: - NULL ufds Handling: curl_multi_waitfds can now accept a NULL ufds if size is also zero. - Counting File Descriptors: If curl_multi_waitfds is passed a NULL ufds, or the size of ufds is insufficient, the output parameter fd_count will return the number of fds needed. This value may be higher than actually needed but never lower. Testing: - Test 2405 has been updated to cover the usage scenarios described above. Fixes https://github.com/curl/curl/issues/15146 Closes https://github.com/curl/curl/pull/15155
This commit is contained in:
parent
7d6edf1d8d
commit
c78044c07e
7 changed files with 120 additions and 43 deletions
|
|
@ -926,10 +926,10 @@ CURLcode Curl_cpool_add_pollfds(struct cpool *cpool,
|
|||
return result;
|
||||
}
|
||||
|
||||
CURLcode Curl_cpool_add_waitfds(struct cpool *cpool,
|
||||
struct curl_waitfds *cwfds)
|
||||
unsigned int Curl_cpool_add_waitfds(struct cpool *cpool,
|
||||
struct curl_waitfds *cwfds)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
unsigned int need = 0;
|
||||
|
||||
CPOOL_LOCK(cpool);
|
||||
if(Curl_llist_head(&cpool->shutdowns)) {
|
||||
|
|
@ -945,14 +945,11 @@ CURLcode Curl_cpool_add_waitfds(struct cpool *cpool,
|
|||
Curl_conn_adjust_pollset(cpool->idata, &ps);
|
||||
Curl_detach_connection(cpool->idata);
|
||||
|
||||
result = Curl_waitfds_add_ps(cwfds, &ps);
|
||||
if(result)
|
||||
goto out;
|
||||
need += Curl_waitfds_add_ps(cwfds, &ps);
|
||||
}
|
||||
}
|
||||
out:
|
||||
CPOOL_UNLOCK(cpool);
|
||||
return result;
|
||||
return need;
|
||||
}
|
||||
|
||||
static void cpool_perform(struct cpool *cpool)
|
||||
|
|
|
|||
|
|
@ -183,8 +183,8 @@ void Curl_cpool_do_locked(struct Curl_easy *data,
|
|||
*/
|
||||
CURLcode Curl_cpool_add_pollfds(struct cpool *connc,
|
||||
struct curl_pollfds *cpfds);
|
||||
CURLcode Curl_cpool_add_waitfds(struct cpool *connc,
|
||||
struct curl_waitfds *cwfds);
|
||||
unsigned int Curl_cpool_add_waitfds(struct cpool *connc,
|
||||
struct curl_waitfds *cwfds);
|
||||
|
||||
/**
|
||||
* Perform maintenance on connections in the pool. Specifically,
|
||||
|
|
|
|||
16
lib/multi.c
16
lib/multi.c
|
|
@ -1200,8 +1200,9 @@ CURLMcode curl_multi_waitfds(CURLM *m,
|
|||
CURLMcode result = CURLM_OK;
|
||||
struct Curl_llist_node *e;
|
||||
struct Curl_multi *multi = m;
|
||||
unsigned int need = 0;
|
||||
|
||||
if(!ufds)
|
||||
if(!ufds && (size || !fd_count))
|
||||
return CURLM_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
|
|
@ -1214,20 +1215,17 @@ CURLMcode curl_multi_waitfds(CURLM *m,
|
|||
for(e = Curl_llist_head(&multi->process); e; e = Curl_node_next(e)) {
|
||||
struct Curl_easy *data = Curl_node_elem(e);
|
||||
multi_getsock(data, &data->last_poll);
|
||||
if(Curl_waitfds_add_ps(&cwfds, &data->last_poll)) {
|
||||
result = CURLM_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
need += Curl_waitfds_add_ps(&cwfds, &data->last_poll);
|
||||
}
|
||||
|
||||
if(Curl_cpool_add_waitfds(&multi->cpool, &cwfds)) {
|
||||
need += Curl_cpool_add_waitfds(&multi->cpool, &cwfds);
|
||||
|
||||
if(need != cwfds.n && ufds) {
|
||||
result = CURLM_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if(fd_count)
|
||||
*fd_count = cwfds.n;
|
||||
*fd_count = need;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
33
lib/select.c
33
lib/select.c
|
|
@ -493,14 +493,14 @@ void Curl_waitfds_init(struct curl_waitfds *cwfds,
|
|||
unsigned int static_count)
|
||||
{
|
||||
DEBUGASSERT(cwfds);
|
||||
DEBUGASSERT(static_wfds);
|
||||
DEBUGASSERT(static_wfds || !static_count);
|
||||
memset(cwfds, 0, sizeof(*cwfds));
|
||||
cwfds->wfds = static_wfds;
|
||||
cwfds->count = static_count;
|
||||
}
|
||||
|
||||
static CURLcode cwfds_add_sock(struct curl_waitfds *cwfds,
|
||||
curl_socket_t sock, short events)
|
||||
static unsigned int cwfds_add_sock(struct curl_waitfds *cwfds,
|
||||
curl_socket_t sock, short events)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -508,23 +508,24 @@ static CURLcode cwfds_add_sock(struct curl_waitfds *cwfds,
|
|||
for(i = (int)cwfds->n - 1; i >= 0; --i) {
|
||||
if(sock == cwfds->wfds[i].fd) {
|
||||
cwfds->wfds[i].events |= events;
|
||||
return CURLE_OK;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* not folded, add new entry */
|
||||
if(cwfds->n >= cwfds->count)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
cwfds->wfds[cwfds->n].fd = sock;
|
||||
cwfds->wfds[cwfds->n].events = events;
|
||||
++cwfds->n;
|
||||
return CURLE_OK;
|
||||
if(cwfds->n < cwfds->count) {
|
||||
cwfds->wfds[cwfds->n].fd = sock;
|
||||
cwfds->wfds[cwfds->n].events = events;
|
||||
++cwfds->n;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
CURLcode Curl_waitfds_add_ps(struct curl_waitfds *cwfds,
|
||||
struct easy_pollset *ps)
|
||||
unsigned int Curl_waitfds_add_ps(struct curl_waitfds *cwfds,
|
||||
struct easy_pollset *ps)
|
||||
{
|
||||
size_t i;
|
||||
unsigned int need = 0;
|
||||
|
||||
DEBUGASSERT(cwfds);
|
||||
DEBUGASSERT(ps);
|
||||
|
|
@ -534,10 +535,8 @@ CURLcode Curl_waitfds_add_ps(struct curl_waitfds *cwfds,
|
|||
events |= CURL_WAIT_POLLIN;
|
||||
if(ps->actions[i] & CURL_POLL_OUT)
|
||||
events |= CURL_WAIT_POLLOUT;
|
||||
if(events) {
|
||||
if(cwfds_add_sock(cwfds, ps->sockets[i], events))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
if(events)
|
||||
need += cwfds_add_sock(cwfds, ps->sockets[i], events);
|
||||
}
|
||||
return CURLE_OK;
|
||||
return need;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,8 +140,7 @@ void Curl_waitfds_init(struct curl_waitfds *cwfds,
|
|||
struct curl_waitfd *static_wfds,
|
||||
unsigned int static_count);
|
||||
|
||||
CURLcode Curl_waitfds_add_ps(struct curl_waitfds *cwfds,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
unsigned int Curl_waitfds_add_ps(struct curl_waitfds *cwfds,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
#endif /* HEADER_CURL_SELECT_H */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue