From de24d7bd4c03ea3eeba928edc9ae9e7a826c67c8 Mon Sep 17 00:00:00 2001 From: Sara Golemon Date: Mon, 27 Aug 2012 12:48:55 -0700 Subject: multi: add curl_multi_wait() /* * Name: curl_multi_wait() * * Desc: Poll on all fds within a CURLM set as well as any * additional fds passed to the function. * * Returns: CURLMcode type, general multi error code. */ CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle, struct curl_waitfd extra_fds[], unsigned int extra_nfds, int timeout_ms); --- include/curl/multi.h | 28 ++++++++++++++++- lib/multi.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/include/curl/multi.h b/include/curl/multi.h index f96566669..737f17ce2 100644 --- a/include/curl/multi.h +++ b/include/curl/multi.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -89,6 +89,19 @@ struct CURLMsg { }; typedef struct CURLMsg CURLMsg; +/* Based on poll(2) structure and values. + * We don't use pollfd and POLL* constants explicitly + * to cover platforms without poll(). */ +#define CURL_WAIT_POLLIN 0x0001 +#define CURL_WAIT_POLLPRI 0x0002 +#define CURL_WAIT_POLLOUT 0x0004 + +struct curl_waitfd { + curl_socket_t fd; + short events; + short revents; /* not supported yet */ +}; + /* * Name: curl_multi_init() * @@ -133,6 +146,19 @@ CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, fd_set *exc_fd_set, int *max_fd); +/* + * Name: curl_multi_wait() + * + * Desc: Poll on all fds within a CURLM set as well as any + * additional fds passed to the function. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms); + /* * Name: curl_multi_perform() * diff --git a/lib/multi.c b/lib/multi.c index d252351b7..4a1f601f6 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -941,6 +941,93 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle, return CURLM_OK; } +CURLMcode curl_multi_wait(CURLM *multi_handle, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms) +{ + struct Curl_multi *multi=(struct Curl_multi *)multi_handle; + struct Curl_one_easy *easy; + curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; + int bitmap; + unsigned int i; + unsigned int nfds = extra_nfds; + struct pollfd *ufds; + + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + + /* Count up how many fds we have from the multi handle */ + easy=multi->easy.next; + while(easy != &multi->easy) { + bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE); + + for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) { + curl_socket_t s = CURL_SOCKET_BAD; + + if(bitmap & GETSOCK_READSOCK(i)) { + ++nfds; + s = sockbunch[i]; + } + if(bitmap & GETSOCK_WRITESOCK(i)) { + ++nfds; + s = sockbunch[i]; + } + if(s == CURL_SOCKET_BAD) { + break; + } + } + + easy = easy->next; /* check next handle */ + } + + ufds = (struct pollfd *)malloc(nfds * sizeof(struct pollfd)); + nfds = 0; + + /* Add the curl handles to our pollfds first */ + easy=multi->easy.next; + while(easy != &multi->easy) { + bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE); + + for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) { + curl_socket_t s = CURL_SOCKET_BAD; + + if(bitmap & GETSOCK_READSOCK(i)) { + ufds[nfds].fd = sockbunch[i]; + ufds[nfds].events = POLLIN; + ++nfds; + s = sockbunch[i]; + } + if(bitmap & GETSOCK_WRITESOCK(i)) { + ufds[nfds].fd = sockbunch[i]; + ufds[nfds].events = POLLOUT; + ++nfds; + s = sockbunch[i]; + } + if(s == CURL_SOCKET_BAD) { + break; + } + } + + easy = easy->next; /* check next handle */ + } + + /* Add external file descriptions from poll-like struct curl_waitfd */ + for(i = 0; i < extra_nfds; i++) { + ufds[nfds].fd = extra_fds[i].fd; + ufds[nfds].events = (short) ( + ((extra_fds[i].events & CURL_WAIT_POLLIN) ? POLLIN : 0) | + ((extra_fds[i].events & CURL_WAIT_POLLPRI) ? POLLPRI : 0) | + ((extra_fds[i].events & CURL_WAIT_POLLOUT) ? POLLOUT : 0) ); + ++nfds; + } + + /* wait... */ + Curl_poll(ufds, nfds, timeout_ms); + free(ufds); + return CURLM_OK; +} + static CURLMcode multi_runsingle(struct Curl_multi *multi, struct timeval now, struct Curl_one_easy *easy) -- cgit v1.2.3