]> Kevux Git Server - fll/commitdiff
Update: Add additional protection around assignment of global.thread.enabled during...
authorKevin Day <Kevin@kevux.org>
Sat, 13 Jul 2024 04:57:20 +0000 (23:57 -0500)
committerKevin Day <Kevin@kevux.org>
Sat, 13 Jul 2024 05:08:42 +0000 (00:08 -0500)
Spend some time trying to ensure that the mutex lock can be achieved and then change the enabled state to disabled.
Add a maximum retry as a fail safe but otherwise keep retrying unless certain error conditions are encountered.

level_3/controller/c/common/private-lock.h
level_3/controller/c/thread/private-thread_process.c

index 965e3ec4150a8b92b0188b4423d4fd9131efbc17..4ddaedc21dde4776bc7f32ca9556092557d15750 100644 (file)
@@ -13,6 +13,16 @@ extern "C" {
 #endif
 
 /**
+ * Controller lock defines.
+ *
+ * controller_lock_*_d:
+ *   - mutex_max_retry: The maximum amount of times to retry the mutex lock before giving up.
+ */
+#ifndef _di_controller_lock_d_
+  #define controller_lock_mutex_max_retry_d 1000000
+#endif // _di_controller_lock_d_
+
+/**
  * A structure for sharing mutexes globally between different threads.
  *
  * The alert lock is intended for a generic waiting on alerts operations.
index 5e5c87b197ee21dbf0c34495873bae69ec47da6e..51954ab44766232dc3fbae85bb318f1ba58be848 100644 (file)
@@ -61,7 +61,6 @@ extern "C" {
     controller_entry_t *entry = 0;
     controller_process_t *process = 0;
 
-    f_status_t status = F_none;
     f_array_length_t i = 0;
     f_array_length_t j = 0;
     pid_t pid = 0;
@@ -99,13 +98,16 @@ extern "C" {
       } // for
     }
 
-    // Use the alert lock to toggle enabled (using it as if it is a write like and a signal lock).
-    status = f_thread_mutex_lock(&global->thread->lock.alert);
+    f_status_t status = F_none;
 
-    if (F_status_is_error(status)) {
-      global->thread->enabled = controller_thread_enabled_not_e;
-    }
-    else {
+    for (f_array_length_t i = 0; i < controller_lock_mutex_max_retry_d; ++i) {
+
+      status = f_thread_mutex_lock(&global->thread->lock.alert);
+
+      if (F_status_is_error_not(status) || F_status_set_fine(status) == F_parameter || F_status_set_fine(status) == F_deadlock) break;
+    } // for
+
+    if (F_status_is_error_not(status) && F_status_set_fine(status) != F_parameter && F_status_set_fine(status) != F_deadlock) {
       if (by == controller_thread_cancel_execute_e) {
         global->thread->enabled = controller_thread_enabled_execute_e;
       }