]> 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:27:46 +0000 (20:27 -0600)
committerKevin Day <kevin@kevux.org>
Thu, 9 Mar 2023 02:27:46 +0000 (20:27 -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 59e2d88cddedb901ea5fc697834addf2f9904182..965e3ec4150a8b92b0188b4423d4fd9131efbc17 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 29f54446467c161681cad59a8e22803b68d908f3..07f170d544631a14cfdf1bc56d00a6bf2dc5b237 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_