From cf96c463dc66d8581150a5b5f2e85c2e25b97fcc Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Tue, 22 Oct 2019 23:20:06 -0400 Subject: [PATCH] Fix #274: Avoid possible deadlock of timer callback If the tick_time from the wait routine was perpetually greater than the interval time, eventually the wait_time became such that it was always below zero. Once this occurs, application callbacks would cease entirely. To avoid this, run the callback condition in a loop for periodic timers only (not for one-shot config). --- src/os/shared/osapi-timebase.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/os/shared/osapi-timebase.c b/src/os/shared/osapi-timebase.c index e6cd7cad3..50384b2aa 100644 --- a/src/os/shared/osapi-timebase.c +++ b/src/os/shared/osapi-timebase.c @@ -494,7 +494,7 @@ void OS_TimeBase_CallbackThread(uint32 timebase_id) timecb = &OS_timecb_table[curr_cb_local_id]; saved_wait_time = timecb->wait_time; timecb->wait_time -= tick_time; - if (timecb->wait_time <= 0) + while (timecb->wait_time <= 0) { timecb->wait_time += timecb->interval_time; @@ -519,6 +519,14 @@ void OS_TimeBase_CallbackThread(uint32 timebase_id) { (*timecb->callback_ptr)(curr_cb_public_id, timecb->callback_arg); } + + /* + * Do not repeat the loop unless interval_time is configured. + */ + if (timecb->interval_time <= 0) + { + break; + } } curr_cb_local_id = timecb->next_ref; }