]> Kevux Git Server - fll/commitdiff
Bugfix: Multiple cancellations may occur, use mutex lock to prevent.
authorKevin Day <kevin@kevux.org>
Thu, 9 Mar 2023 02:31:39 +0000 (20:31 -0600)
committerKevin Day <kevin@kevux.org>
Thu, 9 Mar 2023 02:31:39 +0000 (20:31 -0600)
There is an existing check that prevents the cancellation from being called more than once.
What is not being considered is that if the main thread calls cancellation while another cancellation is active then the controller_thread_process_exit() gets called.
The controller_thread_process_exit() function will begin more forcibly shutting things down.

Avoid this by providing a mutex lock to lock the cancellation.
Only once the first cancellation is complete will the second (or more) then return without doing anything.

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

index 84cc6854f9e634c467c891951987b67308565f0e..eec15c254b188a46c20e69574a1076f70acb5716 100644 (file)
@@ -45,6 +45,7 @@ extern "C" {
   void controller_lock_delete_simple(controller_lock_t * const lock) {
 
     controller_lock_delete_mutex(&lock->alert);
+    controller_lock_delete_mutex(&lock->cancel);
     controller_lock_delete_mutex(&lock->print);
 
     controller_lock_delete_rw(&lock->process);
index ef1e73bb1ca8742905cc38f67ae84c042e398178..ee7baeed419ebbba98596dc0fc3a81e4860fbb62 100644 (file)
@@ -16,11 +16,13 @@ extern "C" {
  * A structure for sharing mutexes globally between different threads.
  *
  * The alert lock is intended for a generic waiting on alerts operations.
+ * The cancel lock is intended for preventing double cancellation calls (which can happen due to interrupts).
  * The print lock is intended to lock any activity printing to stdout/stderr.
  * The process lock is intended to lock any activity on the processs structure.
  * The rule lock is intended to lock any activity on the rules structure.
  *
  * alert:           The alert mutex lock for waking up on alerts.
+ * cancel:          The cancel mutex lock for locking the cancel operation.
  * print:           The print mutex lock.
  * process:         The process r/w lock.
  * rule:            The rule r/w lock.
@@ -29,6 +31,7 @@ extern "C" {
 #ifndef _di_controller_lock_t_
   typedef struct {
     f_thread_mutex_t alert;
+    f_thread_mutex_t cancel;
     f_thread_mutex_t print;
 
     f_thread_lock_t process;
@@ -40,6 +43,7 @@ extern "C" {
   #define controller_lock_t_initialize { \
     f_thread_mutex_t_initialize, \
     f_thread_mutex_t_initialize, \
+    f_thread_mutex_t_initialize, \
     f_thread_lock_t_initialize, \
     f_thread_lock_t_initialize, \
     f_thread_condition_t_initialize, \
index ee3c08fcda5e553d0d325d607ede6773a2a7ce12..311d2e80615010c727aa03ef51b70a45dc226587 100644 (file)
@@ -14,6 +14,9 @@ extern "C" {
     f_status_t status = f_thread_mutex_create(0, &lock->alert);
     if (F_status_is_error(status)) return status;
 
+    status = f_thread_mutex_create(0, &lock->cancel);
+    if (F_status_is_error(status)) return status;
+
     status = f_thread_mutex_create(0, &lock->print);
     if (F_status_is_error(status)) return status;
 
index ceb01937df8fa9f4ae0bb4cca7388357324a4c83..750f17a9caa1c5b3b6e4fa05990da074f183b5fd 100644 (file)
@@ -45,8 +45,13 @@ extern "C" {
 #ifndef _di_controller_thread_process_cancel_
   void controller_thread_process_cancel(const controller_global_t global, const bool is_normal, const uint8_t by, controller_process_t * const caller) {
 
+    f_thread_mutex_lock(&global.thread->lock.cancel);
+
     // Only cancel when enabled.
     if (!controller_thread_is_enabled(is_normal, global.thread)) {
+
+      f_thread_mutex_unlock(&global.thread->lock.cancel);
+
       return;
     }
 
@@ -300,6 +305,8 @@ extern "C" {
         --process->path_pids.used;
       } // while
     } // for
+
+    f_thread_mutex_unlock(&global.thread->lock.cancel);
   }
 #endif // _di_controller_thread_process_cancel_