]> Kevux Git Server - controller/commitdiff
Update: Add additional locking to the instance cancel.
authorKevin Day <Kevin@kevux.org>
Thu, 14 Aug 2025 03:50:08 +0000 (22:50 -0500)
committerKevin Day <Kevin@kevux.org>
Thu, 14 Aug 2025 03:50:08 +0000 (22:50 -0500)
Expand the locking functions to accept the seconds and nanoseconds.
Provide standard locking functions that do not need the seconds and nanoseconds passed.

Add locking with fail out status checks to the instance clean up function.

sources/c/program/controller/main/entry/process.c
sources/c/program/controller/main/instance/prepare.c
sources/c/program/controller/main/lock.c
sources/c/program/controller/main/lock.h
sources/c/program/controller/main/rule/execute.c
sources/c/program/controller/main/rule/instance.c
sources/c/program/controller/main/rule/instance.h
sources/c/program/controller/main/rule/wait.c
sources/c/program/controller/main/thread/instance.c

index 402bf48eefad3ff859ca2b8dd4fac6cbde53cc95..ab130947e1bdc4724d750ba9ef13d513f81c2612 100644 (file)
@@ -186,7 +186,7 @@ extern "C" {
           break;
         }
         else if (entry_action->type == controller_entry_action_type_consider_e || controller_entry_action_type_is_rule(entry_action->type)) {
-          status_lock = controller_lock_write(is_entry, F_true, &main->thread, &main->thread.lock.rule);
+          status_lock = controller_lock_write_standard(is_entry, F_true, &main->thread, &main->thread.lock.rule);
 
           if (status_lock != F_okay) {
             controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false);
@@ -214,7 +214,7 @@ extern "C" {
           id_rule_name[entry_action->parameters.array[0].used] = f_path_separator_s.string[0];
           id_rule_name[id_rule_length] = 0;
 
-          status_lock = controller_lock_read(is_entry, F_true, &main->thread, &main->thread.lock.rule);
+          status_lock = controller_lock_read_standard(is_entry, F_true, &main->thread, &main->thread.lock.rule);
 
           if (status_lock != F_okay) {
             controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_true);
@@ -251,7 +251,7 @@ extern "C" {
             memcpy(cache_name_item, cache->action.name_item.string, sizeof(f_char_t) * cache->action.name_item.used);
             memcpy(cache_name_file, cache->action.name_file.string, sizeof(f_char_t) * cache->action.name_file.used);
 
-            status_lock = controller_lock_write(is_entry, F_true, &main->thread, &main->thread.lock.rule);
+            status_lock = controller_lock_write_standard(is_entry, F_true, &main->thread, &main->thread.lock.rule);
 
             if (status_lock == F_okay) {
               status = controller_rule_read(main, cache, is_entry, alias_rule, entry, &main->process.rules.array[main->process.rules.used]);
index 078f233745750adbc80e0e196aeff42fdede8be0..ffa0012e6a2b95d5424d1d53e6b382500c5c2ac1 100644 (file)
@@ -14,7 +14,7 @@ extern "C" {
     if (controller_instance_find(action, alias, main->thread.instances, id) == F_false) {
       f_thread_unlock(&main->thread.lock.instance);
 
-      status = controller_lock_write(is_normal, F_true, &main->thread, &main->thread.lock.instance);
+      status = controller_lock_write_standard(is_normal, F_true, &main->thread, &main->thread.lock.instance);
 
       if (status != F_okay) {
         controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status), F_false);
@@ -35,7 +35,7 @@ extern "C" {
           controller_instance_t * const instance = F_status_is_error_not(status) ? main->thread.instances.array[main->thread.instances.used] : 0;
 
           if (status == F_okay) {
-            status = controller_lock_write(is_normal, F_true, &main->thread, &instance->lock);
+            status = controller_lock_write_standard(is_normal, F_true, &main->thread, &instance->lock);
           }
 
           if (F_status_is_error(status)) {
@@ -65,7 +65,7 @@ extern "C" {
       }
 
       // The read lock must be restored on return.
-      const f_status_t status_restore = F_status_is_error(controller_lock_read(is_normal, F_false, &main->thread, &main->thread.lock.instance))
+      const f_status_t status_restore = F_status_is_error(controller_lock_read_standard(is_normal, F_false, &main->thread, &main->thread.lock.instance))
         ? F_status_set_error(F_lock_read)
         : F_okay;
 
index ebb4412e9f5bada21f73e74334b77ebc70e98a24..93c560458067799a6f490e9c171f7af5966e62c6 100644 (file)
@@ -83,7 +83,7 @@ extern "C" {
 #endif // _di_controller_lock_create_
 
 #ifndef _di_controller_lock_mutex_
-  f_status_t controller_lock_mutex(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_mutex_t * const mutex) {
+  f_status_t controller_lock_mutex(const uint8_t is_normal, const uint8_t check, const time_t seconds, const long nanoseconds, controller_thread_t * const thread, f_thread_mutex_t * const mutex) {
 
     if (!thread || !mutex) return F_status_set_error(F_parameter);
 
@@ -98,7 +98,12 @@ extern "C" {
       status = f_thread_mutex_lock_timed(&time, mutex);
 
       if (status == F_time) {
-        if (check && !controller_thread_enable_is(thread, is_normal)) return F_status_set_error(F_interrupt);
+        if (check) {
+          if (check == 0x2) {
+            if (F_status_is_error(status)) return status;
+          }
+          else if (!controller_thread_enable_is(thread, is_normal)) return F_status_set_error(F_interrupt);
+        }
       }
       else if (status == F_okay) {
         break;
@@ -109,17 +114,24 @@ extern "C" {
   }
 #endif // _di_controller_lock_mutex_
 
+#ifndef _di_controller_lock_mutex_standard_
+  f_status_t controller_lock_mutex_standard(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_mutex_t * const mutex) {
+
+    return controller_lock_mutex(is_normal, check, controller_thread_timeout_lock_read_seconds_d, controller_thread_timeout_lock_read_nanoseconds_d, thread, mutex);
+  }
+#endif // _di_controller_lock_mutex_standard_
+
 #ifndef _di_controller_lock_mutex_instance_
   f_status_t controller_lock_mutex_instance(controller_instance_t * const instance, f_thread_mutex_t * const mutex) {
 
-    if (!instance || !mutex) return F_status_set_error(F_parameter);
+    if (!instance) return F_status_set_error(F_parameter);
 
-    return controller_lock_mutex(instance->type != controller_instance_type_exit_e, F_true, &instance->main->thread, mutex);
+    return controller_lock_mutex_standard(instance->type != controller_instance_type_exit_e, F_true, &instance->main->thread, mutex);
   }
 #endif // _di_controller_lock_mutex_instance_
 
 #ifndef _di_controller_lock_read_
-  f_status_t controller_lock_read(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_lock_t * const lock) {
+  f_status_t controller_lock_read(const uint8_t is_normal, const uint8_t check, const time_t seconds, const long nanoseconds, controller_thread_t * const thread, f_thread_lock_t * const lock) {
 
     if (!thread || !lock) return F_status_set_error(F_parameter);
 
@@ -129,12 +141,17 @@ extern "C" {
 
       memset(&time, 0, sizeof(f_time_spec_t));
 
-      controller_time_now(controller_thread_timeout_lock_read_seconds_d, controller_thread_timeout_lock_read_nanoseconds_d, &time);
+      controller_time_now(seconds, nanoseconds, &time);
 
       status = f_thread_lock_read_timed(&time, lock);
 
       if (status == F_time) {
-        if (check && !controller_thread_enable_is(thread, is_normal)) return F_status_set_error(F_interrupt);
+        if (check) {
+          if (check == 0x2) {
+            if (F_status_is_error(status)) return status;
+          }
+          else if (!controller_thread_enable_is(thread, is_normal)) return F_status_set_error(F_interrupt);
+        }
       }
       else if (status == F_okay) {
         break;
@@ -145,17 +162,24 @@ extern "C" {
   }
 #endif // _di_controller_lock_read_
 
+#ifndef _di_controller_lock_read_standard_
+  f_status_t controller_lock_read_standard(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_lock_t * const lock) {
+
+    return controller_lock_read(is_normal, check, controller_thread_timeout_lock_read_seconds_d, controller_thread_timeout_lock_read_nanoseconds_d, thread, lock);
+  }
+#endif // _di_controller_lock_read_standard_
+
 #ifndef _di_controller_lock_read_instance_
   f_status_t controller_lock_read_instance(controller_instance_t * const instance, f_thread_lock_t * const lock) {
 
-    if (!instance || !instance->main || !lock) return F_status_set_error(F_parameter);
+    if (!instance || !instance->main) return F_status_set_error(F_parameter);
 
-    return controller_lock_read(instance->type != controller_instance_type_exit_e, F_true, &instance->main->thread, lock);
+    return controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_true, &instance->main->thread, lock);
   }
 #endif // _di_controller_lock_read_instance_
 
 #ifndef _di_controller_lock_write_
-  f_status_t controller_lock_write(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_lock_t * const lock) {
+  f_status_t controller_lock_write(const uint8_t is_normal, const uint8_t check, const time_t seconds, const long nanoseconds, controller_thread_t * const thread, f_thread_lock_t * const lock) {
 
     if (!thread || !lock) return F_status_set_error(F_parameter);
 
@@ -163,12 +187,17 @@ extern "C" {
 
     for (f_time_spec_t time; ; ) {
 
-      controller_time_now(controller_thread_timeout_lock_write_seconds_d, controller_thread_timeout_lock_write_nanoseconds_d, &time);
+      controller_time_now(seconds, nanoseconds, &time);
 
       status = f_thread_lock_write_timed(&time, lock);
 
       if (status == F_time) {
-        if (check && !controller_thread_enable_is(thread, is_normal)) return F_status_set_error(F_interrupt);
+        if (check) {
+          if (check == 0x2) {
+            if (F_status_is_error(status)) return status;
+          }
+          else if (!controller_thread_enable_is(thread, is_normal)) return F_status_set_error(F_interrupt);
+        }
       }
       else if (status == F_okay) {
         break;
@@ -179,12 +208,19 @@ extern "C" {
   }
 #endif // _di_controller_lock_write_
 
+#ifndef _di_controller_lock_write_standard_
+  f_status_t controller_lock_write_standard(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_lock_t * const lock) {
+
+    return controller_lock_write(is_normal, check, controller_thread_timeout_lock_write_seconds_d, controller_thread_timeout_lock_write_nanoseconds_d, thread, lock);
+  }
+#endif // _di_controller_lock_write_standard_
+
 #ifndef _di_controller_lock_write_instance_
   f_status_t controller_lock_write_instance(controller_instance_t * const instance, f_thread_lock_t * const lock) {
 
-    if (!instance || !lock) return F_status_set_error(F_parameter);
+    if (!instance) return F_status_set_error(F_parameter);
 
-    return controller_lock_write(instance->type != controller_instance_type_exit_e, F_true, &instance->main->thread, lock);
+    return controller_lock_write_standard(instance->type != controller_instance_type_exit_e, F_true, &instance->main->thread, lock);
   }
 #endif // _di_controller_lock_write_instance_
 
index 6f53642aa715427890f8ef77d042f696ceeecbc4..4c33330efd6beed627e145ba64c1ba83df8c2c29 100644 (file)
@@ -47,9 +47,14 @@ extern "C" {
  * @param is_normal
  *   If TRUE, then perform as if this operates during a normal operation (Entry and Control).
  *   If FALSE, then perform as if this operates during a an Exit operation.
+ *   IF 0x2, then this is is also TRUE, but it does not call controller_thread_enable_is() and returns on any lock error.
  * @param check
  *   If TRUE, then check if the state is enabled and if it is not then abort.
  *   If FALSE, then do not check if the state is enabled and keep looping.
+ * @param seconds
+ *   The seconds to add to current time.
+ * @param nanoseconds
+ *   The nanoseconds to add to current time.
  * @param thread
  *   The thread data used to determine if the main thread is disabled or not.
  *
@@ -72,10 +77,42 @@ extern "C" {
  * @see f_thread_mutex_lock_timed()
  */
 #ifndef _di_controller_lock_mutex_
-  extern f_status_t controller_lock_mutex(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_mutex_t * const mutex);
+  extern f_status_t controller_lock_mutex(const uint8_t is_normal, const uint8_t check, const time_t seconds, const long nanoseconds, controller_thread_t * const thread, f_thread_mutex_t * const mutex);
 #endif // _di_controller_lock_mutex_
 
 /**
+ * Wait to get a mutex lock, using standard seconds and nanoseconds.
+ *
+ * Given a mutex lock, periodically check to see if main thread is disabled while waiting.
+ *
+ * @param is_normal
+ *   If TRUE, then perform as if this operates during a normal operation (Entry and Control).
+ *   If FALSE, then perform as if this operates during a an Exit operation.
+ *   IF 0x2, then this is is also TRUE, but it does not call controller_thread_enable_is() and returns on any lock error.
+ * @param check
+ *   If TRUE, then check if the state is enabled and if it is not then abort.
+ *   If FALSE, then do not check if the state is enabled and keep looping.
+ * @param thread
+ *   The thread data used to determine if the main thread is disabled or not.
+ *
+ *   Must not be NULL.
+ * @param mutex
+ *   The mutex to lock.
+ *
+ *   Must not be NULL.
+ *
+ * @return
+ *   Status from: controller_lock_mutex().
+ *
+ *   Errors (with error bit) from: controller_lock_mutex().
+ *
+ * @see controller_lock_mutex()
+ */
+#ifndef _di_controller_lock_mutex_standard_
+  extern f_status_t controller_lock_mutex_standard(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_mutex_t * const mutex);
+#endif // _di_controller_lock_mutex_standard_
+
+/**
  * Wait to get a mutex lock for some instance.
  *
  * Given a mutex lock, periodically check to see if main thread is disabled while waiting.
@@ -113,6 +150,11 @@ extern "C" {
  * @param check
  *   If TRUE, then check if the state is enabled and if it is not then abort.
  *   If FALSE, then do not check if the state is enabled and keep looping.
+ *   IF 0x2, then this is is also TRUE, but it does not call controller_thread_enable_is() and returns on any lock error.
+ * @param seconds
+ *   The seconds to add to current time.
+ * @param nanoseconds
+ *   The nanoseconds to add to current time.
  * @param thread
  *   The thread data used to determine if the main thread is disabled or not.
  *
@@ -135,10 +177,42 @@ extern "C" {
  * @see f_thread_lock_read_timed()
  */
 #ifndef _di_controller_lock_read_
-  extern f_status_t controller_lock_read(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_lock_t * const lock);
+  extern f_status_t controller_lock_read(const uint8_t is_normal, const uint8_t check, const time_t seconds, const long nanoseconds, controller_thread_t * const thread, f_thread_lock_t * const lock);
 #endif // _di_controller_lock_read_
 
 /**
+ * Wait to get a read lock, using standard seconds and nanoseconds.
+ *
+ * Given a r/w lock, periodically check to see if main thread is disabled while waiting.
+ *
+ * @param is_normal
+ *   If TRUE, then perform as if this operates during a normal operation (Entry and Control).
+ *   If FALSE, then perform as if this operates during a an Exit operation.
+ * @param check
+ *   If TRUE, then check if the state is enabled and if it is not then abort.
+ *   If FALSE, then do not check if the state is enabled and keep looping.
+ *   IF 0x2, then this is is also TRUE, but it does not call controller_thread_enable_is() and returns on any lock error.
+ * @param thread
+ *   The thread data used to determine if the main thread is disabled or not.
+ *
+ *   Must not be NULL.
+ * @param lock
+ *   The r/w lock to obtain a read lock on.
+ *
+ *   Must not be NULL.
+ *
+ * @return
+ *   Status from: controller_lock_read().
+ *
+ *   Errors (with error bit) from: controller_lock_read().
+ *
+ * @see controller_lock_read()
+ */
+#ifndef _di_controller_lock_read_standard_
+  extern f_status_t controller_lock_read_standard(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_lock_t * const lock);
+#endif // _di_controller_lock_read_standard_
+
+/**
  * Wait to get a read lock for some instance.
  *
  * Given a r/w lock, periodically check to see if main thread is disabled while waiting.
@@ -176,6 +250,11 @@ extern "C" {
  * @param check
  *   If TRUE, then check if the state is enabled and if it is not then abort.
  *   If FALSE, then do not check if the state is enabled and keep looping.
+ *   IF 0x2, then this is is also TRUE, but it does not call controller_thread_enable_is() and returns on any lock error.
+ * @param seconds
+ *   The seconds to add to current time.
+ * @param nanoseconds
+ *   The nanoseconds to add to current time.
  * @param thread
  *   The thread data used to determine if the main thread is disabled or not.
  *
@@ -198,10 +277,42 @@ extern "C" {
  * @see f_thread_lock_write_timed()
  */
 #ifndef _di_controller_lock_write_
-  extern f_status_t controller_lock_write(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_lock_t * const lock);
+  extern f_status_t controller_lock_write(const uint8_t is_normal, const uint8_t check, const time_t seconds, const long nanoseconds, controller_thread_t * const thread, f_thread_lock_t * const lock);
 #endif // _di_controller_lock_write_
 
 /**
+ * Wait to get a write lock, using standard seconds and nanoseconds.
+ *
+ * Given a r/w lock, periodically check to see if main thread is disabled while waiting.
+ *
+ * @param is_normal
+ *   If TRUE, then perform as if this operates during a normal operation (Entry and Control).
+ *   If FALSE, then perform as if this operates during a an Exit operation.
+ * @param check
+ *   If TRUE, then check if the state is enabled and if it is not then abort.
+ *   If FALSE, then do not check if the state is enabled and keep looping.
+ *   IF 0x2, then this is is also TRUE, but it does not call controller_thread_enable_is() and returns on any lock error.
+ * @param thread
+ *   The thread data used to determine if the main thread is disabled or not.
+ *
+ *   Must not be NULL.
+ * @param lock
+ *   The r/w lock to obtain a write lock on.
+ *
+ *   Must not be NULL.
+ *
+ * @return
+ *   Status from: controller_lock_write().
+ *
+ *   Errors (with error bit) from: controller_lock_write().
+ *
+ * @see controller_lock_write()
+ */
+#ifndef _di_controller_lock_write_standard_
+  extern f_status_t controller_lock_write_standard(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_lock_t * const lock);
+#endif // _di_controller_lock_write_standard_
+
+/**
  * Wait to get a write lock for some instance.
  *
  * Given a r/w lock, periodically check to see if main thread is disabled while waiting.
index 93b72cb34a426f7442a1cb3371056febfa07ef5a..94bd07d44bf94d88db89c09add5c5f8edb2f2a85 100644 (file)
@@ -410,7 +410,7 @@ extern "C" {
       success = F_false;
 
       if (F_status_set_fine(status) == F_lock_read) {
-        status = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock);
+        status = controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock);
         if (status != F_okay) return F_status_set_error(F_lock_read);
 
         status = F_status_set_error(F_lock);
@@ -440,7 +440,7 @@ extern "C" {
     f_execute_result_t result = f_execute_result_t_initialize;
 
     // @fixme Lock the instance.childs.used with write access. (active should already have a read lock)
-    //status = controller_lock_write(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock);
+    //status = controller_lock_write_standard(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock);
     //if (status != F_okay) return F_status_set_error(F_lock_read);
 
     status = f_memory_array_increase(controller_allocation_small_d, sizeof(pid_t), (void **) &instance->childs.array, &instance->childs.used, &instance->childs.size);
@@ -491,7 +491,7 @@ extern "C" {
       if (F_status_is_error(status_lock)) {
         controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false);
 
-        status_lock = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &instance->main->thread, &instance->lock);
+        status_lock = controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_false, &instance->main->thread, &instance->lock);
         if (status_lock != F_okay) return F_status_set_error(F_lock_read);
 
         return F_status_set_error(F_lock);
@@ -510,7 +510,7 @@ extern "C" {
 
         // Try again, after the first interrupt.
         if (F_status_set_fine(status_lock) == F_interrupt) {
-          status_lock = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &instance->main->thread, &instance->lock);
+          status_lock = controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_false, &instance->main->thread, &instance->lock);
         }
 
         if (status_lock != F_okay) {
@@ -606,7 +606,7 @@ extern "C" {
     f_execute_result_t result = f_execute_result_t_initialize;
 
     // @fixme Lock the instance.childs.used with write access. (active should already have a read lock)
-    //status = controller_lock_write(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock);
+    //status = controller_lock_write_standard(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock);
     //if (status != F_okay) return F_status_set_error(F_lock_read);
 
     status = f_memory_array_increase(controller_allocation_small_d, sizeof(pid_t), (void **) &instance->childs.array, &instance->childs.used, &instance->childs.size);
@@ -685,7 +685,7 @@ extern "C" {
       if (status_lock != F_okay) {
         controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false);
 
-        status_lock = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &instance->main->thread, &instance->lock);
+        status_lock = controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_false, &instance->main->thread, &instance->lock);
         if (status_lock != F_okay) return F_status_set_error(F_lock_read);
 
         return F_status_set_error(F_lock);
@@ -710,7 +710,7 @@ extern "C" {
       if (status_lock != F_okay) {
         controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false);
 
-        status_lock = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &instance->main->thread, &instance->lock);
+        status_lock = controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_false, &instance->main->thread, &instance->lock);
         if (status_lock != F_okay) return F_status_set_error(F_lock_read);
 
         return F_status_set_error(F_lock);
index 932c0871da08b0ad1ef5c2c4e9c76c8d659f4259..717185fab330a6bdf78225ef70c65f8ac21b11d0 100644 (file)
@@ -407,7 +407,7 @@ extern "C" {
     if (F_status_is_error(status_lock)) {
       controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false);
 
-      status_lock = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock);
+      status_lock = controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock);
       if (status_lock != F_okay) return F_status_set_error(F_lock_read);
 
       return F_status_set_error(F_lock);
@@ -428,7 +428,7 @@ extern "C" {
       // Remove the write lock and restore the read lock.
       f_thread_unlock(&instance->lock);
 
-      status_lock = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock);
+      status_lock = controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock);
       if (status_lock != F_okay) return F_status_set_error(F_lock_read);
 
       return F_status_set_error(F_lock);
@@ -459,7 +459,7 @@ extern "C" {
     if (F_status_is_error(status_lock)) {
       controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_true);
 
-      status_lock = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock);
+      status_lock = controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock);
       if (status_lock != F_okay) return F_status_set_error(F_lock_read);
 
       return F_status_set_error(F_lock);
@@ -475,7 +475,7 @@ extern "C" {
     if (!main || !cache) return F_status_set_error(F_parameter);
     if (!controller_thread_is_enabled_instance_type(&main->thread, type)) return F_status_set_error(F_interrupt);
 
-    f_status_t status = controller_lock_read(type != controller_instance_type_exit_e, F_true, &main->thread, &main->thread.lock.instance);
+    f_status_t status = controller_lock_read_standard(type != controller_instance_type_exit_e, F_true, &main->thread, &main->thread.lock.instance);
 
     if (status != F_okay) {
       controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status), F_true);
@@ -497,7 +497,7 @@ extern "C" {
 
     controller_instance_t * const instance = main->thread.instances.array[at];
 
-    status = controller_lock_read(type != controller_instance_type_exit_e, F_true, &main->thread, &instance->active);
+    status = controller_lock_read_standard(type != controller_instance_type_exit_e, F_true, &main->thread, &instance->active);
 
     if (status != F_okay) {
       controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status), F_true);
index e3fb6f8c41466a1fa781ef304bbb78180b17d88b..6b1b371f1330c1965d5706d288ce41742308c14b 100644 (file)
@@ -42,8 +42,11 @@ extern "C" {
  *   F_lock (with error bit) if failed to establish a lock, and the instance->lock read lock is already restored.
  *   F_lock_read (with error bit) if failed to re-establish read lock on instance->lock while returning.
  *
- *   Errors (with error bit) from: controller_lock_read().
- *   Errors (with error bit) from: controller_lock_write().
+ *   Errors (with error bit) from: controller_lock_read_standard().
+ *   Errors (with error bit) from: controller_lock_write_instance().
+ *
+ *   @see controller_lock_read_standard().
+ *   @see controller_lock_write_instance().
  */
 #ifndef _di_controller_rule_instance_
   extern f_status_t controller_rule_instance(controller_instance_t * const instance);
index 93ecae2e055a9959ea3f7a3dd8c55741fa5e1a2c..701e0d12da22b0b347c1006e349f66115f8aa345 100644 (file)
@@ -9,7 +9,7 @@ extern "C" {
 
     if (!main) return F_status_set_error(F_parameter);
 
-    f_status_t status_lock = controller_lock_read(is_normal, F_false, &main->thread, &main->thread.lock.instance);
+    f_status_t status_lock = controller_lock_read_standard(is_normal, F_false, &main->thread, &main->thread.lock.instance);
 
     if (status_lock != F_okay) {
       controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_true);
@@ -45,7 +45,7 @@ extern "C" {
       if (!controller_thread_enable_is(&main->thread, is_normal)) break;
 
       // Re-establish instance read lock to wait for or protect from the cleanup thread while checking the read instance.
-      status_lock = controller_lock_read(is_normal, F_true, &main->thread, &main->thread.lock.instance);
+      status_lock = controller_lock_read_standard(is_normal, F_true, &main->thread, &main->thread.lock.instance);
       if (status_lock != F_okay) break;
 
       if (!instance_list[i]) {
@@ -54,7 +54,7 @@ extern "C" {
         continue;
       }
 
-      status_lock = controller_lock_read(is_normal, F_true, &main->thread, &instance_list[i]->active);
+      status_lock = controller_lock_read_standard(is_normal, F_true, &main->thread, &instance_list[i]->active);
 
       if (status_lock != F_okay) {
         f_thread_unlock(&main->thread.lock.instance);
@@ -65,7 +65,7 @@ extern "C" {
       // Once the active lock is obtained, then the main instance read lock can be safely released.
       f_thread_unlock(&main->thread.lock.instance);
 
-      status_lock = controller_lock_read(is_normal, F_true, &main->thread, &instance_list[i]->lock);
+      status_lock = controller_lock_read_standard(is_normal, F_true, &main->thread, &instance_list[i]->lock);
 
       if (status_lock != F_okay) {
         f_thread_unlock(&instance_list[i]->active);
@@ -87,7 +87,7 @@ extern "C" {
         if (instance_list[i]->state == controller_instance_state_done_e) {
           f_thread_unlock(&instance_list[i]->lock);
 
-          status_lock = controller_lock_write(is_normal, F_true, &main->thread, &instance_list[i]->lock);
+          status_lock = controller_lock_write_standard(is_normal, F_true, &main->thread, &instance_list[i]->lock);
 
           if (status_lock != F_okay) {
             controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false);
@@ -109,7 +109,7 @@ extern "C" {
               f_thread_condition_signal_all(&instance_list[i]->wait_condition);
             }
 
-            status_lock = controller_lock_read(is_normal, F_true, &main->thread, &instance_list[i]->active);
+            status_lock = controller_lock_read_standard(is_normal, F_true, &main->thread, &instance_list[i]->active);
 
             if (status_lock != F_okay) {
               f_thread_unlock(&instance_list[i]->lock);
@@ -120,7 +120,7 @@ extern "C" {
 
           f_thread_unlock(&instance_list[i]->lock);
 
-          status_lock = controller_lock_read(is_normal, F_true, &main->thread, &instance_list[i]->lock);
+          status_lock = controller_lock_read_standard(is_normal, F_true, &main->thread, &instance_list[i]->lock);
           if (status_lock != F_okay) break;
         }
 
@@ -157,7 +157,7 @@ extern "C" {
           break;
         }
 
-        status_lock = controller_lock_read(is_normal, F_true, &main->thread, &instance_list[i]->lock);
+        status_lock = controller_lock_read_standard(is_normal, F_true, &main->thread, &instance_list[i]->lock);
 
         if (status_lock != F_okay) {
           f_thread_unlock(&instance_list[i]->active);
index e446e6510fe0ad7a5204a004c47ebb396d477680..df4ab6ede7335701391741420cd1fddc041dcb7b 100644 (file)
@@ -28,25 +28,8 @@ extern "C" {
 
     if (!main) return;
 
-    f_status_t status = F_okay;
-
-    {
-      f_time_spec_t time;
-
-      do {
-        if (!controller_thread_enable_is(&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_okay);
-
-      status = F_okay;
-    }
+    f_status_t status = controller_lock_mutex(is_normal, 0x2, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &main->thread.lock.cancel);
+    if (F_status_is_error(status)) return;
 
     // Only cancel when enabled.
     if (!controller_thread_enable_is(&main->thread, is_normal)) {
@@ -71,6 +54,8 @@ extern "C" {
     time.tv_nsec = interval_nanoseconds;
 
     if (main->process.mode == controller_process_mode_helper_e && !(main->setting.flag & controller_main_flag_validate_d)) {
+      controller_lock_read(is_normal, F_false, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &main->thread.lock.instance);
+
       for (i = 0; i < main->thread.instances.used; ++i) {
 
         if (!main->thread.instances.array[i]) continue;
@@ -83,6 +68,8 @@ extern "C" {
 
         instance->id_thread = 0;
       } // for
+
+      f_thread_unlock(&main->thread.lock.instance);
     }
 
     {
@@ -129,6 +116,14 @@ extern "C" {
       return;
     }
 
+    status = controller_lock_read(is_normal, F_false, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &main->thread.lock.instance);
+
+    if (F_status_is_error(status)) {
+      f_thread_mutex_unlock(&main->thread.lock.cancel);
+
+      return;
+    }
+
     for (int signal = 0; i < main->thread.instances.used; ++i) {
 
       if (!main->thread.instances.array[i]) continue;
@@ -152,7 +147,7 @@ extern "C" {
       for (j = 0; j < instance->path_pids.used; ++j) {
 
         if (instance->path_pids.array[j].used && f_file_exists(instance->path_pids.array[j], F_true) == F_true) {
-          status = controller_file_pid_read(instance->path_pids.array[j], &pid);
+          controller_file_pid_read(instance->path_pids.array[j], &pid);
 
           if (pid) {
             signal = controller_thread_signal_get(&main->thread);
@@ -163,9 +158,13 @@ extern "C" {
       } // for
     } // for
 
+    f_thread_unlock(&main->thread.lock.instance);
+
     if (entry->timeout_exit && !(entry->flag & controller_entry_flag_timeout_exit_no_e)) {
       f_number_unsigned_t lapsed = 0;
 
+      controller_lock_read(is_normal, F_false, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &main->thread.lock.instance);
+
       for (i = 0; i < main->thread.instances.used && lapsed < entry->timeout_exit; ++i) {
 
         if (!main->thread.instances.array[i]) continue;
@@ -201,7 +200,7 @@ extern "C" {
         for (j = 0; j < instance->path_pids.used && lapsed < entry->timeout_exit; ++j) {
 
           if (instance->path_pids.array[j].used && f_file_exists(instance->path_pids.array[j], F_true) == F_true) {
-            status = controller_file_pid_read(instance->path_pids.array[j], &pid);
+            controller_file_pid_read(instance->path_pids.array[j], &pid);
 
             if (pid) {
               while (lapsed < entry->timeout_exit) {
@@ -225,16 +224,33 @@ extern "C" {
           }
         } // for
       } // for
+
+      f_thread_unlock(&main->thread.lock.instance);
+    }
+
+    status = controller_lock_read(is_normal, F_false, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &main->thread.lock.instance);
+
+    if (F_status_is_error(status)) {
+      f_thread_mutex_unlock(&main->thread.lock.cancel);
+
+      return;
     }
 
     for (i = 0; i < main->thread.instances.size; ++i) {
 
       if (!main->thread.instances.array[i]) continue;
 
+      status = controller_lock_read(is_normal, F_false, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &main->thread.instances.array[i]->active);
+      if (F_status_is_error(status)) continue;
+
       instance = main->thread.instances.array[i];
 
       // Do not kill Exit Instances, when not performing "execute" during exit.
-      if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) continue;
+      if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) {
+        f_thread_unlock(&instance->active);
+
+        continue;
+      }
 
       if (instance->id_thread) {
         if (instance->childs.used) {
@@ -271,7 +287,11 @@ extern "C" {
               f_signal_send(F_signal_kill, instance->childs.array[j]);
             }
 
+            status = controller_lock_write(is_normal, F_false, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &instance->lock);
+
             instance->childs.array[j] = 0;
+
+            if (F_status_is_error_not(status)) f_thread_unlock(&instance->lock);
           }
         } // for
       }
@@ -283,39 +303,53 @@ extern "C" {
           if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) continue;
 
           if (f_file_exists(instance->path_pids.array[j], F_true) == F_true) {
-            status = controller_file_pid_read(instance->path_pids.array[j], &pid);
+            controller_file_pid_read(instance->path_pids.array[j], &pid);
 
             if (pid) {
               f_signal_send(F_signal_kill, pid);
             }
 
+            status = controller_lock_write(is_normal, F_false, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &instance->lock);
+
             f_file_remove(instance->path_pids.array[j]);
             instance->path_pids.array[j].used = 0;
+
+            if (F_status_is_error_not(status)) f_thread_unlock(&instance->lock);
           }
         } // for
       }
 
-      // Shrink the child pids as much as possible.
-      while (instance->childs.used) {
+      status = controller_lock_write(is_normal, F_false, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &instance->lock);
 
-        // Do not shrink below an Exit Instances, when not performing "execute" during exit.
-        if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) break;
-        if (instance->childs.array[j] > 0) break;
+      if (F_status_is_error_not(status)) {
 
-        --instance->childs.used;
-      } // while
+        // Shrink the child pids as much as possible.
+        while (instance->childs.used) {
 
-      // Shrink the path pids as much as possible.
-      while (instance->path_pids.used) {
+          // Do not shrink below an Exit Instances, when not performing "execute" during exit.
+          if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) break;
+          if (instance->childs.array[j] > 0) break;
 
-        // Do not shrink below an Exit Instances, when not performing "execute" during exit.
-        if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) break;
-        if (instance->path_pids.array[j].used) break;
+          --instance->childs.used;
+        } // while
+
+        // Shrink the path pids as much as possible.
+        while (instance->path_pids.used) {
+
+          // Do not shrink below an Exit Instances, when not performing "execute" during exit.
+          if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) break;
+          if (instance->path_pids.array[j].used) break;
+
+          --instance->path_pids.used;
+        } // while
+
+        f_thread_unlock(&instance->lock);
+      }
 
-        --instance->path_pids.used;
-      } // while
+      f_thread_unlock(&instance->active);
     } // for
 
+    f_thread_unlock(&main->thread.lock.instance);
     f_thread_mutex_unlock(&main->thread.lock.cancel);
   }
 #endif // _di_controller_thread_instance_cancel_