From 3add3c0e19b659427a2624ec85daf67019b8ed7f Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Mon, 9 Jun 2008 15:44:02 +0000 Subject: Lots of bug fixes, changes. --- common/server-mainloop.c | 77 ++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 38 deletions(-) (limited to 'common') diff --git a/common/server-mainloop.c b/common/server-mainloop.c index fcd471d..1ba5085 100644 --- a/common/server-mainloop.c +++ b/common/server-mainloop.c @@ -45,6 +45,7 @@ typedef struct _socket_callback { int fd; server_socket_callback callback; void *arg; + int closed; struct _socket_callback *next; } socket_callback; @@ -54,6 +55,7 @@ typedef struct _timer_callback { struct timeval interval; server_timer_callback callback; void* arg; + int closed; struct _timer_callback *next; } timer_callback; @@ -166,35 +168,33 @@ add_timer (int ms, int oneshot, server_timer_callback callback, void *arg) return 0; } -static timer_callback* -remove_timer(timer_callback *timcb) +static void +remove_closed (void) { - timer_callback *cb; - timer_callback *next; - - if (!ctx.timers) - return NULL; - - /* First in list */; - if (ctx.timers == timcb) { - cb = ctx.timers; - ctx.timers = ctx.timers->next; - free (cb); - return ctx.timers; + timer_callback **tcb, *timcb; + socket_callback **scb, *sockcb; + + for (tcb = &ctx.timers; *tcb; ) { + timcb = *tcb; + if (timcb->closed) { + *tcb = timcb->next; + free (timcb); + continue; + } else { + tcb = &timcb->next; + } } - /* One ahead processing of rest */ - for (cb = ctx.timers; cb->next; cb = cb->next) { - if(cb->next == timcb) { - next = cb->next->next; - free (cb->next); - cb->next = next; - return cb->next; + for (scb = &ctx.callbacks; *scb; ) { + sockcb = *scb; + if (sockcb->closed) { + *scb = sockcb->next; + free (sockcb); + continue; + } else { + scb = &sockcb->next; } } - - /* Couldn't remove, return self */ - return timcb; } void @@ -248,7 +248,7 @@ server_run (void) struct timeval *timeout; struct timeval tv, current; timer_callback *timcb; - socket_callback *sockcb, *socknx; + socket_callback *sockcb; fd_set rfds, wfds; int r; @@ -268,9 +268,12 @@ server_run (void) return -1; /* Cycle through timers */ - for (timcb = ctx.timers; timcb; ) { + for (timcb = ctx.timers; timcb; timcb = timcb->next) { assert (timcb->callback); + if (timcb->closed) + continue; + /* Call any timers that have already passed */ if (timeval_compare (¤t, &timcb->at) >= 0) { @@ -287,7 +290,7 @@ server_run (void) /* Otherwise remove it. Either one shot, or returned 0 */ } else { - timcb = remove_timer (timcb); + timcb->closed = 1; continue; } } @@ -295,8 +298,6 @@ server_run (void) /* Get soonest timer */ if (!timeout || timeval_compare (&timcb->at, timeout) < 0) timeout = &timcb->at; - - timcb = timcb->next; } /* Convert to an offset */ @@ -309,6 +310,10 @@ server_run (void) if (ctx.stopped) continue; + remove_closed (); + if (!ctx.callbacks && !ctx.timers) + break; + /* fprintf(stderr, "selecting with timeout: "); timeval_dump(timeout); fprintf(stderr, "\n"); */ @@ -329,17 +334,16 @@ server_run (void) if(r == 0) continue; - for (sockcb = ctx.callbacks; sockcb; ) { + for (sockcb = ctx.callbacks; sockcb; sockcb = sockcb->next) { assert (sockcb->fd != -1); - socknx = sockcb->next; + if (sockcb->closed) + continue; /* Call any that are set */ if (FD_ISSET (sockcb->fd, &rfds)) (sockcb->callback) (sockcb->fd, SERVER_READ, sockcb->arg); if (FD_ISSET (sockcb->fd, &wfds)) (sockcb->callback) (sockcb->fd, SERVER_WRITE, sockcb->arg); - - sockcb = socknx; } } @@ -405,17 +409,14 @@ server_unwatch (int fd) /* First in list */; if (ctx.callbacks->fd == fd) { - cb = ctx.callbacks; - ctx.callbacks = cb->next; - free (cb); + ctx.callbacks->closed = 1; return; } /* One ahead processing of rest */ for (cb = ctx.callbacks; cb->next; cb = cb->next) { if (cb->next->fd == fd) { - cb->next = cb->next->next; - free (cb->next); + cb->next->closed = 1; return; } } -- cgit v1.2.3