mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
the curl_multi_socket() test application (still using select())
This commit is contained in:
parent
c7a634641f
commit
b466ef2581
140
hiper/shiper.c
140
hiper/shiper.c
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user