From 3649aeec5fac74a369c269433ffb1c135f82d26c Mon Sep 17 00:00:00 2001 From: Sara Golemon Date: Sat, 14 Jul 2012 09:30:45 -0700 Subject: [PATCH 1/4] Add curl_multi_getinfo() method --- include/curl/multi.h | 24 ++++++++++++++++ lib/multi.c | 65 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/include/curl/multi.h b/include/curl/multi.h index f96566669c6771..066ae4017eb937 100644 --- a/include/curl/multi.h +++ b/include/curl/multi.h @@ -67,6 +67,21 @@ typedef enum { CURLM_LAST } CURLMcode; +#define CURLMINFO_STRING CURLINFO_STRING +#define CURLMINFO_LONG CURLINFO_LONG +#define CURLMINFO_DOUBLE CURLINFO_DOUBLE +#define CURLMINFO_SLIST CURLINFO_SLIST +#define CURLMINFO_MASK CURLINFO_MASK +#define CURLMINFO_TYPEMASK CURLINFO_TYPEMASK + +typedef enum { + CURLMINFO_NONE, + CURLMINFO_NUM_READ_FDS = CURLMINFO_LONG + 1, + CURLMINFO_NUM_WRITE_FDS = CURLMINFO_LONG + 2, + CURLMINFO_NUM_EX_FDS = CURLMINFO_LONG + 3, + CURLMINFO_NUM_FDS = CURLMINFO_LONG + 4 +} CURLMINFO; + /* just to make code nicer when using curl_multi_socket() you can now check for CURLM_CALL_MULTI_SOCKET too in the same style it works for curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ @@ -325,6 +340,15 @@ typedef enum { CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, CURLMoption option, ...); +/* + * Name: curl_multi_getinfo() + * + * Desc: Retreives info from a multi handle. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_getinfo(CURLM *multi_handle, + CURLMINFO info, ...); /* * Name: curl_multi_assign() diff --git a/lib/multi.c b/lib/multi.c index f4e15c4138bcbd..8cef06f004314b 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -2259,6 +2259,71 @@ CURLMcode curl_multi_setopt(CURLM *multi_handle, return res; } +static unsigned long curl_multi_count_fds(struct Curl_multi *multi, + char readH, char writeH, char exH) +{ + struct Curl_one_easy *easy; + int nfds = 0; + (void)exH; /* not used */ + + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + + for(easy = multi->easy.next; + easy != &multi->easy; + easy = easy->next) { + curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; + int i, bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE); + + for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) { + if ((readH && (bitmap & GETSOCK_READSOCK(i))) || + (writeH && (bitmap & GETSOCK_WRITESOCK(i)))) { + nfds++; + } + } + } + + return nfds; +} + +#undef curl_multi_getinfo +CURLMcode curl_multi_getinfo(CURLM *multi_handle, + CURLMINFO info, ...) +{ + struct Curl_multi *multi=(struct Curl_multi *)multi_handle; + CURLMcode res = CURLM_OK; + va_list param; + void *voidp; + long *longp; + + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + + va_start(param, info); + voidp = va_arg(param, void *); + longp = (long*)voidp; + + switch(info) { + case CURLMINFO_NUM_READ_FDS: + *longp = curl_multi_count_fds(multi, 1, 0, 0); + break; + case CURLMINFO_NUM_WRITE_FDS: + *longp = curl_multi_count_fds(multi, 0, 1, 0); + break; + case CURLMINFO_NUM_EX_FDS: + *longp = curl_multi_count_fds(multi, 0, 0, 1); + break; + case CURLMINFO_NUM_FDS: + *longp = curl_multi_count_fds(multi, 1, 1, 1); + break; + default: + res = CURLM_UNKNOWN_OPTION; + } + + va_end(param); + return res; +} + /* we define curl_multi_socket() in the public multi.h header */ #undef curl_multi_socket From 0ea58d1b5d95bb0e67f46eabb0be0f5a65c7f0b0 Mon Sep 17 00:00:00 2001 From: Sara Golemon Date: Sat, 14 Jul 2012 09:42:41 -0700 Subject: [PATCH 2/4] Add curl_multi_fdvec() method --- include/curl/multi.h | 12 ++++++++++++ lib/multi.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/include/curl/multi.h b/include/curl/multi.h index 066ae4017eb937..26bbeac8fdc388 100644 --- a/include/curl/multi.h +++ b/include/curl/multi.h @@ -148,6 +148,18 @@ CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, fd_set *exc_fd_set, int *max_fd); +/* + * Name: curl_multi_fdvec() + * + * Desc: Retreive a vector of fds contained in the multi handle + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_fdvec(CURLM *multi_handle, + int *read_fds, + int *write_fds, + int *ex_fds); + /* * Name: curl_multi_perform() * diff --git a/lib/multi.c b/lib/multi.c index 8cef06f004314b..99533bd7e3b924 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -941,6 +941,38 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle, return CURLM_OK; } +CURLMcode curl_multi_fdvec(CURLM *multi_handle, + int *read_fds, + int *write_fds, + int *ex_fds) +{ + struct Curl_multi *multi=(struct Curl_multi *)multi_handle; + struct Curl_one_easy *easy; + int rfds = 0, wfds = 0, xfds = 0; + (void)ex_fds; /* not used */ + + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + + for(easy = multi->easy.next; + easy != &multi->easy; + easy = easy->next) { + curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; + int i, bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE); + + for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) { + if (read_fds && (bitmap & GETSOCK_READSOCK(i))) { + read_fds[rfds++] = sockbunch[i]; + } + if (write_fds && (bitmap & GETSOCK_WRITESOCK(i))) { + write_fds[wfds++] = sockbunch[i]; + } + } + } + + return CURLM_OK; +} + static CURLMcode multi_runsingle(struct Curl_multi *multi, struct timeval now, struct Curl_one_easy *easy) From 8552252ba1a2fd0a6312540d61656e42137cfa70 Mon Sep 17 00:00:00 2001 From: Sara Golemon Date: Sat, 14 Jul 2012 09:30:45 -0700 Subject: [PATCH 3/4] Add curl_multi_getinfo() method --- include/curl/multi.h | 24 ++++++++++++++++ lib/multi.c | 65 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/include/curl/multi.h b/include/curl/multi.h index f96566669c6771..066ae4017eb937 100644 --- a/include/curl/multi.h +++ b/include/curl/multi.h @@ -67,6 +67,21 @@ typedef enum { CURLM_LAST } CURLMcode; +#define CURLMINFO_STRING CURLINFO_STRING +#define CURLMINFO_LONG CURLINFO_LONG +#define CURLMINFO_DOUBLE CURLINFO_DOUBLE +#define CURLMINFO_SLIST CURLINFO_SLIST +#define CURLMINFO_MASK CURLINFO_MASK +#define CURLMINFO_TYPEMASK CURLINFO_TYPEMASK + +typedef enum { + CURLMINFO_NONE, + CURLMINFO_NUM_READ_FDS = CURLMINFO_LONG + 1, + CURLMINFO_NUM_WRITE_FDS = CURLMINFO_LONG + 2, + CURLMINFO_NUM_EX_FDS = CURLMINFO_LONG + 3, + CURLMINFO_NUM_FDS = CURLMINFO_LONG + 4 +} CURLMINFO; + /* just to make code nicer when using curl_multi_socket() you can now check for CURLM_CALL_MULTI_SOCKET too in the same style it works for curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ @@ -325,6 +340,15 @@ typedef enum { CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, CURLMoption option, ...); +/* + * Name: curl_multi_getinfo() + * + * Desc: Retreives info from a multi handle. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_getinfo(CURLM *multi_handle, + CURLMINFO info, ...); /* * Name: curl_multi_assign() diff --git a/lib/multi.c b/lib/multi.c index ff43378f561dfa..577adb3e8d235d 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -2269,6 +2269,71 @@ CURLMcode curl_multi_setopt(CURLM *multi_handle, return res; } +static unsigned long curl_multi_count_fds(struct Curl_multi *multi, + char readH, char writeH, char exH) +{ + struct Curl_one_easy *easy; + int nfds = 0; + (void)exH; /* not used */ + + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + + for(easy = multi->easy.next; + easy != &multi->easy; + easy = easy->next) { + curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; + int i, bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE); + + for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) { + if ((readH && (bitmap & GETSOCK_READSOCK(i))) || + (writeH && (bitmap & GETSOCK_WRITESOCK(i)))) { + nfds++; + } + } + } + + return nfds; +} + +#undef curl_multi_getinfo +CURLMcode curl_multi_getinfo(CURLM *multi_handle, + CURLMINFO info, ...) +{ + struct Curl_multi *multi=(struct Curl_multi *)multi_handle; + CURLMcode res = CURLM_OK; + va_list param; + void *voidp; + long *longp; + + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + + va_start(param, info); + voidp = va_arg(param, void *); + longp = (long*)voidp; + + switch(info) { + case CURLMINFO_NUM_READ_FDS: + *longp = curl_multi_count_fds(multi, 1, 0, 0); + break; + case CURLMINFO_NUM_WRITE_FDS: + *longp = curl_multi_count_fds(multi, 0, 1, 0); + break; + case CURLMINFO_NUM_EX_FDS: + *longp = curl_multi_count_fds(multi, 0, 0, 1); + break; + case CURLMINFO_NUM_FDS: + *longp = curl_multi_count_fds(multi, 1, 1, 1); + break; + default: + res = CURLM_UNKNOWN_OPTION; + } + + va_end(param); + return res; +} + /* we define curl_multi_socket() in the public multi.h header */ #undef curl_multi_socket From 04ce9423f9c43384f43ae88e88991db34f084bcd Mon Sep 17 00:00:00 2001 From: Sara Golemon Date: Sat, 14 Jul 2012 09:42:41 -0700 Subject: [PATCH 4/4] Add curl_multi_fdvec() method --- include/curl/multi.h | 12 ++++++++++++ lib/multi.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/include/curl/multi.h b/include/curl/multi.h index 066ae4017eb937..26bbeac8fdc388 100644 --- a/include/curl/multi.h +++ b/include/curl/multi.h @@ -148,6 +148,18 @@ CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, fd_set *exc_fd_set, int *max_fd); +/* + * Name: curl_multi_fdvec() + * + * Desc: Retreive a vector of fds contained in the multi handle + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_fdvec(CURLM *multi_handle, + int *read_fds, + int *write_fds, + int *ex_fds); + /* * Name: curl_multi_perform() * diff --git a/lib/multi.c b/lib/multi.c index 577adb3e8d235d..7bb71a8ccbf57f 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -941,6 +941,38 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle, return CURLM_OK; } +CURLMcode curl_multi_fdvec(CURLM *multi_handle, + int *read_fds, + int *write_fds, + int *ex_fds) +{ + struct Curl_multi *multi=(struct Curl_multi *)multi_handle; + struct Curl_one_easy *easy; + int rfds = 0, wfds = 0, xfds = 0; + (void)ex_fds; /* not used */ + + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + + for(easy = multi->easy.next; + easy != &multi->easy; + easy = easy->next) { + curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; + int i, bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE); + + for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) { + if (read_fds && (bitmap & GETSOCK_READSOCK(i))) { + read_fds[rfds++] = sockbunch[i]; + } + if (write_fds && (bitmap & GETSOCK_WRITESOCK(i))) { + write_fds[wfds++] = sockbunch[i]; + } + } + } + + return CURLM_OK; +} + static CURLMcode multi_runsingle(struct Curl_multi *multi, struct timeval now, struct Curl_one_easy *easy)