the curl_multi_socket() test application (still using select())

This commit is contained in:
Daniel Stenberg 2005-12-22 14:14:14 +00:00
parent c7a634641f
commit b466ef2581
1 changed files with 104 additions and 36 deletions

View File

@ -35,10 +35,18 @@
#include <event.h> /* for libevent */ #include <event.h> /* for libevent */
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#define MICROSEC 1000000 /* number of microseconds in one second */ #define MICROSEC 1000000 /* number of microseconds in one second */
/* The maximum time (in microseconds) we run the test */ /* The maximum time (in microseconds) we run the test */
#define RUN_FOR_THIS_LONG (20*MICROSEC) #define RUN_FOR_THIS_LONG (5*MICROSEC)
/* Number of loops (seconds) we allow the total download amount and alive /* Number of loops (seconds) we allow the total download amount and alive
connections to remain the same until we bail out. Set this slightly higher connections to remain the same until we bail out. Set this slightly higher
@ -51,7 +59,7 @@ struct ourfdset {
FD_SET() macro usage but it would hardly be portable */ FD_SET() macro usage but it would hardly be portable */
char __fds_bits[NCONNECTIONS/8]; char __fds_bits[NCONNECTIONS/8];
}; };
#define FD2_ZERO(x) FD_ZERO((fd_set *)x) #define FD2_ZERO(x) memset(x, 0, sizeof(struct ourfdset))
typedef struct ourfdset fd2_set; typedef struct ourfdset fd2_set;
@ -115,15 +123,20 @@ static void remsock(curl_socket_t s)
allsocks = NULL; allsocks = NULL;
} }
static void setsock(struct fdinfo *fdp, curl_socket_t s, CURL *easy,
int action, long timeout)
{
fdp->sockfd = s;
fdp->action = action;
fdp->timeout = timeout;
fdp->easy = easy;
}
static void addsock(curl_socket_t s, CURL *easy, int action, long timeout) static void addsock(curl_socket_t s, CURL *easy, int action, long timeout)
{ {
struct fdinfo *fdp = calloc(sizeof(struct fdinfo), 1); struct fdinfo *fdp = calloc(sizeof(struct fdinfo), 1);
fdp->sockfd = s; setsock(fdp, s, easy, action, timeout);
fdp->action = action;
fdp->timeout = timeout;
fdp->easy = easy;
if(allsocks) { if(allsocks) {
fdp->next = allsocks; fdp->next = allsocks;
@ -139,17 +152,42 @@ static void addsock(curl_socket_t s, CURL *easy, int action, long timeout)
static void fdinfo2fdset(fd2_set *fdread, fd2_set *fdwrite, int *maxfd) static void fdinfo2fdset(fd2_set *fdread, fd2_set *fdwrite, int *maxfd)
{ {
struct fdinfo *fdp = allsocks; struct fdinfo *fdp = allsocks;
int writable=0;
FD2_ZERO(fdread);
FD2_ZERO(fdwrite);
*maxfd = 0;
#if 0
printf("Wait for: ");
#endif
while(fdp) { while(fdp) {
if(fdp->action & CURL_POLL_IN) if(fdp->action & CURL_POLL_IN) {
FD_SET(fdp->sockfd, (fd_set *)fdread); FD_SET(fdp->sockfd, (fd_set *)fdread);
if(fdp->action & CURL_POLL_OUT) }
if(fdp->action & CURL_POLL_OUT) {
FD_SET(fdp->sockfd, (fd_set *)fdwrite); FD_SET(fdp->sockfd, (fd_set *)fdwrite);
writable++;
}
#if 0
printf("%d (%s%s) ",
fdp->sockfd,
(fdp->action & CURL_POLL_IN)?"r":"",
(fdp->action & CURL_POLL_OUT)?"w":"");
#endif
if(fdp->sockfd > *maxfd) if(fdp->sockfd > *maxfd)
*maxfd = fdp->sockfd; *maxfd = fdp->sockfd;
fdp = fdp->next; fdp = fdp->next;
} }
#if 0
if(writable)
printf("Check for %d writable sockets\n", writable);
#endif
} }
/* on port 8999 we run a modified (fork-) sws that supports pure idle and full /* on port 8999 we run a modified (fork-) sws that supports pure idle and full
@ -168,13 +206,24 @@ static int socket_callback(CURL *easy, /* easy handle */
long ms, /* timeout for wait */ long ms, /* timeout for wait */
void *userp) /* "private" pointer */ void *userp) /* "private" pointer */
{ {
struct fdinfo *fdp;
printf("socket %d easy %p what %d timeout %ld\n", s, easy, what, ms); printf("socket %d easy %p what %d timeout %ld\n", s, easy, what, ms);
if(what == CURL_POLL_REMOVE) if(what == CURL_POLL_REMOVE)
remsock(s); remsock(s);
else if(!findsock(s)) else {
addsock(s, easy, what, ms); fdp = findsock(s);
if(!fdp) {
addsock(s, easy, what, ms);
}
else {
/* we already know about it, just change action/timeout */
printf("Changing info for socket %d from %d to %d\n",
s, fdp->action, what);
setsock(fdp, s, easy, what, ms);
}
}
return 0; /* return code meaning? */ return 0; /* return code meaning? */
} }
@ -265,9 +314,9 @@ struct globalinfo info;
struct connection *conns; struct connection *conns;
long selects; long selects;
long selectsalive;
long timeouts; long timeouts;
long multi_socket;
long performalive; long performalive;
long performselect; long performselect;
long topselect; long topselect;
@ -291,19 +340,23 @@ static void report(void)
num_total, num_active); num_total, num_active);
printf("%d out of %d connections provided data\n", numdl, num_total); printf("%d out of %d connections provided data\n", numdl, num_total);
printf("Total time: %ldus select(): %ldus curl_multi_perform(): %ldus\n", printf("Total time: %ldus paused: %ldus curl_multi_socket(): %ldus\n",
total, paused, active); total, paused, active);
printf("%d calls to select(), average %d alive " printf("%d calls to select() "
"Average time: %dus\n", "Average time: %dus\n",
selects, selectsalive/selects, selects, paused/selects);
paused/selects);
printf(" Average number of readable connections per select() return: %d\n", printf(" Average number of readable connections per select() return: %d\n",
performselect/selects); performselect/selects);
printf(" Max number of readable connections for a single select() " printf(" Max number of readable connections for a single select() "
"return: %d\n", "return: %d\n",
topselect); topselect);
printf("%ld calls to multi_socket(), "
"Average time: %ldus\n",
multi_socket, active/multi_socket);
printf("%ld select() timeouts\n", timeouts); printf("%ld select() timeouts\n", timeouts);
printf("Downloaded %ld bytes in %ld bytes/sec, %ld usec/byte\n", printf("Downloaded %ld bytes in %ld bytes/sec, %ld usec/byte\n",
@ -321,12 +374,10 @@ int main(int argc, char **argv)
CURLMcode mcode = CURLM_OK; CURLMcode mcode = CURLM_OK;
int rc; int rc;
int i; int i;
int prevalive=-1;
int prevsamecounter=0;
int prevtotal = -1;
fd2_set fdsizecheck; fd2_set fdsizecheck;
int selectmaxamount; int selectmaxamount;
struct fdinfo *fdp;
char act;
memset(&info, 0, sizeof(struct globalinfo)); memset(&info, 0, sizeof(struct globalinfo));
@ -408,6 +459,7 @@ int main(int argc, char **argv)
printf("Starting timer, expects to run for %ldus\n", RUN_FOR_THIS_LONG); printf("Starting timer, expects to run for %ldus\n", RUN_FOR_THIS_LONG);
timer_start(); timer_start();
timer_pause();
while(1) { while(1) {
struct timeval timeout; struct timeval timeout;
@ -417,9 +469,6 @@ int main(int argc, char **argv)
fd2_set fdwrite; fd2_set fdwrite;
int maxfd; int maxfd;
FD2_ZERO(&fdread);
FD2_ZERO(&fdwrite);
/* set a suitable timeout to play around with */ /* set a suitable timeout to play around with */
timeout.tv_sec = 1; timeout.tv_sec = 1;
timeout.tv_usec = 0; timeout.tv_usec = 0;
@ -427,16 +476,11 @@ int main(int argc, char **argv)
/* convert file descriptors from the transfers to fd_sets */ /* convert file descriptors from the transfers to fd_sets */
fdinfo2fdset(&fdread, &fdwrite, &maxfd); fdinfo2fdset(&fdread, &fdwrite, &maxfd);
timer_pause();
selects++; selects++;
selectsalive += still_running;
rc = select(maxfd+1, rc = select(maxfd+1,
(fd_set *)&fdread, (fd_set *)&fdread,
(fd_set *)&fdwrite, (fd_set *)&fdwrite,
NULL, &timeout); NULL, &timeout);
timer_continue();
switch(rc) { switch(rc) {
case -1: case -1:
/* select error */ /* select error */
@ -445,11 +489,40 @@ int main(int argc, char **argv)
timeouts++; timeouts++;
default: default:
/* timeout or readable/writable sockets */ /* timeout or readable/writable sockets */
for(i=0, fdp = allsocks; fdp; fdp = fdp->next) {
act = 0;
if((fdp->action & CURL_POLL_IN) &&
FD_ISSET(fdp->sockfd, &fdread)) {
act |= CURL_POLL_IN;
i++;
}
if((fdp->action & CURL_POLL_OUT) &&
FD_ISSET(fdp->sockfd, &fdwrite)) {
act |= CURL_POLL_OUT;
i++;
}
if(act) {
multi_socket++;
#if 0 #if 0
curl_multi_socket(multi_handle, CURL_SOCKET_BAD, conns[0].e, printf("multi_socket for %p socket %d (%d)\n",
socket_callback, NULL); fdp, fdp->sockfd, act);
#endif #endif
timer_continue();
if(act & CURL_POLL_OUT)
act--;
curl_multi_socket(multi_handle,
CURL_SOCKET_BAD,
fdp->easy,
socket_callback, NULL);
timer_pause();
}
}
#if 0
curl_multi_socket_all(multi_handle, socket_callback, NULL); curl_multi_socket_all(multi_handle, socket_callback, NULL);
#endif
performselect += rc; performselect += rc;
if(rc > topselect) if(rc > topselect)
@ -457,17 +530,12 @@ int main(int argc, char **argv)
break; break;
} }
timer_total(); /* calculate the total time spent so far */
if(total > RUN_FOR_THIS_LONG) { if(total > RUN_FOR_THIS_LONG) {
printf("Stopped after %ldus\n", total); printf("Stopped after %ldus\n", total);
break; break;
} }
if(prevalive != still_running) {
printf("%d connections alive\n", still_running);
}
prevalive = still_running;
timer_total(); /* calculate the total time spent so far */
} }
if(still_running != num_total) { if(still_running != num_total) {