summaryrefslogtreecommitdiff
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
parent2f6e1a8cc3f4573b29d48b7bd8177dbbc4c337fd (diff)
downloadcurl-de24d7bd4c03ea3eeba928edc9ae9e7a826c67c8.tar.gz
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);
-rw-r--r--include/curl/multi.h28
-rw-r--r--lib/multi.c87
2 files changed, 114 insertions, 1 deletions
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, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, 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)