From efe3cb6e1ae672a48746c6000b1aedd2742deac7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 13 Oct 2006 07:11:26 +0000 Subject: Added curl_multi_dump() when built with CURLDEBUG - this is not a stable public function, this is only meant to allow easier tracking of the internal handle's state and what sockets they use. Only for research and development. --- lib/multi.c | 101 ++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 33 deletions(-) diff --git a/lib/multi.c b/lib/multi.c index 7272f471a..69f8699a0 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -85,11 +85,6 @@ typedef enum { #define GETSOCK_READABLE (0x00ff) #define GETSOCK_WRITABLE (0xff00) -struct socketstate { - curl_socket_t socks[MAX_SOCKSPEREASYHANDLE]; - unsigned int action; /* socket action bitmap */ -}; - struct closure { struct closure *next; /* a simple one-way list of structs */ struct SessionHandle *easy_handle; @@ -182,28 +177,33 @@ static void add_closure(struct Curl_multi *multi, struct SessionHandle *data); static int update_timer(struct Curl_multi *multi); +#ifdef CURLDEBUG +static const char *statename[]={ + "INIT", + "CONNECT", + "WAITRESOLVE", + "WAITCONNECT", + "PROTOCONNECT", + "WAITDO", + "DO", + "DOING", + "DO_MORE", + "DO_DONE", + "WAITPERFORM", + "PERFORM", + "TOOFAST", + "DONE", + "COMPLETED", + "CANCELLED" +}; + +void curl_multi_dump(CURLM *multi_handle); +#endif + /* always use this function to change state, to make debugging easier */ static void multistate(struct Curl_one_easy *easy, CURLMstate state) { #ifdef CURLDEBUG - const char *statename[]={ - "INIT", - "CONNECT", - "WAITRESOLVE", - "WAITCONNECT", - "PROTOCONNECT", - "WAITDO", - "DO", - "DOING", - "DO_MORE", - "DO_DONE", - "WAITPERFORM", - "PERFORM", - "TOOFAST", - "DONE", - "COMPLETED", - "CANCELLED" - }; long index = -1; #endif CURLMstate oldstate = easy->state; @@ -1473,19 +1473,20 @@ CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue) static void singlesocket(struct Curl_multi *multi, struct Curl_one_easy *easy) { - struct socketstate current; + curl_socket_t socks[MAX_SOCKSPEREASYHANDLE]; int i; struct Curl_sh_entry *entry; curl_socket_t s; int num; + unsigned int curraction; - memset(¤t, 0, sizeof(current)); + memset(&socks, 0, sizeof(socks)); for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) - current.socks[i] = CURL_SOCKET_BAD; + socks[i] = CURL_SOCKET_BAD; /* Fill in the 'current' struct with the state as it is now: what sockets to supervise and for what actions */ - current.action = multi_getsock(easy, current.socks, MAX_SOCKSPEREASYHANDLE); + curraction = multi_getsock(easy, socks, MAX_SOCKSPEREASYHANDLE); /* We have 0 .. N sockets already and we get to know about the 0 .. M sockets we should have from now on. Detect the differences, remove no @@ -1493,18 +1494,18 @@ static void singlesocket(struct Curl_multi *multi, /* walk over the sockets we got right now */ for(i=0; (i< MAX_SOCKSPEREASYHANDLE) && - (current.action & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))); + (curraction & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))); i++) { int action = CURL_POLL_NONE; - s = current.socks[i]; + s = socks[i]; /* get it from the hash */ entry = Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s)); - if(current.action & GETSOCK_READSOCK(i)) + if(curraction & GETSOCK_READSOCK(i)) action |= CURL_POLL_IN; - if(current.action & GETSOCK_WRITESOCK(i)) + if(curraction & GETSOCK_WRITESOCK(i)) action |= CURL_POLL_OUT; if(entry) { @@ -1538,7 +1539,7 @@ static void singlesocket(struct Curl_multi *multi, int j; s = easy->sockets[i]; for(j=0; jsockets, current.socks, num*sizeof(curl_socket_t)); + memcpy(easy->sockets, socks, num*sizeof(curl_socket_t)); easy->numsocks = num; } @@ -1946,3 +1947,37 @@ static void add_closure(struct Curl_multi *multi, } } + +#ifdef CURLDEBUG +void curl_multi_dump(CURLM *multi_handle) +{ + struct Curl_multi *multi=(struct Curl_multi *)multi_handle; + struct Curl_one_easy *easy; + int i; + fprintf(stderr, "* Multi status: %d handles, %d alive\n", + multi->num_easy, multi->num_alive); + for(easy=multi->easy.next; easy; easy = easy->next) { + if(easy->state != CURLM_STATE_COMPLETED) { + /* only display handles that are not completed */ + fprintf(stderr, "handle %p, state %s, %d sockets\n", + (void *)easy, statename[easy->state], easy->numsocks); + for(i=0; i < easy->numsocks; i++) { + curl_socket_t s = easy->sockets[i]; + struct Curl_sh_entry *entry = + Curl_hash_pick(multi->sockhash, (char *)&s, sizeof(s)); + + fprintf(stderr, "%d ", (int)s); + if(!entry) { + fprintf(stderr, "INTERNAL CONFUSION\n"); + continue; + } + fprintf(stderr, "[%s %s] ", + entry->action&CURL_POLL_IN?"RECVING":"", + entry->action&CURL_POLL_OUT?"SENDING":""); + } + if(easy->numsocks) + fprintf(stderr, "\n"); + } + } +} +#endif -- cgit v1.2.3