Fix crash when timeout is removed from its handler
Remove the timeout before dispatching the handler, and allow calling SCH_RemoveTimeout() with nonexistent id.
This commit is contained in:
parent
30c038c3c3
commit
1d6b94b458
1 changed files with 8 additions and 19 deletions
27
sched.c
27
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;
|
||||
|
|
Loading…
Reference in a new issue