]> Kevux Git Server - controller/commitdiff
Bugfix: Instance thread can deadlock on interrupt.
authorKevin Day <Kevin@kevux.org>
Tue, 29 Jul 2025 02:57:38 +0000 (21:57 -0500)
committerKevin Day <Kevin@kevux.org>
Tue, 29 Jul 2025 03:14:00 +0000 (22:14 -0500)
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.

sources/c/program/controller/main/thread/instance.c

index 9cd8c673502df33ab8e8e87b888064af3abbe5b4..d0ec5b391840699e2b07da9f5bc7c5392bb0089b 100644 (file)
@@ -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);