From 0810fcb7cb5d823026b87e2025ad0b443b47eb80 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sun, 16 Aug 2009 19:24:18 +0000 Subject: [PATCH] THTTPD integration git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2027 42af7a65-404d-4744-a932-0658087f49c3 --- netutils/thttpd/fdwatch.c | 75 ++++++++++++++++++++------------------- netutils/thttpd/fdwatch.h | 11 +++--- netutils/thttpd/thttpd.c | 46 +++++++++--------------- netutils/thttpd/timers.c | 37 +++++++++---------- 4 files changed, 79 insertions(+), 90 deletions(-) diff --git a/netutils/thttpd/fdwatch.c b/netutils/thttpd/fdwatch.c index 5e5d9d9a75..9f2003bc51 100644 --- a/netutils/thttpd/fdwatch.c +++ b/netutils/thttpd/fdwatch.c @@ -43,15 +43,8 @@ #include #include - -#if 0 -#include - -#include -#include -#include -#endif #include +#include #include "config.h" #include "fdwatch.h" @@ -82,6 +75,29 @@ static long nwatches = 0; * Private Functions ****************************************************************************/ +#ifdef CONFIG_THTTPD_FDWATCH_DEBUG +static void fdwatch_dump(const char *msg, FAR struct fdwatch_s *fw) +{ + int i; + + nvdbg("%s\n", msg); + nvdbg("nwatched: %d nfds: %d\n", fw->nwatched, fw->nfds); + for (i = 0; i < fw->nwatched; i++) + { + nvdbg("%2d. pollfds: {fd: %d events: %02x revents: %02x} client: %p\n", + i+1, fw->pollfds[i].fd, fw->pollfds[i].events, + fw->pollfds[i].revents, fw->client[i]); + } + nvdbg("nactive: %d next: %d\n", fw->nactive, fw->next); + for (i = 0; i < fw->nactive; i++) + { + nvdbg("%2d. %d active\n", i, fw->ready[i]); + } +} +#else +# define fdwatch_dump(m,f) +#endif + static int fdwatch_pollndx(FAR struct fdwatch_s *fw, int fd) { int pollndx; @@ -141,6 +157,8 @@ struct fdwatch_s *fdwatch_initialize(int nfds) { goto errout_with_allocations; } + + fdwatch_dump("Initial state:", fw); return fw; errout_with_allocations: @@ -154,6 +172,7 @@ void fdwatch_uninitialize(struct fdwatch_s *fw) { if (fw) { + fdwatch_dump("Uninitializing:", fw); if (fw->client) { free(fw->client); @@ -178,15 +197,7 @@ void fdwatch_uninitialize(struct fdwatch_s *fw) void fdwatch_add_fd(struct fdwatch_s *fw, int fd, void *client_data) { nvdbg("fd: %d client_data: %p\n", fd, client_data); - -#ifdef CONFIG_DEBUG - if (fd < CONFIG_NFILE_DESCRIPTORS || - fd >= CONFIG_NFILE_DESCRIPTORS+fw->nfds) - { - ndbg("Received bad fd (%d)\n", fd); - return; - } -#endif + fdwatch_dump("Before adding:", fw); if (fw->nwatched >= fw->nfds) { @@ -203,6 +214,7 @@ void fdwatch_add_fd(struct fdwatch_s *fw, int fd, void *client_data) /* Increment the count of watched descriptors */ fw->nwatched++; + fdwatch_dump("After adding:", fw); } /* Remove a descriptor from the watch list. */ @@ -212,15 +224,7 @@ void fdwatch_del_fd(struct fdwatch_s *fw, int fd) int pollndx; nvdbg("fd: %d\n", fd); - -#ifdef CONFIG_DEBUG - if (fd < CONFIG_NFILE_DESCRIPTORS || - fd >= CONFIG_NFILE_DESCRIPTORS+fw->nfds) - { - ndbg("Received bad fd: %d\n", fd); - return; - } -#endif + fdwatch_dump("Before deleting:", fw); /* Get the index associated with the fd */ @@ -241,6 +245,7 @@ void fdwatch_del_fd(struct fdwatch_s *fw, int fd) fw->client[pollndx] = fw->client[fw->nwatched]; } } + fdwatch_dump("After deleting:", fw); } /* Do the watch. Return value is the number of descriptors that are ready, @@ -262,10 +267,11 @@ int fdwatch(struct fdwatch_s *fw, long timeout_msecs) * or <0 on an error. */ - nvdbg("Waiting...\n"); + fdwatch_dump("Before waiting:", fw); + nvdbg("Waiting... (timeout %d)\n", timeout_msecs); fw->nactive = 0; fw->next = 0; - ret = poll(fw->pollfds, fw->nwatched, (int)timeout_msecs); + ret = poll(fw->pollfds, fw->nwatched, (int)timeout_msecs); nvdbg("Awakened: %d\n", ret); /* Look through all of the descriptors and make a list of all of them than @@ -296,6 +302,7 @@ int fdwatch(struct fdwatch_s *fw, long timeout_msecs) /* Return the number of descriptors with activity */ nvdbg("nactive: %d\n", fw->nactive); + fdwatch_dump("After wakeup:", fw); return ret; } @@ -306,15 +313,7 @@ int fdwatch_check_fd(struct fdwatch_s *fw, int fd) int pollndx; nvdbg("fd: %d\n", fd); - -#ifdef CONFIG_DEBUG - if (fd < CONFIG_NFILE_DESCRIPTORS || - fd >= CONFIG_NFILE_DESCRIPTORS + fw->nfds) - { - ndbg("Bad fd: %d\n", fd); - return 0; - } -#endif + fdwatch_dump("Checking:", fw); /* Get the index associated with the fd */ @@ -330,6 +329,7 @@ int fdwatch_check_fd(struct fdwatch_s *fw, int fd) void *fdwatch_get_next_client_data(struct fdwatch_s *fw) { + fdwatch_dump("Before getting client data:", fw); if (fw->next >= fw->nwatched) { nvdbg("All client data returned: %d\n", fw->next); @@ -345,6 +345,7 @@ void *fdwatch_get_next_client_data(struct fdwatch_s *fw) #if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET) void fdwatch_logstats(struct fdwatch_s *fw, long secs) { + fdwatch_dump("LOG stats:", fw); if (secs > 0) { ndbg("fdwatch - %ld polls (%g/sec)\n", nwatches, (float)nwatches / secs); diff --git a/netutils/thttpd/fdwatch.h b/netutils/thttpd/fdwatch.h index 4a87c32808..144badbdac 100644 --- a/netutils/thttpd/fdwatch.h +++ b/netutils/thttpd/fdwatch.h @@ -47,8 +47,9 @@ * Pre-Processor Definitions ****************************************************************************/ -#define FDW_READ 0 -#define FDW_WRITE 1 +/* Define to enable detailed FDWATCH debug output */ + +#undef CONFIG_THTTPD_FDWATCH_DEBUG #ifndef INFTIM # define INFTIM -1 @@ -60,9 +61,9 @@ struct fdwatch_s { - struct pollfd *pollfds; /* Poll data */ - void **client; /* Client data */ - uint8 *ready; /* The list of fds with activity */ + struct pollfd *pollfds; /* Poll data (allocated) */ + void **client; /* Client data (allocated) */ + uint8 *ready; /* The list of fds with activity (allocated) */ uint8 nfds; /* The configured maximum number of fds */ uint8 nwatched; /* The number of fds currently watched */ uint8 nactive; /* The number of fds with activity */ diff --git a/netutils/thttpd/thttpd.c b/netutils/thttpd/thttpd.c index cbdda8a99c..3608c94860 100644 --- a/netutils/thttpd/thttpd.c +++ b/netutils/thttpd/thttpd.c @@ -76,8 +76,7 @@ #define CNST_FREE 0 #define CNST_READING 1 #define CNST_SENDING 2 -#define CNST_PAUSING 3 -#define CNST_LINGERING 4 +#define CNST_LINGERING 3 #define SPARE_FDS 2 #define AVAILABLE_FDS (CONFIG_NSOCKET_DESCRIPTORS - SPARE_FDS) @@ -528,7 +527,7 @@ static void handle_linger(struct connect_s *conn, struct timeval *tv) char buf[4096]; int ret; - /* In lingering-close mode we just read and ignore bytes. An error or EOF + /* In lingering-close mode we just read and ignore bytes. An error or EOF * ends things, otherwise we go until a timeout */ @@ -582,39 +581,29 @@ static void clear_connection(struct connect_s *conn, struct timeval *tv) /* If we were already lingering, shut down for real */ tmr_cancel(conn->linger_timer); - conn->linger_timer = NULL; + conn->linger_timer = NULL; conn->hc->should_linger = FALSE; } if (conn->hc->should_linger) { - if (conn->conn_state != CNST_PAUSING) - { - fdwatch_del_fd(fw, conn->hc->conn_fd); - } - + fdwatch_del_fd(fw, conn->hc->conn_fd); conn->conn_state = CNST_LINGERING; - close(conn->hc->conn_fd); fdwatch_add_fd(fw, conn->hc->conn_fd, conn); client_data.p = conn; + conn->linger_timer = tmr_create(tv, linger_clear_connection, client_data, + CONFIG_THTTPD_LINGER_MSEC, 0); if (conn->linger_timer != NULL) { - ndbg("replacing non-null linger_timer!\n"); + return; } + ndbg("tmr_create(linger_clear_connection) failed\n"); + } - conn->linger_timer = - tmr_create(tv, linger_clear_connection, client_data, CONFIG_THTTPD_LINGER_MSEC, 0); - if (conn->linger_timer == NULL) - { - ndbg("tmr_create(linger_clear_connection) failed\n"); - exit(1); - } - } - else - { - really_clear_connection(conn, tv); - } + /* Either we are done lingering, we shouldn't linger, or we failed to setup the linger */ + + really_clear_connection(conn, tv); } static void really_clear_connection(struct connect_s *conn, struct timeval *tv) @@ -622,11 +611,8 @@ static void really_clear_connection(struct connect_s *conn, struct timeval *tv) #if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET) stats_bytes += conn->hc->bytes_sent; #endif - if (conn->conn_state != CNST_PAUSING) - { - fdwatch_del_fd(fw, conn->hc->conn_fd); - } + fdwatch_del_fd(fw, conn->hc->conn_fd); httpd_close_conn(conn->hc, tv); if (conn->linger_timer != NULL) { @@ -634,7 +620,7 @@ static void really_clear_connection(struct connect_s *conn, struct timeval *tv) conn->linger_timer = 0; } - conn->conn_state = CNST_FREE; + conn->conn_state = CNST_FREE; conn->next_free_connect = first_free_connect; first_free_connect = conn - connects; /* division by sizeof is implied */ num_connects--; @@ -661,7 +647,6 @@ static void idle(ClientData client_data, struct timeval *nowP) break; case CNST_SENDING: - case CNST_PAUSING: if (nowP->tv_sec - conn->active_at >= CONFIG_THTTPD_IDLE_SEND_LIMIT_SEC) { ndbg("%s connection timed out sending\n", httpd_ntoa(&conn->hc->client_addr)); @@ -676,6 +661,7 @@ static void linger_clear_connection(ClientData client_data, struct timeval *nowP { struct connect_s *conn; + nvdbg("Clear connection\n"); conn = (struct connect_s *) client_data.p; conn->linger_timer = NULL; really_clear_connection(conn, nowP); @@ -894,7 +880,7 @@ int thttpd_main(int argc, char **argv) continue; } - ndbg("fdwatch: %d\n", errno); + ndbg("fdwatch failed: %d\n", errno); exit(1); } diff --git a/netutils/thttpd/timers.c b/netutils/thttpd/timers.c index 9a768dedb2..b005da20b1 100644 --- a/netutils/thttpd/timers.c +++ b/netutils/thttpd/timers.c @@ -202,33 +202,33 @@ Timer *tmr_create(struct timeval *nowP, TimerProc * timer_proc, } else { - t = (Timer *) malloc(sizeof(Timer)); + t = (Timer*)malloc(sizeof(Timer)); if (!t) { return NULL; } - ++alloc_count; + alloc_count++; } - t->timer_proc = timer_proc; + t->timer_proc = timer_proc; t->client_data = client_data; - t->msecs = msecs; - t->periodic = periodic; + t->msecs = msecs; + t->periodic = periodic; - if (nowP != (struct timeval *)0) + if (nowP != NULL) { t->time = *nowP; } else { - (void)gettimeofday(&t->time, (struct timezone *)0); + (void)gettimeofday(&t->time, NULL); } - t->time.tv_sec += msecs / 1000L; + t->time.tv_sec += msecs / 1000L; t->time.tv_usec += (msecs % 1000L) * 1000L; if (t->time.tv_usec >= 1000000L) { - t->time.tv_sec += t->time.tv_usec / 1000000L; + t->time.tv_sec += t->time.tv_usec / 1000000L; t->time.tv_usec %= 1000000L; } t->hash = hash(t); @@ -248,7 +248,7 @@ long tmr_mstimeout(struct timeval *nowP) register Timer *t; gotone = 0; - msecs = 0; /* make lint happy */ + msecs = 0; /* Since the lists are sorted, we only need to look at the * first timer on * each one. @@ -272,6 +272,7 @@ long tmr_mstimeout(struct timeval *nowP) } } } + if (!gotone) { return INFTIM; @@ -306,7 +307,7 @@ void tmr_run(struct timeval *nowP) break; } - (t->timer_proc) (t->client_data, nowP); + (t->timer_proc)(t->client_data, nowP); if (t->periodic) { /* Reschedule. */ @@ -332,14 +333,14 @@ void tmr_cancel(Timer * t) /* Remove it from its active list. */ l_remove(t); - --active_count; + active_count--; /* And put it on the free list. */ - t->next = free_timers; + t->next = free_timers; free_timers = t; - ++free_count; - t->prev = NULL; + free_count++; + t->prev = NULL; } void tmr_cleanup(void) @@ -350,9 +351,9 @@ void tmr_cleanup(void) { t = free_timers; free_timers = t->next; - --free_count; - free((void *)t); - --alloc_count; + free_count--; + free((void*)t); + alloc_count--; } }