aboutsummaryrefslogtreecommitdiff
path: root/lib/multi.c
diff options
context:
space:
mode:
authorSara Golemon <sgolemon@fb.com>2012-08-27 12:48:55 -0700
committerDaniel Stenberg <daniel@haxx.se>2012-09-01 23:10:53 +0200
commitde24d7bd4c03ea3eeba928edc9ae9e7a826c67c8 (patch)
tree19f1663d427c4f75c7f201d5841ce1c24d6b005c /lib/multi.c
parent2f6e1a8cc3f4573b29d48b7bd8177dbbc4c337fd (diff)
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);
Diffstat (limited to 'lib/multi.c')
-rw-r--r--lib/multi.c87
1 files changed, 87 insertions, 0 deletions
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)