From 505b1aca2c6a4a15b5834698e3f331046726c6ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Thu, 7 Mar 2019 10:38:59 +0100 Subject: [PATCH] lockstep_scheduler: work around a potential dead-lock for canceled threads --- .../include/lockstep_scheduler/lockstep_scheduler.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/platforms/posix/src/lockstep_scheduler/include/lockstep_scheduler/lockstep_scheduler.h b/platforms/posix/src/lockstep_scheduler/include/lockstep_scheduler/lockstep_scheduler.h index 10c084aa4b..d9c8c6daee 100644 --- a/platforms/posix/src/lockstep_scheduler/include/lockstep_scheduler/lockstep_scheduler.h +++ b/platforms/posix/src/lockstep_scheduler/include/lockstep_scheduler/lockstep_scheduler.h @@ -21,6 +21,18 @@ private: struct TimedWait { ~TimedWait() { + if (!done) { + // This can only happen when a thread gets canceled (e.g. via pthread_cancel), and since + // pthread_cond_wait is a cancellation point, the rest of LockstepScheduler::cond_timedwait afterwards + // might not be executed. Which means the mutex will not be unlocked either, so we unlock to avoid + // a dead-lock in LockstepScheduler::set_absolute_time(). + // This destructor gets called as part of thread-local storage cleanup. + // This is really only a work-around for non-proper thread stopping. Note that we also assume, + // that we can still access the mutex. + pthread_mutex_unlock(passed_lock); + done = true; + } + // If a thread quickly exits after a cond_timedwait(), the // thread_local object can still be in the linked list. In that case // we need to wait until it's removed.