From: Miroslav Lichvar Date: Fri, 17 Dec 2010 13:52:39 +0000 (+0100) Subject: Fix crash when timeout is removed from its handler X-Git-Tag: 1.25-pre1~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1d6b94b458f688010f8bef298a857fde10485101;p=thirdparty%2Fchrony.git Fix crash when timeout is removed from its handler Remove the timeout before dispatching the handler, and allow calling SCH_RemoveTimeout() with nonexistent id. --- diff --git a/sched.c b/sched.c index cd6cf78b..47fc9425 100644 --- a/sched.c +++ b/sched.c @@ -395,12 +395,9 @@ void SCH_RemoveTimeout(SCH_TimeoutID id) { TimerQueueEntry *ptr; - int ok; assert(initialised); - ok = 0; - for (ptr = timer_queue.next; ptr != &timer_queue; ptr = ptr->next) { if (ptr->id == id) { @@ -416,14 +413,9 @@ SCH_RemoveTimeout(SCH_TimeoutID id) /* Release memory back to the operating system */ release_tqe(ptr); - ok = 1; - break; } } - - assert(ok); - } /* ================================================== */ @@ -433,27 +425,24 @@ SCH_RemoveTimeout(SCH_TimeoutID id) static int dispatch_timeouts(struct timeval *now) { TimerQueueEntry *ptr; + SCH_TimeoutHandler handler; + SCH_ArbitraryArgument arg; int n_done = 0; if ((n_timer_queue_entries > 0) && (UTI_CompareTimevals(now, &(timer_queue.next->tv)) >= 0)) { ptr = timer_queue.next; + handler = ptr->handler; + arg = ptr->arg; + + SCH_RemoveTimeout(ptr->id); + /* Dispatch the handler */ - (ptr->handler)(ptr->arg); + (handler)(arg); /* Increment count of timeouts handled */ ++n_done; - - /* Unlink entry from the queue */ - ptr->prev->next = ptr->next; - ptr->next->prev = ptr->prev; - - /* Decrement count of entries in queue */ - --n_timer_queue_entries; - - /* Delete entry */ - release_tqe(ptr); } return n_done;