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)
|
SCH_RemoveTimeout(SCH_TimeoutID id)
|
||||||
{
|
{
|
||||||
TimerQueueEntry *ptr;
|
TimerQueueEntry *ptr;
|
||||||
int ok;
|
|
||||||
|
|
||||||
assert(initialised);
|
assert(initialised);
|
||||||
|
|
||||||
ok = 0;
|
|
||||||
|
|
||||||
for (ptr = timer_queue.next; ptr != &timer_queue; ptr = ptr->next) {
|
for (ptr = timer_queue.next; ptr != &timer_queue; ptr = ptr->next) {
|
||||||
|
|
||||||
if (ptr->id == id) {
|
if (ptr->id == id) {
|
||||||
|
@ -416,14 +413,9 @@ SCH_RemoveTimeout(SCH_TimeoutID id)
|
||||||
/* Release memory back to the operating system */
|
/* Release memory back to the operating system */
|
||||||
release_tqe(ptr);
|
release_tqe(ptr);
|
||||||
|
|
||||||
ok = 1;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(ok);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
@ -433,27 +425,24 @@ SCH_RemoveTimeout(SCH_TimeoutID id)
|
||||||
static int
|
static int
|
||||||
dispatch_timeouts(struct timeval *now) {
|
dispatch_timeouts(struct timeval *now) {
|
||||||
TimerQueueEntry *ptr;
|
TimerQueueEntry *ptr;
|
||||||
|
SCH_TimeoutHandler handler;
|
||||||
|
SCH_ArbitraryArgument arg;
|
||||||
int n_done = 0;
|
int n_done = 0;
|
||||||
|
|
||||||
if ((n_timer_queue_entries > 0) &&
|
if ((n_timer_queue_entries > 0) &&
|
||||||
(UTI_CompareTimevals(now, &(timer_queue.next->tv)) >= 0)) {
|
(UTI_CompareTimevals(now, &(timer_queue.next->tv)) >= 0)) {
|
||||||
ptr = timer_queue.next;
|
ptr = timer_queue.next;
|
||||||
|
|
||||||
|
handler = ptr->handler;
|
||||||
|
arg = ptr->arg;
|
||||||
|
|
||||||
|
SCH_RemoveTimeout(ptr->id);
|
||||||
|
|
||||||
/* Dispatch the handler */
|
/* Dispatch the handler */
|
||||||
(ptr->handler)(ptr->arg);
|
(handler)(arg);
|
||||||
|
|
||||||
/* Increment count of timeouts handled */
|
/* Increment count of timeouts handled */
|
||||||
++n_done;
|
++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;
|
return n_done;
|
||||||
|
|
Loading…
Reference in a new issue