]> Kevux Git Server - fll/commitdiff
Progress: controller program.
authorKevin Day <thekevinday@gmail.com>
Fri, 9 Apr 2021 02:10:37 +0000 (21:10 -0500)
committerKevin Day <thekevinday@gmail.com>
Fri, 9 Apr 2021 23:59:21 +0000 (18:59 -0500)
Copy over the rule item action statuses when the rule process completes.

Update cleanup thread:
- deallocate rule data in no longer used space.
- make sure cache thread is being started.

Implement asynchronous example rules for testing.

Disable asynchronous execution when running in validation mode.
This ensures consistency and cleanliness when outputting the validation data.
There is no reason to run asynchronously in this mode because nothing is supposed to be run anyway.
Make sure that execution (simulated or not) is not performed in validation mode.
Make sure the program immediately executes at the end when in validation mode.

documents/threads.txt
level_3/controller/c/private-controller.c
level_3/controller/c/private-rule.c
level_3/controller/c/private-thread.c
level_3/controller/data/settings/example/entries/asynchronous.entry
level_3/controller/data/settings/example/rules/asynchronous/sleep_1.rule [new file with mode: 0644]
level_3/controller/data/settings/example/rules/asynchronous/sleep_10.rule [new file with mode: 0644]
level_3/controller/data/settings/example/rules/asynchronous/sleep_2.rule [new file with mode: 0644]
level_3/controller/data/settings/example/rules/asynchronous/sleep_3.rule [new file with mode: 0644]
level_3/controller/data/settings/example/rules/asynchronous/sleep_5.rule [new file with mode: 0644]
level_3/controller/data/settings/example/rules/asynchronous/sleep_8.rule [new file with mode: 0644]

index edbae5bbb8f6a97bd4977dc2f54596ef30f6a328..fbb2f7990fd6bad6255444a8545fc141760f2440 100644 (file)
@@ -25,3 +25,10 @@ GLIBC Problems:
 
   There needs to be more investigation into the cause of this.
   Maybe there is some way to fix this during compile or link time without having to fix GLIBC or use a different libc for static linking.
+
+Valgrind Debugging:
+  The tool "helgrind" in valgrind allows for debugging threads (such as valgrind --tool=helgrrind controller).
+
+  The way in which the "active" lock is used will result in out of order locks.
+  This causes "helgrind" to produce a lot of warnings about locks being out of order.
+  Therefore, it is stongly recommended to use the parameter "--track-lockorders=no".
index e8da949c090a27048bb5c75304bc0a18b0a6af2f..ca34fe7d6eab6a2109121952085fd546143039c7 100644 (file)
@@ -1100,8 +1100,10 @@ extern "C" {
             }
 
             if (entry_action->code & controller_entry_rule_code_asynchronous) {
-              process_options |= controller_process_option_asynchronous;
-              rule_options |= controller_rule_option_asynchronous;
+              if (main.data->parameters[controller_parameter_validate].result != f_console_result_found) {
+                process_options |= controller_process_option_asynchronous;
+                rule_options |= controller_rule_option_asynchronous;
+              }
             }
 
             status = controller_rule_process_begin(process_options, alias_rule, controller_rule_action_type_start, rule_options, stack, main, *cache);
index 99499d86272a99a47b06ae3a341bef1579b5cbbe..e959722776739adbe65f31b342fa512c24e51e80 100644 (file)
@@ -1639,6 +1639,8 @@ extern "C" {
 
     if ((process->options & controller_rule_option_simulate) && main.data->parameters[controller_parameter_validate].result == f_console_result_found) {
       controller_rule_validate(process->rule, controller_rule_action_type_start, process->options, main, &process->cache);
+
+      return F_none;
     }
 
     f_array_length_t i = 0;
@@ -1935,9 +1937,25 @@ extern "C" {
       controller_rule_error_print(main.data->error, process->cache.action, F_status_set_fine(status), "controller_rule_find", F_true, F_true, main.thread);
     }
     else {
-      main.setting->rules.array[id_rule].status = process->rule.status;
+      controller_rule_t *rule = &main.setting->rules.array[id_rule];
+
+      rule->status = process->rule.status;
+
+      f_array_length_t j = 0;
+
+      controller_rule_item_t *rule_item = 0;
+      controller_rule_action_t *rule_action = 0;
 
-      // @fixme the rule item action status needs to be copied over from the local rule to the old one but there is no way to map the two (the structure could have changeed).
+      // @todo implement a "version" counter and detect if the rule version is different before attempting update.
+      // copy all rule item action statuses from the rule process to the rule.
+      for (i = 0; i < rule->items.used; ++i) {
+
+        rule_item = &rule->items.array[i];
+
+        for (j = 0; j < rule_item->actions.used; ++j) {
+          rule_item->actions.array[j].status = process->rule.items.array[i].actions.array[j].status;
+        } // for
+      } // for
     }
 
     f_thread_unlock(&main.thread->lock.rule);
index f4dbb16b77c4acbf58e76b807b6608aebda29d73..785652679eb6fabb891f5776e1d398c69319ee2c 100644 (file)
@@ -77,6 +77,11 @@ extern "C" {
           controller_cache_delete_simple(&process->cache);
           f_type_array_lengths_resize(0, &process->stack);
 
+          // deallocate any rules in the space that is declared to be unused.
+          if (i >= main->thread->processs.used) {
+            controller_rule_delete_simple(&process->rule);
+          }
+
           f_thread_unlock(&process->active);
         } // for
 
@@ -222,50 +227,60 @@ extern "C" {
 
           thread.id_rule = 0;
           status = thread.status;
-        }
 
-        if (status == F_child) {
-          controller_thread_delete_simple(&thread);
+          if (status == F_child) {
+            controller_thread_delete_simple(&thread);
 
-          return F_child;
+            return F_child;
+          }
         }
       }
     }
 
+    // @todo consider redesigning to spawn forked processes from main thread to allow proper deallocation via a timed mutex condition (only need to do this for scripts).
+
     // only make the rule and control threads available once any/all pre-processing and are completed.
     if (F_status_is_error_not(status) && status != F_signal && status != F_child && thread.enabled) {
 
-      if (data->parameters[controller_parameter_validate].result == f_console_result_none && thread.id_rule) {
+      if (data->parameters[controller_parameter_validate].result == f_console_result_none) {
 
-        // wait for the entry thread to complete before starting the rule thread.
-        f_thread_join(thread.id_rule, 0);
+        if (thread.id_rule) {
 
-        if (thread.status == F_child) {
-          controller_thread_delete_simple(&thread);
+          // wait for the entry thread to complete before starting the rule thread.
+          f_thread_join(thread.id_rule, 0);
 
-          return F_child;
-        }
+          if (thread.status == F_child) {
+            controller_thread_delete_simple(&thread);
 
-        thread.id_rule = 0;
+            return F_child;
+          }
+
+          thread.id_rule = 0;
+        }
 
         if (thread.enabled) {
           status = f_thread_create(0, &thread.id_rule, &controller_thread_rule, (void *) &main);
-        }
 
-        status = f_thread_create(0, &thread.id_control, &controller_thread_control, (void *) &main);
+          if (F_status_is_error(status)) {
+            thread.id_rule = 0;
+          }
+          else {
+            status = f_thread_create(0, &thread.id_control, &controller_thread_control, (void *) &main);
+          }
 
-        if (F_status_is_error(status)) {
-          thread.id_control = 0;
-        }
-        else {
-          status = f_thread_create(0, &thread.id_cleanup, &controller_thread_cleanup, (void *) &main);
-        }
+          if (F_status_is_error(status)) {
+            thread.id_control = 0;
+          }
+          else {
+            status = f_thread_create(0, &thread.id_cleanup, &controller_thread_cleanup, (void *) &main);
+          }
 
-        if (F_status_is_error(status)) {
-          thread.id_cleanup = 0;
+          if (F_status_is_error(status)) {
+            thread.id_cleanup = 0;
 
-          if (data->error.verbosity != f_console_verbosity_quiet) {
-            controller_error_print(data->error, F_status_set_fine(status), "f_thread_create", F_true, &thread);
+            if (data->error.verbosity != f_console_verbosity_quiet) {
+              controller_error_print(data->error, F_status_set_fine(status), "f_thread_create", F_true, &thread);
+            }
           }
         }
       }
@@ -292,9 +307,9 @@ extern "C" {
 
         thread.id_signal = 0;
       }
-    }
 
-    controller_thread_process_cancel(&main);
+      controller_thread_process_cancel(&main);
+    }
 
     if (thread.id_signal) f_thread_cancel(thread.id_signal);
     if (thread.id_cleanup) f_thread_cancel(thread.id_cleanup);
index 67f0d67f91e4c6935c8dbe899e6c96e6e314b6bb..5a2f516cbff78d114be2d92bcbdd20f36dbd28cd 100644 (file)
@@ -1,3 +1,14 @@
 # fss-0005
 
 main:
+  consider asynchronous sleep_3 asynchronous
+  consider asynchronous sleep_5 asynchronous
+
+  rule asynchronous sleep_1 asynchronous
+  rule asynchronous sleep_2 asynchronous
+  rule asynchronous sleep_3 asynchronous
+  rule asynchronous sleep_5 asynchronous
+  rule asynchronous sleep_8 asynchronous
+  rule asynchronous sleep_10 asynchronous
+
+  ready
diff --git a/level_3/controller/data/settings/example/rules/asynchronous/sleep_1.rule b/level_3/controller/data/settings/example/rules/asynchronous/sleep_1.rule
new file mode 100644 (file)
index 0000000..17671c1
--- /dev/null
@@ -0,0 +1,13 @@
+# fss-000d
+
+setting:
+  name "Sleep 1 Seconds."
+  nice 15
+  limit nice 1 2
+  need asynchronous sleep_3
+
+script:
+  start sleep 1
+
+script:
+  start echo "Sleep 1: $(date -u)"
diff --git a/level_3/controller/data/settings/example/rules/asynchronous/sleep_10.rule b/level_3/controller/data/settings/example/rules/asynchronous/sleep_10.rule
new file mode 100644 (file)
index 0000000..d4e89b0
--- /dev/null
@@ -0,0 +1,12 @@
+# fss-000d
+
+setting:
+  name "Sleep 10 Seconds."
+  nice 15
+  limit nice 1 2
+
+script:
+  start sleep 10
+
+script:
+  start echo "Sleep 10: $(date -u)"
diff --git a/level_3/controller/data/settings/example/rules/asynchronous/sleep_2.rule b/level_3/controller/data/settings/example/rules/asynchronous/sleep_2.rule
new file mode 100644 (file)
index 0000000..a080fd1
--- /dev/null
@@ -0,0 +1,13 @@
+# fss-000d
+
+setting:
+  name "Sleep 2 Seconds."
+  nice 15
+  limit nice 1 2
+  need asynchronous sleep_5
+
+script:
+  start sleep 2
+
+script:
+  start echo "Sleep 2: $(date -u)"
diff --git a/level_3/controller/data/settings/example/rules/asynchronous/sleep_3.rule b/level_3/controller/data/settings/example/rules/asynchronous/sleep_3.rule
new file mode 100644 (file)
index 0000000..436fbbd
--- /dev/null
@@ -0,0 +1,13 @@
+# fss-000d
+
+setting:
+  name "Sleep 3 Seconds."
+  nice 15
+  limit nice 1 2
+  need asynchronous sleep_5
+
+script:
+  start sleep 3
+
+script:
+  start echo "Sleep 3: $(date -u)"
diff --git a/level_3/controller/data/settings/example/rules/asynchronous/sleep_5.rule b/level_3/controller/data/settings/example/rules/asynchronous/sleep_5.rule
new file mode 100644 (file)
index 0000000..e6ede53
--- /dev/null
@@ -0,0 +1,12 @@
+# fss-000d
+
+setting:
+  name "Sleep 5 Seconds."
+  nice 15
+  limit nice 1 2
+
+script:
+  start sleep 5
+
+script:
+  start echo "Sleep 5: $(date -u)"
diff --git a/level_3/controller/data/settings/example/rules/asynchronous/sleep_8.rule b/level_3/controller/data/settings/example/rules/asynchronous/sleep_8.rule
new file mode 100644 (file)
index 0000000..1c5dbfc
--- /dev/null
@@ -0,0 +1,12 @@
+# fss-000d
+
+setting:
+  name "Sleep 8 Seconds."
+  nice 15
+  limit nice 1 2
+
+script:
+  start sleep 8
+
+script:
+  start echo "Sleep 8: $(date -u)"