From a6c48608f4bbec94d3c5939d165ce8cee6eab53b Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Mon, 28 Jul 2025 21:57:38 -0500 Subject: [PATCH] Bugfix: Instance thread can deadlock on interrupt. The instance thread can deadlock on interrupt because the thread enable is not being checked before performing the lock. Add a wait and retry lock that includes checking if enabled. --- .../c/program/controller/main/thread/instance.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/sources/c/program/controller/main/thread/instance.c b/sources/c/program/controller/main/thread/instance.c index 9cd8c67..d0ec5b3 100644 --- a/sources/c/program/controller/main/thread/instance.c +++ b/sources/c/program/controller/main/thread/instance.c @@ -28,7 +28,25 @@ extern "C" { if (!main) return; - f_thread_mutex_lock(&main->thread.lock.cancel); + f_status_t status = F_okay; + + { + f_time_spec_t time; + + do { + if (!controller_thread_is_enabled(&main->thread, is_normal)) return; + + memset((void *) &time, 0, sizeof(struct timespec)); + + controller_time_now(controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &time); + + status = f_thread_mutex_lock_timed(&time, &main->thread.lock.cancel); + if (F_status_is_error(status)) return; + + } while (status == F_time); + + status = F_okay; + } // Only cancel when enabled. if (!controller_thread_is_enabled(&main->thread, is_normal)) { @@ -67,8 +85,6 @@ extern "C" { } // for } - f_status_t status = F_okay; - for (f_number_unsigned_t i = 0; i < controller_lock_mutex_max_retry_d; ++i) { status = f_thread_mutex_lock(&main->thread.lock.alert); -- 1.8.3.1