]> Kevux Git Server - controller/commitdiff
Update: Major improvements in locking logic.
authorKevin Day <Kevin@kevux.org>
Sun, 10 Aug 2025 01:32:18 +0000 (20:32 -0500)
committerKevin Day <Kevin@kevux.org>
Sun, 10 Aug 2025 01:32:18 +0000 (20:32 -0500)
Major Improvements:
- Add custom thread status checking functions (also replacing `controller_thread_is_enabled()` with `controller_thread_enable_is()`).
- The thread enable property is now `enable` rather than `enabled`.
- Add new `controller_thread_enable_none_e` to allow for handling default behavior.
- Add new `enable` read/write lock to better handle the reading and writing of the enable property.
- Change the signalling logic to directly call `f_thread_condition_signal_all()` and to not read lock the conditions on signal send.
- Change the lock status checks to more explicitly check for `F_okay` so that unknown conditions without error bit set are ignored.

Being explicit on handling the `F_okay` helps ensures that the lock is guaranteed to be set.

I think I need to additional review and re-structuring of the thread logic beyond this commit.
There will likely be additional commits in the future to further improve the locking logic.

I believe that there are some cases where unlock might be called on a not-locked lock.
The additional work will likely include addressing this.
I suspect this is happening in cases where the same function is called in two different contexts.
One context is directly from a thread and another is in the middle of processing something.
The lock might not be set in the case of the directly calling from the thread.

32 files changed:
data/build/settings
data/build/stand_alone/settings.controller
data/build/stand_alone/settings.init
sources/c/program/controller/init/signal.c
sources/c/program/controller/main/common/enumeration/thread.h
sources/c/program/controller/main/common/type/lock.c
sources/c/program/controller/main/common/type/lock.h
sources/c/program/controller/main/common/type/thread.h
sources/c/program/controller/main/controller.h
sources/c/program/controller/main/entry.c
sources/c/program/controller/main/entry/preprocess.c
sources/c/program/controller/main/entry/process.c
sources/c/program/controller/main/instance.c
sources/c/program/controller/main/instance.h
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/process.c
sources/c/program/controller/main/rule/execute.c
sources/c/program/controller/main/rule/instance.c
sources/c/program/controller/main/rule/wait.c
sources/c/program/controller/main/thread/cleanup.c
sources/c/program/controller/main/thread/control.c
sources/c/program/controller/main/thread/enable.c [new file with mode: 0644]
sources/c/program/controller/main/thread/enable.h [new file with mode: 0644]
sources/c/program/controller/main/thread/entry.c
sources/c/program/controller/main/thread/instance.c
sources/c/program/controller/main/thread/instance.h
sources/c/program/controller/main/thread/is.c
sources/c/program/controller/main/thread/is.h
sources/c/program/controller/main/thread/rule.c
sources/c/program/controller/main/thread/signal.c

index 4dc0fa88497af1223c97d02ffe41fda2c78784e6..e8f614fcfbd91251ced0b05ae9a4f86ae9b0e7bb 100644 (file)
@@ -70,7 +70,7 @@ build_sources_library print/output/entry/setting.c print/output/rule/execute.c p
 build_sources_library print/message.c print/message/entry.c print/message/entry/action.c print/message/entry/item.c
 build_sources_library print/warning/entry/action.c print/warning/entry/item.c print/warning/entry/setting.c print/warning/rule/action.c print/warning/rule/item.c print/warning/rule/setting.c
 build_sources_library signal.c status.c time.c
-build_sources_library thread.c thread/cleanup.c thread/control.c thread/entry.c thread/instance.c thread/is.c thread/rule.c thread/signal.c
+build_sources_library thread.c thread/cleanup.c thread/control.c thread/enable.c thread/entry.c thread/instance.c thread/is.c thread/rule.c thread/signal.c
 build_sources_library validate.c
 
 build_sources_headers common.h controller.h common/define.h common/enumeration.h common/print.h common/string.h common/thread.h common/type.h
@@ -93,7 +93,7 @@ build_sources_headers print/output/entry/setting.h print/output/rule/execute.h p
 build_sources_headers print/message.h print/message/entry.h print/message/entry/action.h print/message/entry/item.h
 build_sources_headers print/warning/entry/action.h print/warning/entry/item.h print/warning/entry/setting.h print/warning/rule/action.h print/warning/rule/item.h print/warning/rule/setting.h
 build_sources_headers signal.h status.h time.h
-build_sources_headers thread.h thread/cleanup.h thread/control.h thread/entry.h thread/instance.h thread/is.h thread/rule.h thread/signal.h
+build_sources_headers thread.h thread/cleanup.h thread/control.h thread/enable.h thread/entry.h thread/instance.h thread/is.h thread/rule.h thread/signal.h
 build_sources_headers validate.h
 
 build_sources_documentation man
index 6ddbce38398395902047d56e6716670ba9d69ba9..2cefe19e7e2e3c9f5decac6ec1782cfbbad24d2b 100644 (file)
@@ -105,7 +105,7 @@ build_sources_program program/controller/main/print/output/entry/setting.c progr
 build_sources_program program/controller/main/print/message.c program/controller/main/print/message/entry.c program/controller/main/print/message/entry/action.c program/controller/main/print/message/entry/item.c
 build_sources_program program/controller/main/print/warning/entry/action.c program/controller/main/print/warning/entry/item.c program/controller/main/print/warning/entry/setting.c program/controller/main/print/warning/rule/action.c program/controller/main/print/warning/rule/item.c program/controller/main/print/warning/rule/setting.c
 build_sources_program program/controller/main/signal.c program/controller/main/status.c program/controller/main/time.c
-build_sources_program program/controller/main/thread.c program/controller/main/thread/cleanup.c program/controller/main/thread/control.c program/controller/main/thread/entry.c program/controller/main/thread/instance.c program/controller/main/thread/is.c program/controller/main/thread/rule.c program/controller/main/thread/signal.c
+build_sources_program program/controller/main/thread.c program/controller/main/thread/cleanup.c program/controller/main/thread/control.c program/controller/main/thread/enable.c program/controller/main/thread/entry.c program/controller/main/thread/instance.c program/controller/main/thread/is.c program/controller/main/thread/rule.c program/controller/main/thread/signal.c
 build_sources_program program/controller/main/validate.c
 
 build_sources_program program/controller/controller/config.c program/controller/controller/main.c program/controller/controller/controller.c program/controller/controller/string.c
index 7639b49d5fd9a2afda4ee2c6ce9c2c7655e4368f..5c90e118047902575b283b7d949c4a0c3563c06f 100644 (file)
@@ -105,7 +105,7 @@ build_sources_program program/controller/main/print/output/entry/setting.c progr
 build_sources_program program/controller/main/print/message.c program/controller/main/print/message/entry.c program/controller/main/print/message/entry/action.c program/controller/main/print/message/entry/item.c
 build_sources_program program/controller/main/print/warning/entry/action.c program/controller/main/print/warning/entry/item.c program/controller/main/print/warning/entry/setting.c program/controller/main/print/warning/rule/action.c program/controller/main/print/warning/rule/item.c program/controller/main/print/warning/rule/setting.c
 build_sources_program program/controller/main/signal.c program/controller/main/status.c program/controller/main/time.c
-build_sources_program program/controller/main/thread.c program/controller/main/thread/cleanup.c program/controller/main/thread/control.c program/controller/main/thread/entry.c program/controller/main/thread/instance.c program/controller/main/thread/is.c program/controller/main/thread/rule.c program/controller/main/thread/signal.c
+build_sources_program program/controller/main/thread.c program/controller/main/thread/cleanup.c program/controller/main/thread/control.c program/controller/main/thread/enable.c program/controller/main/thread/entry.c program/controller/main/thread/instance.c program/controller/main/thread/is.c program/controller/main/thread/rule.c program/controller/main/thread/signal.c
 build_sources_program program/controller/main/validate.c
 
 build_sources_program program/controller/init/config.c program/controller/init/main.c program/controller/init/init.c program/controller/init/print.c program/controller/init/signal.c program/controller/init/string.c
index 7e777a409c21b1aec1d22f29a20a6d2128d5aeaf..2a64c7f3452aa27675d91d702cd318c689c1b1fb 100644 (file)
@@ -8,13 +8,13 @@ extern "C" {
   void controller_init_signal_thread(controller_t * const main, const uint8_t is_normal) {
 
     if (!main) return;
-    if (!controller_thread_is_enabled(&main->thread, is_normal)) return;
+    if (!controller_thread_enable_is(&main->thread, is_normal)) return;
     if (!(main->setting.flag & controller_main_flag_interruptible_d)) return;
 
     siginfo_t information;
     f_time_spec_t time = f_time_spec_t_initialize;
 
-    while (controller_thread_is_enabled(&main->thread, is_normal)) {
+    while (controller_thread_enable_is(&main->thread, is_normal)) {
 
       memset((void *) &information, 0, sizeof(siginfo_t));
 
@@ -30,7 +30,7 @@ extern "C" {
 
       // Send F_signal_reserved_35 to cleanup process to reap child processes.
       if (information.si_signo == F_signal_child || information.si_signo == F_signal_reserved_35) {
-        controller_lock_signal(&main->thread.lock.reap_condition, &main->thread.lock.reap);
+        f_thread_condition_signal_all(&main->thread.lock.reap_condition);
 
         continue;
       }
@@ -38,7 +38,7 @@ extern "C" {
       if (information.si_signo == F_signal_interrupt || information.si_signo == F_signal_abort || information.si_signo == F_signal_quit || information.si_signo == F_signal_termination) {
         main->thread.signal = information.si_signo;
 
-        controller_lock_signal(&main->thread.lock.reap_condition, &main->thread.lock.reap);
+        f_thread_condition_signal_all(&main->thread.lock.reap_condition);
         controller_thread_instance_cancel(main, is_normal, controller_thread_cancel_signal_e);
 
         break;
index 9411ed9c914737200e2c3309ed92012c958a95fa..05eb318fdc38016ae450136bea7725c22b3608d9 100644 (file)
@@ -19,8 +19,9 @@ extern "C" {
   /**
    * States for the thread, designating how to stop the process.
    *
-   * controller_thread_*_e:
-   *   - enabled_not:          The controller is no longer enabled, shut down and abort all work.
+   * controller_thread_enable_*_e:
+   *   - enabled_none:         The enable state is not set or unknown (may be returned to designate failure to read enable state).
+   *   - enabled_not:          The controller is no longer enabled, shut down and abort all work (this is expected to be smaller than all enabled modes other than "none".
    *   - enabled:              The controller is operating normally.
    *   - enabled_execute:      The controller is executing another process, all running operations must terminate.
    *   - enabled_exit:         The controller is shutting down, only process Exit rules.
@@ -28,12 +29,13 @@ extern "C" {
    *   - enabled_exit_ready:   The controller is shutting down, only process Exit rules, and now ready to send termination signals.
    */
   enum {
-    controller_thread_enabled_not_e = 0,
-    controller_thread_enabled_e,
-    controller_thread_enabled_execute_e,
-    controller_thread_enabled_exit_e,
-    controller_thread_enabled_exit_execute_e,
-    controller_thread_enabled_exit_ready_e,
+    controller_thread_enable_none_e = 0,
+    controller_thread_enable_not_e,
+    controller_thread_enable_e,
+    controller_thread_enable_execute_e,
+    controller_thread_enable_exit_e,
+    controller_thread_enable_exit_execute_e,
+    controller_thread_enable_exit_ready_e,
   }; // enum
 
   /**
index d7b45db141777a3159dde0763edf848d72e6c089..a3a16cc0aee5c1b2fdbf7194b8370db2f030bc06 100644 (file)
@@ -14,6 +14,7 @@ extern "C" {
     f_thread_mutex_delete(&lock->print);
     f_thread_mutex_delete(&lock->reap);
 
+    f_thread_lock_delete(&lock->enable);
     f_thread_lock_delete(&lock->instance);
     f_thread_lock_delete(&lock->rule);
 
index 34ce5e52b8bc71d071d766571137c923f4b61677..5734438804d8d008aec899bc23aa1e72b2c827b7 100644 (file)
@@ -21,9 +21,10 @@ extern "C" {
  *
  * 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 enable lock is intended for a handling checks to the enable state.
  * The print lock is intended to lock any activity printing to stdout/stderr.
  * The instance lock is intended to lock any activity on the instance structure.
- * The Rule lock is intended to lock any activity on the rules structure.
+ * The rule lock is intended to lock any activity on the rules structure.
  *
  * Properties:
  *   - flag:            A set of flags associated with the locks.
@@ -31,8 +32,9 @@ extern "C" {
  *   - cancel:          The cancel mutex lock for locking the cancel operation.
  *   - print:           The print mutex lock.
  *   - reap:            The reap_condition mutex lock.
+ *   - enable:          The enable r/w lock.
  *   - instance:        The instance r/w lock.
- *   - rule:            The Rule r/w lock.
+ *   - rule:            The rule r/w lock.
  *   - alert_condition: The condition used to trigger alerts.
  *   - reap_condition:  The condition used to trigger zombie reaping.
  */
@@ -45,6 +47,7 @@ extern "C" {
     f_thread_mutex_t print;
     f_thread_mutex_t reap;
 
+    f_thread_lock_t enable;
     f_thread_lock_t instance;
     f_thread_lock_t rule;
 
@@ -60,6 +63,7 @@ extern "C" {
     f_thread_mutex_t_initialize, \
     f_thread_lock_t_initialize, \
     f_thread_lock_t_initialize, \
+    f_thread_lock_t_initialize, \
     f_thread_condition_t_initialize, \
     f_thread_condition_t_initialize, \
   }
index 1d17bae5e9fc4ba1f36e65ceb9e987f2c3d9d1e4..0f11527668fac560888982202ae986fab26092db 100644 (file)
@@ -21,17 +21,12 @@ extern "C" {
  *
  * This is essentially data shared globally between threads, about threads.
  *
- * The "enabled" and "signal" utilize the lock: lock.process.
- *
- * The lock.alert must be used when writing to any of:
- *   - enabled.
- *
  * The typedef for this is located in the defs.h header.
  *
  * Properties:
- *   - enabled: F_true when threads are active, FALSE when inactive and the program is essentially shutting down, no new threads should be started when F_false.
- *   - signal:  The code of any signal received.
- *   - status:  A status used by the main entry/rule processing thread for synchronous operations.
+ *   - enable: F_true when threads are active, FALSE when inactive and the program is essentially shutting down, no new threads should be started when F_false.
+ *   - signal: The code of any signal received.
+ *   - status: A status used by the main entry/rule processing thread for synchronous operations.
  *
  *   - id_cleanup: The thread ID representing the Cleanup Process.
  *   - id_control: The thread ID representing the Control Process.
@@ -45,7 +40,7 @@ extern "C" {
  */
 #ifndef _di_controller_thread_t_
   struct controller_thread_t_ {
-    uint8_t enabled;
+    uint8_t enable;
     int signal;
     f_status_t status;
 
@@ -61,7 +56,7 @@ extern "C" {
   };
 
   #define controller_thread_t_initialize { \
-    controller_thread_enabled_e, \
+    controller_thread_enable_e, \
     0, \
     F_none, \
     f_thread_id_t_initialize, \
index d02031485a27b7b3fb76274d3843ca1ddaf8eb5a..f9a1362296911610f8484ff7bfe5f56213f07524 100644 (file)
 #include <program/controller/main/time.h>
 #include <program/controller/main/thread/cleanup.h>
 #include <program/controller/main/thread/control.h>
+#include <program/controller/main/thread/enable.h>
 #include <program/controller/main/thread/entry.h>
 #include <program/controller/main/thread/is.h>
 #include <program/controller/main/thread/instance.h>
index 07941cae992c3124e8f3be7724490fefc9c9aa88..3978e19c8c32e964bd646b8760f5623370eb8019 100644 (file)
@@ -109,7 +109,7 @@ extern "C" {
         f_number_unsigned_t at = 0;
         f_number_unsigned_t j = 0;
 
-        for (i = 0; i < main->thread.cache.object_items.used && controller_thread_is_enabled(&main->thread, is_entry); ++i) {
+        for (i = 0; i < main->thread.cache.object_items.used && controller_thread_enable_is(&main->thread, is_entry); ++i) {
 
           code &= ~0x2;
           at = 0;
@@ -266,7 +266,7 @@ extern "C" {
 
               for (j = 0; j < entry->items.array[i].actions.used; ++j) {
 
-                if (!controller_thread_is_enabled(&main->thread, is_entry)) {
+                if (!controller_thread_enable_is(&main->thread, is_entry)) {
                   entry->status = controller_status_simplify_error(F_interrupt);
 
                   return F_status_set_error(F_interrupt);
index 29a50ad70e27fec2311204a17b01e385114b0386..b87b5c390d749adf3c0b48e53ccc080a48d34320 100644 (file)
@@ -58,11 +58,11 @@ extern "C" {
       return status;
     }
 
-    while (controller_thread_is_enabled(&main->thread, is_entry)) {
+    while (controller_thread_enable_is(&main->thread, is_entry)) {
 
       actions = &entry->items.array[cache->ats.array[at_i]].actions;
 
-      for (; cache->ats.array[at_j] < actions->used && controller_thread_is_enabled(&main->thread, is_entry); ++cache->ats.array[at_j]) {
+      for (; cache->ats.array[at_j] < actions->used && controller_thread_enable_is(&main->thread, is_entry); ++cache->ats.array[at_j]) {
 
         cache->action.line_action = actions->array[cache->ats.array[at_j]].line;
         cache->action.name_action.used = 0;
@@ -91,7 +91,7 @@ extern "C" {
           else if (f_compare_dynamic(controller_settings_s, actions->array[cache->ats.array[at_j]].parameters.array[0]) == F_equal_to) continue;
 
           // Walk though each items and check to see if the item actually exists.
-          for (i = 1; i < entry->items.used && controller_thread_is_enabled(&main->thread, is_entry); ++i) {
+          for (i = 1; i < entry->items.used && controller_thread_enable_is(&main->thread, is_entry); ++i) {
 
             if (f_compare_dynamic(entry->items.array[i].name, actions->array[cache->ats.array[at_j]].parameters.array[0]) == F_equal_to) {
 
@@ -193,7 +193,7 @@ extern "C" {
       }
     } // while
 
-    if (!controller_thread_is_enabled(&main->thread, is_entry)) return F_status_set_error(F_interrupt);
+    if (!controller_thread_enable_is(&main->thread, is_entry)) return F_status_set_error(F_interrupt);
 
     // If ready is not found in the entry, then default to always ready.
     if (main->process.ready == controller_process_ready_no_e) {
index 5ddebb2d0428f1eaf942ba0cb9a73327b1184196..402bf48eefad3ff859ca2b8dd4fac6cbde53cc95 100644 (file)
@@ -16,8 +16,8 @@ extern "C" {
     uint8_t options_force = 0;
     uint8_t options_instance = 0;
 
-    controller_entry_t * const entry = is_entry ? &main->process.entry : &main->process.exit;
     controller_cache_t * const cache = &main->thread.cache;
+    controller_entry_t * const entry = is_entry ? &main->process.entry : &main->process.exit;
     controller_entry_action_t *entry_action = 0;
     controller_entry_actions_t *entry_actions = 0;
 
@@ -68,11 +68,11 @@ extern "C" {
       if (F_status_is_error(status)) return status;
     }
 
-    while (controller_thread_is_enabled(&main->thread, is_entry)) {
+    while (controller_thread_enable_is(&main->thread, is_entry)) {
 
       entry_actions = &entry->items.array[cache->ats.array[at_i]].actions;
 
-      for (; cache->ats.array[at_j] < entry_actions->used && controller_thread_is_enabled(&main->thread, is_entry); ++cache->ats.array[at_j]) {
+      for (; cache->ats.array[at_j] < entry_actions->used && controller_thread_enable_is(&main->thread, is_entry); ++cache->ats.array[at_j]) {
 
         entry_action = &entry_actions->array[cache->ats.array[at_j]];
 
@@ -188,7 +188,7 @@ extern "C" {
         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);
 
-          if (F_status_is_error(status_lock)) {
+          if (status_lock != F_okay) {
             controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false);
 
             break;
@@ -216,7 +216,7 @@ extern "C" {
 
           status_lock = controller_lock_read(is_entry, F_true, &main->thread, &main->thread.lock.rule);
 
-          if (F_status_is_error(status_lock)) {
+          if (status_lock != F_okay) {
             controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_true);
 
             break;
@@ -230,7 +230,7 @@ extern "C" {
             controller_print_message_entry_item_rule(&main->program.message, entry, entry_action, is_entry, alias_rule);
           }
 
-          if (!controller_thread_is_enabled(&main->thread, is_entry)) break;
+          if (!controller_thread_enable_is(&main->thread, is_entry)) break;
 
           // The Rule is not yet loaded, ensure that it is loaded.
           if (status != F_true) {
@@ -253,7 +253,7 @@ extern "C" {
 
             status_lock = controller_lock_write(is_entry, F_true, &main->thread, &main->thread.lock.rule);
 
-            if (F_status_is_fine(status_lock)) {
+            if (status_lock == F_okay) {
               status = controller_rule_read(main, cache, is_entry, alias_rule, entry, &main->process.rules.array[main->process.rules.used]);
             }
 
@@ -273,13 +273,13 @@ extern "C" {
             cache->action.line_action = cache_line_action;
             cache->action.line_item = cache_line_item;
 
-            if (F_status_is_error(status_lock)) {
+            if (status_lock != F_okay) {
               controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false);
 
               break;
             }
 
-            if (F_status_set_fine(status) == F_interrupt || !controller_thread_is_enabled(&main->thread, is_entry)) {
+            if (F_status_set_fine(status) == F_interrupt || !controller_thread_enable_is(&main->thread, is_entry)) {
               f_thread_unlock(&main->thread.lock.rule);
 
               break;
@@ -464,9 +464,9 @@ extern "C" {
       }
     } // while
 
-    if (!controller_thread_is_enabled(&main->thread, is_entry)) return F_status_set_error(F_interrupt);
+    if (!controller_thread_enable_is(&main->thread, is_entry)) return F_status_set_error(F_interrupt);
     if (status == F_child) return status;
-    if (F_status_is_error(status_lock)) return status_lock;
+    if (status_lock != F_okay) return status_lock;
 
     // Check to see if any required processes failed, but do not do this if already operating in failsafe.
     if (F_status_is_error_not(status) && !failsafe && !(main->setting.flag & controller_main_flag_validate_d) && main->process.mode != controller_process_mode_helper_e) {
index f0b1f51c922e044f9576ce31b02360d02db4aecc..7ad9a912a9ef47f5ab35bf58fe0a2f84ea98012d 100644 (file)
@@ -23,22 +23,6 @@ extern "C" {
   }
 #endif // _di_controller_instance_find_
 
-#ifndef _di_controller_instance_signal_wait_
-  f_status_t controller_instance_signal_wait(controller_instance_t * const instance) {
-
-    if (!instance) return F_status_set_error(F_parameter);
-
-    const f_status_t status = controller_lock_mutex(instance->type != controller_instance_type_exit_e, F_true, &instance->main->thread, &instance->wait);
-
-    if (status == F_okay) {
-      f_thread_condition_signal_all(&instance->wait_condition);
-      f_thread_mutex_unlock(&instance->wait);
-    }
-
-    return F_okay;
-  }
-#endif // _di_controller_instance_signal_wait_
-
 #ifdef __cplusplus
 } // extern "C"
 #endif
index f93771ef3e8e2af83e42ec78aa8cf5cdefdd4bb5..44a5acb0c96d6f4cb26268976f35c1fb30ce2165 100644 (file)
@@ -41,29 +41,6 @@ extern "C" {
   f_status_t controller_instance_find(const f_number_unsigned_t action, const f_string_static_t alias, const controller_instances_t instances, f_number_unsigned_t * const at);
 #endif // _di_controller_instance_find_
 
-/**
- * Send a signal to the wait condition.
- *
- * Used to inform all things waiting on a specific instance that the specific instance has finished running.
- *
- * @param instance
- *   The Controller Instance.
- *
- *   Must not be NULL.
- *
- * @return
- *   F_okay on success.
- *
- *   F_parameter (with error bit) if a parameter is invalid.
- *
- *   Errors (with error bit) from: controller_lock_mutex().
- *
- * @see controller_lock_mutex()
- */
-#ifndef _di_controller_instance_signal_wait_
-  extern f_status_t controller_instance_signal_wait(controller_instance_t * const instance);
-#endif // _di_controller_instance_signal_wait_
-
 #ifdef __cplusplus
 } // extern "C"
 #endif
index f1a2b85aca751a9ab878a8d0a96dd7b9e93cacc8..078f233745750adbc80e0e196aeff42fdede8be0 100644 (file)
@@ -16,7 +16,7 @@ extern "C" {
 
       status = controller_lock_write(is_normal, F_true, &main->thread, &main->thread.lock.instance);
 
-      if (F_status_is_error(status)) {
+      if (status != F_okay) {
         controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status), F_false);
       }
       else {
@@ -34,7 +34,7 @@ extern "C" {
 
           controller_instance_t * const instance = F_status_is_error_not(status) ? main->thread.instances.array[main->thread.instances.used] : 0;
 
-          if (F_status_is_error_not(status)) {
+          if (status == F_okay) {
             status = controller_lock_write(is_normal, F_true, &main->thread, &instance->lock);
           }
 
index 9bfe2d93479d9195865acc97900fe1cf5c47aa51..ebb4412e9f5bada21f73e74334b77ebc70e98a24 100644 (file)
@@ -21,29 +21,37 @@ extern "C" {
         status = f_thread_mutex_create(0, &lock->reap);
 
         if (F_status_is_error_not(status)) {
-          status = f_thread_lock_create(0, &lock->instance);
+          status = f_thread_lock_create(0, &lock->enable);
 
           if (F_status_is_error_not(status)) {
-            status = f_thread_lock_create(0, &lock->rule);
+            status = f_thread_lock_create(0, &lock->instance);
 
             if (F_status_is_error_not(status)) {
-              status = f_thread_condition_create(0, &lock->alert_condition);
+              status = f_thread_lock_create(0, &lock->rule);
 
               if (F_status_is_error_not(status)) {
-                status = f_thread_condition_create(0, &lock->reap_condition);
+                status = f_thread_condition_create(0, &lock->alert_condition);
+
+                if (F_status_is_error_not(status)) {
+                  status = f_thread_condition_create(0, &lock->reap_condition);
+
+                  if (F_status_is_error(status)) {
+                    f_thread_condition_delete(&lock->alert_condition);
+                  }
+                }
 
                 if (F_status_is_error(status)) {
-                  f_thread_condition_delete(&lock->alert_condition);
+                  f_thread_lock_delete(&lock->rule);
                 }
               }
 
               if (F_status_is_error(status)) {
-                f_thread_lock_delete(&lock->rule);
+                f_thread_lock_delete(&lock->instance);
               }
             }
 
             if (F_status_is_error(status)) {
-              f_thread_lock_delete(&lock->instance);
+              f_thread_lock_delete(&lock->enable);
             }
           }
 
@@ -90,14 +98,14 @@ extern "C" {
       status = f_thread_mutex_lock_timed(&time, mutex);
 
       if (status == F_time) {
-        if (check && !controller_thread_is_enabled(thread, is_normal)) return F_status_set_error(F_interrupt);
+        if (check && !controller_thread_enable_is(thread, is_normal)) return F_status_set_error(F_interrupt);
       }
-      else {
+      else if (status == F_okay) {
         break;
       }
     } // for
 
-    return status;
+    return F_okay;
   }
 #endif // _di_controller_lock_mutex_
 
@@ -126,14 +134,14 @@ extern "C" {
       status = f_thread_lock_read_timed(&time, lock);
 
       if (status == F_time) {
-        if (check && !controller_thread_is_enabled(thread, is_normal)) return F_status_set_error(F_interrupt);
+        if (check && !controller_thread_enable_is(thread, is_normal)) return F_status_set_error(F_interrupt);
       }
-      else {
+      else if (status == F_okay) {
         break;
       }
     } // for
 
-    return status;
+    return F_okay;
   }
 #endif // _di_controller_lock_read_
 
@@ -146,22 +154,6 @@ extern "C" {
   }
 #endif // _di_controller_lock_read_instance_
 
-#ifndef _di_controller_lock_signal_
-  f_status_t controller_lock_signal(f_thread_condition_t * const condition, f_thread_mutex_t * const mutex) {
-
-    if (!condition || !mutex) return F_status_set_error(F_parameter);
-
-    const f_status_t status = f_thread_mutex_lock(mutex);
-
-    if (status == F_okay) {
-      f_thread_condition_signal_all(condition);
-      f_thread_mutex_unlock(mutex);
-    }
-
-    return F_okay;
-  }
-#endif // _di_controller_lock_signal_
-
 #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) {
 
@@ -176,14 +168,14 @@ extern "C" {
       status = f_thread_lock_write_timed(&time, lock);
 
       if (status == F_time) {
-        if (check && !controller_thread_is_enabled(thread, is_normal)) return F_status_set_error(F_interrupt);
+        if (check && !controller_thread_enable_is(thread, is_normal)) return F_status_set_error(F_interrupt);
       }
-      else {
+      else if (status == F_okay) {
         break;
       }
     } // for
 
-    return status;
+    return F_okay;
   }
 #endif // _di_controller_lock_write_
 
index 9c3f72cb5c203bc52c6c1e2aab7597158d749431..6f53642aa715427890f8ef77d042f696ceeecbc4 100644 (file)
@@ -166,32 +166,6 @@ extern "C" {
 #endif // _di_controller_lock_read_instance_
 
 /**
- * Send a signal to the given condition.
- *
- * @param condition
- *   The condition to send the signal too.
- *
- *   Must not be NULL.
- *
- * @param mutex
- *   The mutex lock associated with the condition.
- *
- *   Must not be NULL.
- *
- * @return
- *   F_okay on success.
- *
- *   F_parameter (with error bit) if a parameter is invalid.
- *
- *   Errors (with error bit) from: controller_lock_mutex().
- *
- * @see controller_lock_mutex()
- */
-#ifndef _di_controller_lock_signal_
-  extern f_status_t controller_lock_signal(f_thread_condition_t * const condition, f_thread_mutex_t * const mutex);
-#endif // _di_controller_lock_signal_
-
-/**
  * Wait to get a write lock.
  *
  * Given a r/w lock, periodically check to see if main thread is disabled while waiting.
index 54cb4ed7328a45a7293db5542fe7f57f572196f7..57d4d426b2a9ba9d1b7245f9a29a70e64ef45709 100644 (file)
@@ -101,13 +101,13 @@ extern "C" {
     }
 
     // Only make the Rule and control threads available once any/all pre-processing is complete.
-    if (F_status_is_error_not(status) && status != F_failure && status != F_child && main->thread.enabled == controller_thread_enabled_e) {
+    if (F_status_is_error_not(status) && status != F_failure && status != F_child && controller_thread_enable_get(&main->thread) == controller_thread_enable_e) {
       if (!(main->setting.flag & controller_main_flag_validate_d)) {
 
         // Wait for the Entry thread to complete before starting the Rule thread.
         controller_thread_join(&main->thread.id_rule);
 
-        if (main->thread.enabled && main->process.mode == controller_process_mode_service_e) {
+        if (controller_thread_enable_get(&main->thread) > controller_thread_enable_not_e && main->process.mode == controller_process_mode_service_e) {
           status = f_thread_create(0, &main->thread.id_rule, &controller_thread_rule, (void *) main);
 
           if (F_status_is_error(status)) {
@@ -129,7 +129,7 @@ extern "C" {
       return;
     }
 
-    if (F_status_is_error_not(status) && status != F_failure && !(main->setting.flag & controller_main_flag_validate_d) && controller_thread_is_enabled(&main->thread, F_true)) {
+    if (F_status_is_error_not(status) && status != F_failure && !(main->setting.flag & controller_main_flag_validate_d) && controller_thread_enable_is(&main->thread, F_true)) {
       if (main->process.mode == controller_process_mode_service_e) {
         controller_thread_join(&main->thread.id_signal);
       }
index 6ccdcd27a72aa2e964378f59016c0ca0fe11bdf4..93b72cb34a426f7442a1cb3371056febfa07ef5a 100644 (file)
@@ -411,7 +411,7 @@ extern "C" {
 
       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);
-        if (F_status_is_error(status)) return F_status_set_error(F_lock_read);
+        if (status != F_okay) return F_status_set_error(F_lock_read);
 
         status = F_status_set_error(F_lock);
       }
@@ -435,12 +435,14 @@ extern "C" {
 
     if (!instance || !instance->main) return F_status_set_error(F_parameter);
 
-    f_status_t status = F_okay;
-
     controller_t * const main = instance->main;
-
+    f_status_t status = F_okay;
     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);
+    //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);
 
     if (F_status_is_error(status)) {
@@ -449,7 +451,7 @@ extern "C" {
       return status;
     }
 
-    pid_t * const process_child_id = controller_rule_execute_next_child(instance);
+    pid_t * const process_child_id = controller_rule_execute_next_child(instance); // @fixme should be included in write lock.
 
     if (options & controller_instance_option_simulate_e) {
       controller_print_entry_output_execute_simulate(&main->program.output, instance, program, arguments);
@@ -490,7 +492,7 @@ extern "C" {
         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);
-        if (F_status_is_error(status_lock)) return F_status_set_error(F_lock_read);
+        if (status_lock != F_okay) return F_status_set_error(F_lock_read);
 
         return F_status_set_error(F_lock);
       }
@@ -504,14 +506,14 @@ extern "C" {
 
       status_lock = controller_lock_read_instance(instance, &instance->lock);
 
-      if (F_status_is_error(status_lock)) {
+      if (status_lock != F_okay) {
 
         // 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);
         }
 
-        if (F_status_is_error(status_lock)) {
+        if (status_lock != F_okay) {
           controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_true);
 
           return F_status_set_error(F_lock_read);
@@ -599,10 +601,14 @@ extern "C" {
 
     if (!execute_set || !instance || !instance->main) return F_status_set_error(F_parameter);
 
-    f_status_t status = F_okay;
     controller_t * const main = instance->main;
+    f_status_t status = F_okay;
     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);
+    //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);
 
     if (F_status_is_error_not(status)) {
@@ -615,7 +621,7 @@ extern "C" {
       return status;
     }
 
-    pid_t * const process_child_id = controller_rule_execute_next_child(instance);
+    pid_t * const process_child_id = controller_rule_execute_next_child(instance); // @fixme should be included in write lock.
     f_string_dynamic_t * const process_child_pid_file = controller_rule_execute_next_pid_path(instance);
 
     status = f_file_exists(pid_file, F_true);
@@ -676,11 +682,11 @@ extern "C" {
 
       f_status_t status_lock = controller_lock_write_instance(instance, &instance->lock);
 
-      if (F_status_is_error(status_lock)) {
+      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);
-        if (F_status_is_error(status_lock)) return F_status_set_error(F_lock_read);
+        if (status_lock != F_okay) return F_status_set_error(F_lock_read);
 
         return F_status_set_error(F_lock);
       }
@@ -701,11 +707,11 @@ extern "C" {
 
       status_lock = controller_lock_write_instance(instance, &instance->lock);
 
-      if (F_status_is_error(status_lock)) {
+      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);
-        if (F_status_is_error(status_lock)) return F_status_set_error(F_lock_read);
+        if (status_lock != F_okay) return F_status_set_error(F_lock_read);
 
         return F_status_set_error(F_lock);
       }
index a2b5f2c347f807ce6a05c25f95aa5bb49f232418..932c0871da08b0ad1ef5c2c4e9c76c8d659f4259 100644 (file)
@@ -136,7 +136,7 @@ extern "C" {
 
           status_lock = controller_lock_read_instance(instance, &main->thread.lock.instance);
 
-          if (F_status_is_error(status_lock)) {
+          if (status_lock != F_okay) {
             controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_true);
           }
           else {
@@ -365,7 +365,7 @@ extern "C" {
 
       // Find at least one of the requested Action when the Rule is required.
       if (instance->options & controller_instance_option_require_e) {
-        bool missing = F_true;
+        uint8_t missing = F_true;
         f_number_unsigned_t j = 0;
 
         for (i = 0; i < instance->rule.items.used; ++i) {
@@ -408,7 +408,7 @@ extern "C" {
       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);
-      if (F_status_is_error(status_lock)) return F_status_set_error(F_lock_read);
+      if (status_lock != F_okay) return F_status_set_error(F_lock_read);
 
       return F_status_set_error(F_lock);
     }
@@ -429,7 +429,7 @@ extern "C" {
       f_thread_unlock(&instance->lock);
 
       status_lock = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock);
-      if (F_status_is_error(status_lock)) return F_status_set_error(F_lock_read);
+      if (status_lock != F_okay) return F_status_set_error(F_lock_read);
 
       return F_status_set_error(F_lock);
     }
@@ -460,7 +460,7 @@ extern "C" {
       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);
-      if (F_status_is_error(status_lock)) return F_status_set_error(F_lock_read);
+      if (status_lock != F_okay) return F_status_set_error(F_lock_read);
 
       return F_status_set_error(F_lock);
     }
@@ -477,7 +477,7 @@ extern "C" {
 
     f_status_t status = controller_lock_read(type != controller_instance_type_exit_e, F_true, &main->thread, &main->thread.lock.instance);
 
-    if (F_status_is_error(status)) {
+    if (status != F_okay) {
       controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status), F_true);
 
       return status;
@@ -499,7 +499,7 @@ extern "C" {
 
     status = controller_lock_read(type != controller_instance_type_exit_e, F_true, &main->thread, &instance->active);
 
-    if (F_status_is_error(status)) {
+    if (status != F_okay) {
       controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status), F_true);
       controller_print_error_rule_item(&main->program.error, &cache->action, F_false, F_status_set_fine(status));
 
@@ -533,7 +533,7 @@ extern "C" {
     // The thread is done, so close the thread.
     if (instance->state == controller_instance_state_done_e) {
       controller_thread_join(&instance->id_thread);
-      controller_instance_signal_wait(instance);
+      f_thread_condition_signal_all(&instance->wait_condition);
     }
 
     instance->id = at;
@@ -661,7 +661,7 @@ extern "C" {
         instance->state = controller_instance_state_idle_e;
       }
 
-      controller_instance_signal_wait(instance);
+      f_thread_condition_signal_all(&instance->wait_condition);
 
       f_thread_unlock(&instance->lock);
     }
@@ -700,7 +700,7 @@ extern "C" {
     f_status_t status_lock = F_okay;
 
     // The instance and active locks shall be held for the duration of this instanceing (aside from switching between read to/from write).
-    if (options_force & controller_instance_option_asynchronous_e) {
+    if (options_force & controller_instance_option_asynchronous_e) { // @fixme are all of these async "active" locks save/valid?
       status_lock = controller_lock_read_instance(instance, &instance->active);
 
       if (F_status_is_error(status_lock)) {
@@ -906,7 +906,7 @@ extern "C" {
     instance->state = (options_force & controller_instance_option_asynchronous_e) ? controller_instance_state_done_e : controller_instance_state_idle_e;
     instance->stack.used = used_original_stack;
 
-    controller_instance_signal_wait(instance);
+    f_thread_condition_signal_all(&instance->wait_condition);
     f_thread_unlock(&instance->lock);
     private_controller_rule_instance_perform_unlock_active(instance, options_force);
 
index 7be4247e2cc9ce7697eb5a9903587a0addd8a771..93ecae2e055a9959ea3f7a3dd8c55741fa5e1a2c 100644 (file)
@@ -11,7 +11,7 @@ extern "C" {
 
     f_status_t status_lock = controller_lock_read(is_normal, F_false, &main->thread, &main->thread.lock.instance);
 
-    if (F_status_is_error(status_lock)) {
+    if (status_lock != F_okay) {
       controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_true);
 
       return status_lock;
@@ -42,11 +42,11 @@ extern "C" {
 
     for (i = 0; i < instance_total; ++i) {
 
-      if (!controller_thread_is_enabled(&main->thread, is_normal)) break;
+      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);
-      if (F_status_is_error(status_lock)) break;
+      if (status_lock != F_okay) break;
 
       if (!instance_list[i]) {
         f_thread_unlock(&main->thread.lock.instance);
@@ -56,7 +56,7 @@ extern "C" {
 
       status_lock = controller_lock_read(is_normal, F_true, &main->thread, &instance_list[i]->active);
 
-      if (F_status_is_error(status_lock)) {
+      if (status_lock != F_okay) {
         f_thread_unlock(&main->thread.lock.instance);
 
         break;
@@ -67,7 +67,7 @@ extern "C" {
 
       status_lock = controller_lock_read(is_normal, F_true, &main->thread, &instance_list[i]->lock);
 
-      if (F_status_is_error(status_lock)) {
+      if (status_lock != F_okay) {
         f_thread_unlock(&instance_list[i]->active);
 
         break;
@@ -89,7 +89,7 @@ extern "C" {
 
           status_lock = controller_lock_write(is_normal, F_true, &main->thread, &instance_list[i]->lock);
 
-          if (F_status_is_error(status_lock)) {
+          if (status_lock != F_okay) {
             controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false);
 
             f_thread_unlock(&instance_list[i]->active);
@@ -106,12 +106,12 @@ extern "C" {
               instance_list[i]->state = controller_instance_state_idle_e;
 
               f_thread_unlock(&instance_list[i]->active);
-              controller_instance_signal_wait(instance_list[i]);
+              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);
 
-            if (F_status_is_error(status_lock)) {
+            if (status_lock != F_okay) {
               f_thread_unlock(&instance_list[i]->lock);
 
               break;
@@ -121,7 +121,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);
-          if (F_status_is_error(status_lock)) break;
+          if (status_lock != F_okay) break;
         }
 
         if (instance_list[i]->options & controller_instance_option_require_e) {
@@ -159,7 +159,7 @@ extern "C" {
 
         status_lock = controller_lock_read(is_normal, F_true, &main->thread, &instance_list[i]->lock);
 
-        if (F_status_is_error(status_lock)) {
+        if (status_lock != F_okay) {
           f_thread_unlock(&instance_list[i]->active);
 
           break;
@@ -195,7 +195,7 @@ extern "C" {
       return status_lock;
     }
 
-    if (!controller_thread_is_enabled(&main->thread, is_normal)) return F_status_set_error(F_interrupt);
+    if (!controller_thread_enable_is(&main->thread, is_normal)) return F_status_set_error(F_interrupt);
     if (F_status_set_fine(status) == F_require) return status;
     if (required_not_run) return F_require;
 
index 108bf998332a4239dc9cac8b41c33fdf6eceb0c1..09468d65f1e0933bc44ca94b935e9f18fec2006b 100644 (file)
@@ -17,9 +17,10 @@ extern "C" {
     f_time_spec_t delay = f_time_spec_t_initialize;
     siginfo_t signal_data;
     uint8_t reap_count = 0;
+    uint8_t enable = controller_thread_enable_none_e;
     f_status_t status = F_okay;
 
-    while (main->thread.enabled == controller_thread_enabled_e) {
+    while (controller_thread_enable_get(&main->thread) == controller_thread_enable_e) {
 
       controller_time_now(
         main->setting.flag & controller_main_flag_simulate_d
@@ -65,8 +66,10 @@ extern "C" {
         } while (F_false);
       }
 
-      if (main->thread.enabled != controller_thread_enabled_e) {
-        if (main->thread.enabled == controller_thread_enabled_exit_e) continue;
+      enable = controller_thread_enable_get(&main->thread);
+
+      if (enable != controller_thread_enable_e) {
+        if (enable == controller_thread_enable_exit_e) continue;
 
         break;
       }
@@ -76,32 +79,57 @@ extern "C" {
 
         f_number_unsigned_t i = 0;
 
-        for (status = F_okay; i < main->thread.instances.size && main->thread.enabled == controller_thread_enabled_e; ++i) {
+        for (status = F_okay; i < main->thread.instances.used && controller_thread_enable_get(&main->thread) == controller_thread_enable_e; ++i) {
 
           if (!main->thread.instances.array[i]) continue;
 
-          if (i >= main->thread.instances.used) {
-            status = controller_instance_initialize(&main->thread.instances.array[i]);
-          }
-
           instance = main->thread.instances.array[i];
 
+          {
+            f_time_spec_t time;
+
+            do {
+              if (controller_thread_enable_get(&main->thread) != controller_thread_enable_e) {
+                status = F_enable_not;
+
+                break;
+              }
+
+              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)) break;
+
+            } while (status != F_okay);
+
+            if (status == F_enable_not) break;
+            if (F_status_is_error(status)) continue;
+          }
+
           // If "active" has a read or write lock, then do not attempt to clean it.
-          if (f_thread_lock_write_try(&instance->active) != F_okay) continue;
+          if (f_thread_lock_write_try(&instance->active) != F_okay) {
+            f_thread_mutex_unlock(&main->thread.lock.cancel);
+
+            continue;
+          }
 
           // If "lock" has a read or write lock, then do not attempt to clean it.
           if (f_thread_lock_write_try(&instance->lock) != F_okay) {
             f_thread_unlock(&instance->active);
+            f_thread_mutex_unlock(&main->thread.lock.cancel);
 
             continue;
           }
 
           // If instance is active or busy, then do not attempt to clean it.
-          if (instance->state == controller_instance_state_active_e || instance->state == controller_instance_state_busy_e || main->thread.enabled != controller_thread_enabled_e) {
+          if (instance->state == controller_instance_state_active_e || instance->state == controller_instance_state_busy_e || controller_thread_enable_get(&main->thread) != controller_thread_enable_e) {
             f_thread_unlock(&instance->lock);
             f_thread_unlock(&instance->active);
+            f_thread_mutex_unlock(&main->thread.lock.cancel);
 
-            if (main->thread.enabled == controller_thread_enabled_e) continue;
+            if (controller_thread_enable_get(&main->thread) == controller_thread_enable_e) continue;
 
             break;
           }
@@ -110,18 +138,19 @@ extern "C" {
           if (instance->path_pids.used) {
             f_number_unsigned_t j = 0;
 
-            for (; j < instance->path_pids.used && main->thread.enabled == controller_thread_enabled_e; ++j) {
+            for (; j < instance->path_pids.used && controller_thread_enable_get(&main->thread) == controller_thread_enable_e; ++j) {
 
               if (instance->path_pids.array[j].used && f_file_exists(instance->path_pids.array[j], F_true) == F_true) {
                 break;
               }
             } // for
 
-            if (j < instance->path_pids.used || main->thread.enabled != controller_thread_enabled_e) {
+            if (j < instance->path_pids.used || controller_thread_enable_get(&main->thread) != controller_thread_enable_e) {
               f_thread_unlock(&instance->lock);
               f_thread_unlock(&instance->active);
+              f_thread_mutex_unlock(&main->thread.lock.cancel);
 
-              if (main->thread.enabled == controller_thread_enabled_e) continue;
+              if (controller_thread_enable_get(&main->thread) == controller_thread_enable_e) continue;
 
               break;
             }
@@ -135,11 +164,12 @@ extern "C" {
               instance->state = controller_instance_state_idle_e;
               instance->id_thread = 0;
 
-              controller_instance_signal_wait(instance);
+              f_thread_condition_signal_all(&instance->wait_condition);
             }
             else {
               f_thread_unlock(&instance->lock);
               f_thread_unlock(&instance->active);
+              f_thread_mutex_unlock(&main->thread.lock.cancel);
 
               continue;
             }
@@ -151,11 +181,11 @@ extern "C" {
 
           // Shrink the childs array.
           if (instance->childs.used) {
-            for (; instance->childs.used && main->thread.enabled == controller_thread_enabled_e; --instance->childs.used) {
+            for (; instance->childs.used && controller_thread_enable_get(&main->thread) == controller_thread_enable_e; --instance->childs.used) {
               if (instance->childs.array[instance->childs.used]) break;
             } // for
 
-            if (main->thread.enabled != controller_thread_enabled_e) {
+            if (controller_thread_enable_get(&main->thread) != controller_thread_enable_e) {
               f_thread_unlock(&instance->lock);
               f_thread_unlock(&instance->active);
 
@@ -181,6 +211,7 @@ extern "C" {
 
           f_thread_unlock(&instance->lock);
           f_thread_unlock(&instance->active);
+          f_thread_mutex_unlock(&main->thread.lock.cancel);
         } // for
 
         f_thread_unlock(&main->thread.lock.instance);
index cd2f222a43c60eb2a7fc23250cc92d829a816f26..1241d06b0b24ea952feca30d1c98ed7ba95732de 100644 (file)
@@ -14,7 +14,7 @@ extern "C" {
 
     controller_t * const main = (controller_t *) argument;
 
-    if (main->thread.enabled != controller_thread_enabled_e) return 0;
+    if (controller_thread_enable_get(&main->thread) != controller_thread_enable_e) return 0;
 
     f_status_t status = F_okay;
 
diff --git a/sources/c/program/controller/main/thread/enable.c b/sources/c/program/controller/main/thread/enable.c
new file mode 100644 (file)
index 0000000..84ae16b
--- /dev/null
@@ -0,0 +1,66 @@
+#include "../controller.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_controller_thread_enable_get_
+  uint8_t controller_thread_enable_get(controller_thread_t * const thread) {
+
+    if (!thread) return controller_thread_enable_none_e;
+
+    if (f_thread_lock_read_try(&thread->lock.enable) != F_okay) {
+      for (f_time_spec_t time; ; ) {
+
+        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);
+        if (f_thread_lock_read_timed(&time, &thread->lock.enable) == F_okay) break;
+      } // for
+    }
+
+    const uint8_t enable = thread->enable;
+
+    f_thread_unlock(&thread->lock.enable);
+
+    return enable;
+  }
+#endif // _di_controller_thread_enable_get_
+
+#ifndef _di_controller_thread_enable_is_
+  f_status_t controller_thread_enable_is(controller_thread_t * const thread, const uint8_t is_normal) {
+
+    if (!thread) return F_false;
+
+    const uint8_t enable = controller_thread_enable_get(thread);
+
+    return is_normal ? enable == controller_thread_enable_e : enable;
+  }
+#endif // _di_controller_thread_enable_is_
+
+#ifndef _di_controller_thread_enable_set_
+  f_status_t controller_thread_enable_set(controller_thread_t * const thread, const uint8_t value) {
+
+    if (!thread) return F_status_set_error(F_parameter);
+
+    if (f_thread_lock_write_try(&thread->lock.enable) != F_okay) {
+      for (f_time_spec_t time; ; ) {
+
+        memset(&time, 0, sizeof(f_time_spec_t));
+
+        controller_time_now(controller_thread_timeout_lock_write_seconds_d, controller_thread_timeout_lock_write_nanoseconds_d, &time);
+        if (f_thread_lock_write_timed(&time, &thread->lock.enable) == F_okay) break;
+      } // for
+    }
+
+    thread->enable = value;
+
+    f_thread_unlock(&thread->lock.enable);
+
+    return F_okay;
+  }
+#endif // _di_controller_thread_enable_set_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/sources/c/program/controller/main/thread/enable.h b/sources/c/program/controller/main/thread/enable.h
new file mode 100644 (file)
index 0000000..9baa00b
--- /dev/null
@@ -0,0 +1,106 @@
+/**
+ * FLL - Level 3
+ *
+ * Project: Controller
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the thread "enable" functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _controller_main_thread_enable_h
+#define _controller_main_thread_enable_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Get the enable state of the system in a thread-safe manner.
+ *
+ * This infinitely tries to obtain the read lock.
+ *
+ * Locks used on run:
+ *   - main.thread.lock.enable (read lock).
+ *
+ * Locks held on exit:
+ *   - None.
+ *
+ * @param thread
+ *   The thread data.
+ *
+ *   Must not be NULL.
+ *
+ * @return
+ *   The enable status on success.
+ *
+ *   controller_thread_enable_none_e on any error.
+ *
+ * @see controller_time_now()
+ *
+ * @see f_thread_lock_read_timed()
+ * @see f_thread_lock_read_try()
+ * @see f_thread_unlock()
+ */
+#ifndef _di_controller_thread_enable_get_
+  extern uint8_t controller_thread_enable_get(controller_thread_t * const thread);
+#endif // _di_controller_thread_enable_get_
+
+/**
+ * Check to see if thread is enabled for the normal operations like Entry and Control or for Exit operations in a thread-safe manner.
+ *
+ * @param thread
+ *   The thread data.
+ *
+ *   Must not be NULL.
+ * @param is_normal
+ *   If TRUE, then instance as if this operates during a normal operation (Entry and Control).
+ *   If FALSE, then instance as if this operates during an Exit operation.
+ *
+ * @return
+ *   F_true when enabled.
+ *   F_false when disabled.
+ *
+ * @see controller_thread_enable_get()
+ */
+#ifndef _di_controller_thread_enable_is_
+  extern f_status_t controller_thread_enable_is(controller_thread_t * const thread, const uint8_t is_normal);
+#endif // _di_controller_thread_enable_is_
+
+/**
+ * Set the enable state of the system in a thread-safe manner.
+ *
+ * This infinitely tries to obtain the write lock.
+ *
+ * Locks used on run:
+ *   - main.thread.lock.enable (write lock).
+ *
+ * Locks held on exit:
+ *   - None.
+ *
+ * @param thread
+ *   The thread data.
+ *
+ *   Must not be NULL.
+ * @param value
+ *   The new value to assign to the thread enable.
+ *
+ * @return
+ *   F_okay on success.
+ *
+ *   F_parameter (with error bit) if a parmeter is invalid.
+ *
+ * @see f_thread_lock_write_timed()
+ * @see f_thread_lock_write_try()
+ * @see f_thread_unlock()
+ */
+#ifndef _di_controller_thread_enable_set_
+  extern f_status_t controller_thread_enable_set(controller_thread_t * const thread, const uint8_t value);
+#endif // _di_controller_thread_enable_set_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _controller_main_thread_enable_h
index c484f686ac6d0a8ae17950ebfb5eed47b3de1892..11b7c56e08389ed4502e246f09972113cef040ec 100644 (file)
@@ -14,7 +14,7 @@ extern "C" {
 
     controller_t * const main = (controller_t *) argument;
 
-    if (!controller_thread_is_enabled(&main->thread, F_true)) return 0;
+    if (!controller_thread_enable_is(&main->thread, F_true)) return 0;
 
     f_status_t * const status = &main->thread.status;
 
@@ -49,16 +49,9 @@ extern "C" {
             main->process.ready = controller_process_ready_fail_e;
 
             if ((F_status_set_fine(*status) == F_execute || F_status_set_fine(*status) == F_require) && (main->process.flag & controller_process_flag_failsafe_e)) {
-              const uint8_t original_enabled = main->thread.enabled;
+              const uint8_t original_enabled = controller_thread_enable_get(&main->thread);
 
-              // Restore operating mode so that the failsafe can execute.
-              *status = f_thread_mutex_lock(&main->thread.lock.alert);
-
-              if (F_status_is_error_not(*status)) {
-                main->thread.enabled = controller_thread_enabled_e;
-
-                f_thread_mutex_unlock(&main->thread.lock.alert);
-              }
+              controller_thread_enable_set(&main->thread, controller_thread_enable_e);
 
               // Restart the signal main->thread to allow for signals while operating the failsafe Items.
               if (!main->thread.id_signal) {
@@ -73,15 +66,7 @@ extern "C" {
                 controller_print_error_failsafe_item(&main->program.error, &main->thread, main->process.entry.items.array[main->process.failsafe_item_id].name);
               }
               else {
-
-                // Restore operating mode to value prior to failsafe mode.
-                *status = f_thread_mutex_lock(&main->thread.lock.alert);
-
-                if (F_status_is_error_not(*status)) {
-                  main->thread.enabled = original_enabled;
-
-                  f_thread_mutex_unlock(&main->thread.lock.alert);
-                }
+                controller_thread_enable_set(&main->thread, original_enabled);
 
                 *status = F_failure;
               }
@@ -113,7 +98,7 @@ extern "C" {
       // According to the manpages, pthread_exit() calls exit(0), which the value of main->program.child should be returned instead.
       if (main->program.child) exit(main->program.child);
     } else {
-      controller_lock_signal(&main->thread.lock.alert_condition, &main->thread.lock.alert);
+      f_thread_condition_signal_all(&main->thread.lock.alert_condition);
     }
 
     return 0;
@@ -159,17 +144,11 @@ extern "C" {
 
           if ((F_status_set_fine(*status) == F_execute || F_status_set_fine(*status) == F_require) && (main->process.flag & controller_process_flag_failsafe_e)) {
 
-            const uint8_t original_enabled = main->thread.enabled;
+            const uint8_t original_enabled = controller_thread_enable_get(&main->thread);
 
             // Restore operating mode so that the failsafe can execute.
             if (F_status_set_fine(*status) == F_execute) {
-              *status = f_thread_mutex_lock(&main->thread.lock.alert);
-
-              if (F_status_is_error_not(*status)) {
-                main->thread.enabled = controller_thread_enabled_exit_e;
-
-                f_thread_mutex_unlock(&main->thread.lock.alert);
-              }
+              controller_thread_enable_set(&main->thread, controller_thread_enable_exit_e);
 
               // Restart the signal thread to allow for signals while operating the failsafe Items.
               if (!main->thread.id_signal) {
@@ -185,15 +164,7 @@ extern "C" {
               controller_print_error_failsafe_item(&main->program.error, &main->thread, main->process.entry.items.array[main->process.failsafe_item_id].name);
             }
             else {
-
-              // Restore operating mode to value prior to failsafe mode.
-              *status = f_thread_mutex_lock(&main->thread.lock.alert);
-
-              if (F_status_is_error_not(*status)) {
-                main->thread.enabled = original_enabled;
-
-                f_thread_mutex_unlock(&main->thread.lock.alert);
-              }
+              controller_thread_enable_set(&main->thread, original_enabled);
 
               *status = F_failure;
             }
@@ -214,8 +185,9 @@ extern "C" {
       controller_delete(main);
     }
     else {
-      controller_thread_instance_force_set_disable(main);
-      controller_lock_signal(&main->thread.lock.alert_condition, &main->thread.lock.alert);
+      controller_thread_enable_set(&main->thread, controller_thread_enable_not_e);
+
+      f_thread_condition_signal_all(&main->thread.lock.alert_condition);
     }
 
     return 0;
index fba2a57b03a5f81d4133f23dabb395f7b45098f1..96d357c7ccc7449aa9cf1609e8bfc1af19ab017f 100644 (file)
@@ -8,7 +8,7 @@ extern "C" {
   void controller_thread_instance(controller_instance_t * const instance, const uint8_t is_normal) {
 
     if (!instance || !instance->main) return;
-    if (!controller_thread_is_enabled(&instance->main->thread, is_normal)) return;
+    if (!controller_thread_enable_is(&instance->main->thread, is_normal)) return;
 
     const f_status_t status = controller_rule_instance_perform(instance, controller_instance_option_asynchronous_e);
 
@@ -34,7 +34,7 @@ extern "C" {
       f_time_spec_t time;
 
       do {
-        if (!controller_thread_is_enabled(&main->thread, is_normal)) return;
+        if (!controller_thread_enable_is(&main->thread, is_normal)) return;
 
         memset((void *) &time, 0, sizeof(struct timespec));
 
@@ -43,13 +43,13 @@ extern "C" {
         status = f_thread_mutex_lock_timed(&time, &main->thread.lock.cancel);
         if (F_status_is_error(status)) return;
 
-      } while (status == F_time);
+      } while (status != F_okay);
 
       status = F_okay;
     }
 
     // Only cancel when enabled.
-    if (!controller_thread_is_enabled(&main->thread, is_normal)) {
+    if (!controller_thread_enable_is(&main->thread, is_normal)) {
       f_thread_mutex_unlock(&main->thread.lock.cancel);
 
       return;
@@ -85,28 +85,20 @@ extern "C" {
       } // for
     }
 
-    for (f_number_unsigned_t i = 0; i < controller_lock_mutex_max_retry_d; ++i) {
-
-      status = f_thread_mutex_lock(&main->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
+    {
+      uint8_t enable = controller_thread_enable_exit_e;
 
-    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) {
-        main->thread.enabled = controller_thread_enabled_execute_e;
+        enable = controller_thread_enable_execute_e;
       }
       else if (by == controller_thread_cancel_exit_e) {
-        main->thread.enabled = controller_thread_enabled_not_e;
+        enable = controller_thread_enable_not_e;
       }
       else if (by == controller_thread_cancel_exit_execute_e) {
-        main->thread.enabled = controller_thread_enabled_exit_execute_e;
-      }
-      else {
-        main->thread.enabled = controller_thread_enabled_exit_e;
+        enable = controller_thread_enable_exit_execute_e;
       }
 
-      f_thread_mutex_unlock(&main->thread.lock.alert);
+      controller_thread_enable_set(&main->thread, enable);
     }
 
     if (main->thread.id_cleanup) {
@@ -144,7 +136,7 @@ extern "C" {
       instance = main->thread.instances.array[i];
 
       // Do not cancel Exit Instances, when not performing "execute" during exit.
-      if (instance->type == controller_instance_type_exit_e && main->thread.enabled != controller_thread_enabled_exit_execute_e) {
+      if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) {
         continue;
       }
 
@@ -177,7 +169,7 @@ extern "C" {
         instance = main->thread.instances.array[i];
 
         // Do not wait for Instances, when not performing "execute" during exit.
-        if (instance->type == controller_instance_type_exit_e && main->thread.enabled != controller_thread_enabled_exit_execute_e) {
+        if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) {
           continue;
         }
 
@@ -238,7 +230,7 @@ extern "C" {
       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 && main->thread.enabled != controller_thread_enabled_exit_execute_e) continue;
+      if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) continue;
 
       if (instance->id_thread) {
         if (instance->childs.used) {
@@ -266,7 +258,7 @@ extern "C" {
         for (j = 0; j < instance->childs.size; ++j) {
 
           // Do not kill Exit processes, when not performing "execute" during exit.
-          if (instance->type == controller_instance_type_exit_e && main->thread.enabled != controller_thread_enabled_exit_execute_e) continue;
+          if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) continue;
 
           if (instance->childs.array[j]) {
 
@@ -284,7 +276,7 @@ extern "C" {
         for (j = 0; j < instance->path_pids.used; ++j) {
 
           // Do not kill Exit processes, when not performing "execute" during exit.
-          if (instance->type == controller_instance_type_exit_e && main->thread.enabled != controller_thread_enabled_exit_execute_e) continue;
+          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);
@@ -303,7 +295,7 @@ extern "C" {
       while (instance->childs.used) {
 
         // Do not shrink below an Exit Instances, when not performing "execute" during exit.
-        if (instance->type == controller_instance_type_exit_e && main->thread.enabled != controller_thread_enabled_exit_execute_e) break;
+        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;
 
         --instance->childs.used;
@@ -313,7 +305,7 @@ extern "C" {
       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 && main->thread.enabled != controller_thread_enabled_exit_execute_e) break;
+        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;
@@ -327,7 +319,7 @@ extern "C" {
 #ifndef _di_controller_thread_instance_exit_
   void controller_thread_instance_exit(controller_t * const main) {
 
-    if (!main || main->thread.enabled != controller_thread_enabled_exit_e) return;
+    if (!main || controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_e) return;
 
     if (main->process.ready == controller_process_ready_done_e) {
 
@@ -356,7 +348,7 @@ extern "C" {
           controller_print_error_status(&main->program.error, macro_controller_f(f_thread_create), F_status_set_fine(status));
         }
 
-        controller_thread_instance_force_set_disable(main);
+        controller_thread_enable_set(&main->thread, controller_thread_enable_not_e);
       }
       else {
         f_time_spec_t time = f_time_spec_t_initialize;
@@ -371,9 +363,9 @@ extern "C" {
 
           f_thread_mutex_unlock(&main->thread.lock.alert);
 
-        } while (F_status_is_error_not(status) && main->thread.enabled == controller_thread_enabled_exit_e);
+        } while (F_status_is_error_not(status) && controller_thread_enable_get(&main->thread) == controller_thread_enable_exit_e);
 
-        if (F_status_is_error(status)) controller_thread_instance_force_set_disable(main);
+        if (F_status_is_error(status)) controller_thread_enable_set(&main->thread, controller_thread_enable_not_e);
       }
 
       // The sigtimedwait() function that is run inside of signal must be interrupted directly via f_thread_signal_write().
@@ -387,46 +379,11 @@ extern "C" {
       controller_thread_instance_cancel(main, F_false, controller_thread_cancel_exit_e);
     }
     else {
-      controller_thread_instance_force_set_disable(main);
+      controller_thread_enable_set(&main->thread, controller_thread_enable_not_e);
     }
   }
 #endif // _di_controller_thread_instance_exit_
 
-#ifndef _di_controller_thread_instance_force_set_disable_
-  void controller_thread_instance_force_set_disable(controller_t * const main) {
-
-    if (!main) return;
-
-    if (F_status_is_error_not(f_thread_mutex_lock(&main->thread.lock.alert))) {
-      main->thread.enabled = controller_thread_enabled_not_e;
-
-      f_thread_mutex_unlock(&main->thread.lock.alert);
-
-      return;
-    }
-
-    f_time_spec_t time;
-
-    for (uint8_t i = 0; i < controller_thread_exit_disable_force_times; ++i) {
-
-      memset((void *) &time, 0, sizeof(struct timespec));
-
-      controller_time_now(controller_thread_timeout_exit_disable_force_seconds_d, controller_thread_timeout_exit_disable_force_nanoseconds_d, &time);
-
-      if (F_status_is_error_not(f_thread_mutex_lock_timed(&time, &main->thread.lock.alert))) {
-        main->thread.enabled = controller_thread_enabled_not_e;
-
-        f_thread_mutex_unlock(&main->thread.lock.alert);
-
-        return;
-      }
-    } // for
-
-    // Forcibly set disable regardless of the risk.
-    main->thread.enabled = controller_thread_enabled_not_e;
-  }
-#endif // _di_controller_thread_instance_force_set_disable_
-
 #ifndef _di_controller_thread_instance_normal_
   void * controller_thread_instance_normal(void * const argument) {
 
index 1215decf3cf1896abb636b9f3dcd6a4f701b9360..f8a3f3abd126bc5100c3dd30a64082c3466f9fa0 100644 (file)
@@ -71,28 +71,6 @@ extern "C" {
 #endif // _di_controller_thread_instance_exit_
 
 /**
- * Set the execution state to disabled during exiting and force the case if need be.
- *
- * The program must exit during the Exit process.
- * The state must be properly set.
- * Perform a limited number of attempts to set the state to exiting.
- * Should this fail, then force the case regardless of the risk.
- *
- * @param main
- *   The main program data.
- *
- *   Must not be NULL.
- *
- *   This does not alter main.setting.state.status.
- *
- *   The main.thread.lock.alert lock will be set and then unset if possible.
- *   The main.thread.enabled will be updated and set to controller_thread_enabled_not_e.
- */
-#ifndef _di_controller_thread_instance_force_set_disable_
-  extern void controller_thread_instance_force_set_disable(controller_t * const main);
-#endif // _di_controller_thread_instance_force_set_disable_
-
-/**
  * Asynchronously execute a Rule process during normal operations.
  *
  * @param argument
index 577d2e2b9b4fc665ccd1a2cec4f18228d2c0a129..90f57f03a78824f7026d8785be165488f3748af3 100644 (file)
@@ -4,17 +4,6 @@
 extern "C" {
 #endif
 
-#ifndef _di_controller_thread_is_enabled_
-  f_status_t controller_thread_is_enabled(controller_thread_t * const thread, const uint8_t is_normal) {
-
-    if (!thread) return F_false;
-
-    const uint8_t enabled = thread->enabled;
-
-    return is_normal ? enabled == controller_thread_enabled_e : enabled;
-  }
-#endif // _di_controller_thread_is_enabled_
-
 #ifndef _di_controller_thread_is_enabled_instance_
   f_status_t controller_thread_is_enabled_instance(controller_instance_t * const instance) {
 
@@ -27,7 +16,7 @@ extern "C" {
 #ifndef _di_controller_thread_is_enabled_instance_type_
   f_status_t controller_thread_is_enabled_instance_type(controller_thread_t * const thread, const uint8_t type) {
 
-    return controller_thread_is_enabled(thread, type != controller_instance_type_exit_e);
+    return controller_thread_enable_is(thread, type != controller_instance_type_exit_e);
   }
 #endif // _di_controller_thread_is_enabled_instance_type_
 
index d6458167db62c78d56996bd86bf3550f9b5c805a..3675eb5d039c6e3e196753c1630b25e9544b497b 100644 (file)
@@ -17,25 +17,6 @@ extern "C" {
 #endif
 
 /**
- * Check to see if thread is enabled for the normal operations like Entry and Control or for Exit operations.
- *
- * @param thread
- *   The thread data.
- *
- *   Must not be NULL.
- * @param is_normal
- *   If TRUE, then instance as if this operates during a normal operation (Entry and Control).
- *   If FALSE, then instance as if this operates during an Exit operation.
- *
- * @return
- *   F_true when enabled.
- *   F_false when disabled.
- */
-#ifndef _di_controller_thread_is_enabled_
-  extern f_status_t controller_thread_is_enabled(controller_thread_t * const thread, const uint8_t is_normal);
-#endif // _di_controller_thread_is_enabled_
-
-/**
  * Check to see if thread is enabled for the normal operations like Entry and Control or for Exit operations for some instance.
  *
  * @param instance
@@ -64,9 +45,9 @@ extern "C" {
  *   The instance type to use when checking if thread is enabled.
  *
  * @return
- *   Success from controller_thread_is_enabled().
+ *   Success from controller_thread_enable_is().
  *
- * @see controller_thread_is_enabled()
+ * @see controller_thread_enable_is()
  */
 #ifndef _di_controller_thread_is_enabled_instance_type_
   extern f_status_t controller_thread_is_enabled_instance_type(controller_thread_t * const thread, const uint8_t type);
index 4506f593ce4c3859cb0fc2c60c68a77057a3fcfc..3f421b1dc5abfc391fd7b623ccaf54d8c8edaded 100644 (file)
@@ -14,7 +14,7 @@ extern "C" {
 
     controller_t * const main = (controller_t *) argument;
 
-    if (!controller_thread_is_enabled(&main->thread, F_true)) return 0;
+    if (!controller_thread_enable_is(&main->thread, F_true)) return 0;
 
     return 0;
   }
index 86762b228c2c7da859ad7433b267ac8dfad40b4f..e5dd9fa081b75e3b3764cd3769f9d927e616380a 100644 (file)
@@ -8,13 +8,13 @@ extern "C" {
   void controller_thread_signal(controller_t * const main, const uint8_t is_normal) {
 
     if (!main) return;
-    if (!controller_thread_is_enabled(&main->thread, is_normal)) return;
+    if (!controller_thread_enable_is(&main->thread, is_normal)) return;
     if (!(main->setting.flag & controller_main_flag_interruptible_d)) return;
 
     siginfo_t information;
     f_time_spec_t time = f_time_spec_t_initialize;
 
-    while (controller_thread_is_enabled(&main->thread, is_normal)) {
+    while (controller_thread_enable_is(&main->thread, is_normal)) {
 
       memset((void *) &information, 0, sizeof(siginfo_t));
 
@@ -30,7 +30,7 @@ extern "C" {
 
       // Send F_signal_reserved_35 to cleanup process to reap child processes.
       if (information.si_signo == F_signal_child || information.si_signo == F_signal_reserved_35) {
-        controller_lock_signal(&main->thread.lock.reap_condition, &main->thread.lock.reap);
+        f_thread_condition_signal_all(&main->thread.lock.reap_condition);
 
         continue;
       }
@@ -38,7 +38,7 @@ extern "C" {
       if (information.si_signo == F_signal_interrupt || information.si_signo == F_signal_abort || information.si_signo == F_signal_quit || information.si_signo == F_signal_termination) {
         main->thread.signal = information.si_signo;
 
-        controller_lock_signal(&main->thread.lock.reap_condition, &main->thread.lock.reap);
+        f_thread_condition_signal_all(&main->thread.lock.reap_condition);
         controller_thread_instance_cancel(main, is_normal, controller_thread_cancel_signal_e);
 
         break;
@@ -56,7 +56,7 @@ extern "C" {
 
     if (!interrupt->main) return;
 
-    if (!controller_thread_is_enabled(&interrupt->main->thread, interrupt->is_normal)) {
+    if (!controller_thread_enable_is(&interrupt->main->thread, interrupt->is_normal)) {
       interrupt->main->program.signal_received = F_signal_abort;
       interrupt->main->setting.state.status = F_status_set_error(F_interrupt);
     }
@@ -76,7 +76,7 @@ extern "C" {
 
     if (!interrupt->main) return;
 
-    if (!controller_thread_is_enabled(&interrupt->main->thread, interrupt->is_normal)) {
+    if (!controller_thread_enable_is(&interrupt->main->thread, interrupt->is_normal)) {
       interrupt->main->program.signal_received = F_signal_abort;
       interrupt->main->setting.state.status = F_status_set_error(F_interrupt);
     }