Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

curl_multi_fdvec #38

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 36 additions & 0 deletions include/curl/multi.h
Expand Up @@ -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 */
Expand Down Expand Up @@ -133,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()
*
Expand Down Expand Up @@ -325,6 +352,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()
Expand Down
97 changes: 97 additions & 0 deletions lib/multi.c
Expand Up @@ -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)
Expand Down Expand Up @@ -2269,6 +2301,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

Expand Down