iotivity-lite
iotivity-lite copied to clipboard
Race condition when polling an oc_process
Preconditions:
- main loop is running on the main thread in the classic form
while (!quit) {
oc_clock_time_t next_event_mt = oc_main_poll_v1();
pthread_mutex_lock(&mutex);
if (next_event_mt == 0) {
pthread_cond_wait(&cv, &mutex);
} else {
struct timespec next_event = { 1, 0 };
oc_clock_time_t next_event_cv;
if (oc_clock_monotonic_time_to_posix(next_event_mt, CLOCK_MONOTONIC,
&next_event_cv)) {
next_event = oc_clock_time_to_timespec(next_event_cv);
}
pthread_cond_timedwait(&cv, &mutex, &next_event);
}
pthread_mutex_unlock(&mutex);
}
- signal event loop callback implementation:
void
signal_event_loop(void)
{
pthread_cond_signal(&cv);
}
Issue: race condition between oc_main_poll_v1()
and signal_event_loop()
Scenario:
- (main thread) oc_main_poll_v1 call finishes and calculates that the next event should executes in 10seconds, execution of the thread is paused
- (second thread) calls oc_process_poll(process) and _oc_signal_event_loop() // we expected the poll handler to wake the main thread and execute action in a very short time; since the main thread is on yet waiting on the condition variable the
pthread_cond_signal
call fromsignal_event_loop
does nothing - (main thread) resumes execution and sleeps for 10secs and only then executes the process poll handler
Expected behavior:
-
call of oc_process_poll(process) and _oc_signal_event_loop() wakes up the main loop right away
-
Windows code suffers from the same issue
The issue is fixed in tests, but example binaries in apps need to be updated.