multi: make curl_multi_wait avoid malloc in the typical case

When only a few additional file descriptors are used, avoid the malloc.

Closes #1377
This commit is contained in:
Daniel Stenberg 2017-04-01 01:27:24 +02:00
parent 55f4ababde
commit 5f1163517e
1 changed files with 14 additions and 4 deletions

View File

@ -974,6 +974,8 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
return CURLM_OK; return CURLM_OK;
} }
#define NUM_POLLS_ON_STACK 10
CURLMcode curl_multi_wait(struct Curl_multi *multi, CURLMcode curl_multi_wait(struct Curl_multi *multi,
struct curl_waitfd extra_fds[], struct curl_waitfd extra_fds[],
unsigned int extra_nfds, unsigned int extra_nfds,
@ -987,8 +989,10 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
unsigned int nfds = 0; unsigned int nfds = 0;
unsigned int curlfds; unsigned int curlfds;
struct pollfd *ufds = NULL; struct pollfd *ufds = NULL;
bool ufds_malloc = FALSE;
long timeout_internal; long timeout_internal;
int retcode = 0; int retcode = 0;
struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
if(!GOOD_MULTI_HANDLE(multi)) if(!GOOD_MULTI_HANDLE(multi))
return CURLM_BAD_HANDLE; return CURLM_BAD_HANDLE;
@ -1028,9 +1032,14 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
nfds += extra_nfds; /* add the externally provided ones */ nfds += extra_nfds; /* add the externally provided ones */
if(nfds || extra_nfds) { if(nfds || extra_nfds) {
ufds = malloc(nfds * sizeof(struct pollfd)); if(nfds > NUM_POLLS_ON_STACK) {
if(!ufds) ufds = malloc(nfds * sizeof(struct pollfd));
return CURLM_OUT_OF_MEMORY; if(!ufds)
return CURLM_OUT_OF_MEMORY;
ufds_malloc = TRUE;
}
else
ufds = &a_few_on_stack[0];
} }
nfds = 0; nfds = 0;
@ -1108,7 +1117,8 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
} }
} }
free(ufds); if(ufds_malloc)
free(ufds);
if(ret) if(ret)
*ret = retcode; *ret = retcode;
return CURLM_OK; return CURLM_OK;