]> Kevux Git Server - fll/commitdiff
Bugfix: rules not properly handling status.
authorKevin Day <thekevinday@gmail.com>
Sun, 11 Apr 2021 21:53:54 +0000 (16:53 -0500)
committerKevin Day <thekevinday@gmail.com>
Sun, 11 Apr 2021 21:53:54 +0000 (16:53 -0500)
The status F_known_not was incorrectly being treated as busy.
Make sure to guarantee lock and then unlock of the process_other lock (read lock) to prevent execution of dependent rule while analyzing state of dependent rule.

Read the rule's status after executing from the rule in the rules array and not on the process.
The rules on the rules array is updated after execution but the process is not guaranteed this.
The status of process is generally reserved for the process to manage the status and not to represent the rule status.

Expanded the example serial execution test entries and rules.
Add a new alternative serial so that one uses normal execution and other uses dependent execution (execution is executed by something depending on it rather than being directly started via the entry).

15 files changed:
level_3/controller/c/private-rule.c
level_3/controller/data/settings/example/entries/serial-alternate.entry [new file with mode: 0644]
level_3/controller/data/settings/example/entries/serial.entry
level_3/controller/data/settings/example/rules/asynchronous/sleep_1.rule
level_3/controller/data/settings/example/rules/asynchronous/sleep_10.rule
level_3/controller/data/settings/example/rules/asynchronous/sleep_2.rule
level_3/controller/data/settings/example/rules/asynchronous/sleep_3.rule
level_3/controller/data/settings/example/rules/asynchronous/sleep_5.rule
level_3/controller/data/settings/example/rules/asynchronous/sleep_8.rule
level_3/controller/data/settings/example/rules/serial/s_1.rule
level_3/controller/data/settings/example/rules/serial/s_2.rule
level_3/controller/data/settings/example/rules/serial/s_3.rule
level_3/controller/data/settings/example/rules/serial/s_4.rule
level_3/controller/data/settings/example/rules/serial/s_5.rule
level_3/controller/data/settings/example/rules/serial/s_6.rule

index 33304e29bb1c49a8e4b653548db710c6e7e7ce44..e901eb97521a5f6f567e04abb6a5fa59f4e1da3c 100644 (file)
@@ -1811,64 +1811,70 @@ extern "C" {
 
             busy = F_false;
 
-            status = f_thread_lock_read_try(&process_other->lock);
+            f_thread_lock_read(&process_other->lock);
 
-            if (status == F_busy) {
+            if (process_other->state == controller_process_state_active || process_other->state == controller_process_state_busy) {
               busy = F_true;
             }
-            else {
-              if (process_other->status == F_known_not || process_other->state == controller_process_state_active || process_other->state == controller_process_state_busy) {
-                busy = F_true;
-              }
 
+            if (busy) {
               f_thread_unlock(&process_other->lock);
-            }
 
-            if (busy) {
               controller_process_wait(main, process_other);
             }
             else {
-              rule_options = 0;
+              f_thread_lock_read(&main.thread->lock.rule);
 
-              if (main.data->parameters[controller_parameter_test].result == f_console_result_found) {
-                rule_options |= controller_rule_option_simulate;
-              }
+              if (main.setting->rules.array[id_rule].status == F_known_not) {
+                f_thread_unlock(&main.thread->lock.rule);
+                f_thread_unlock(&process_other->lock);
 
-              // synchronously execute dependency.
-              status = controller_rule_process_begin(controller_process_option_execute, alias_other, controller_rule_action_type_start, controller_process_option_execute, process->stack, main, process_other->cache);
+                rule_options = 0;
 
-              if (status == F_child || status == F_signal) {
-                f_thread_unlock(&process_other->active);
+                if (main.data->parameters[controller_parameter_test].result == f_console_result_found) {
+                  rule_options |= controller_rule_option_simulate;
+                }
 
-                break;
-              }
+                // synchronously execute dependency.
+                status = controller_rule_process_begin(controller_process_option_execute, alias_other, controller_rule_action_type_start, controller_process_option_execute, process->stack, main, process_other->cache);
 
-              if (F_status_is_error(status)) {
-                if (i == 0 || i == 1 || F_status_set_fine(status) == F_memory_not) {
-                  f_thread_mutex_lock(&main.thread->lock.print);
+                if (status == F_child || status == F_signal) {
+                  f_thread_unlock(&process_other->active);
 
-                  controller_rule_item_error_print_need_want_wish(main.data->error, strings[i], alias_other_buffer, "failed during execution");
-                  controller_rule_error_print_cache(main.data->error, process->cache.action, F_true);
+                  break;
+                }
 
-                  controller_print_unlock_flush(main.data->output.stream, &main.thread->lock.print);
+                if (F_status_is_error(status)) {
+                  if (i == 0 || i == 1 || F_status_set_fine(status) == F_memory_not) {
+                    f_thread_mutex_lock(&main.thread->lock.print);
 
-                  if (!(process_other->options & controller_rule_option_simulate) || F_status_set_fine(status) == F_memory_not) {
-                    f_thread_unlock(&process_other->active);
+                    controller_rule_item_error_print_need_want_wish(main.data->error, strings[i], alias_other_buffer, "failed during execution");
+                    controller_rule_error_print_cache(main.data->error, process->cache.action, F_true);
+
+                    controller_print_unlock_flush(main.data->output.stream, &main.thread->lock.print);
+
+                    if (!(process_other->options & controller_rule_option_simulate) || F_status_set_fine(status) == F_memory_not) {
+                      f_thread_unlock(&process_other->active);
 
-                    break;
+                      break;
+                    }
                   }
-                }
-                else {
-                  if (main.data->warning.verbosity == f_console_verbosity_debug) {
-                    f_thread_mutex_lock(&main.thread->lock.print);
+                  else {
+                    if (main.data->warning.verbosity == f_console_verbosity_debug) {
+                      f_thread_mutex_lock(&main.thread->lock.print);
 
-                    controller_rule_item_error_print_need_want_wish(main.data->warning, strings[i], alias_other_buffer, "failed during execution");
-                    controller_rule_error_print_cache(main.data->warning, process->cache.action, F_true);
+                      controller_rule_item_error_print_need_want_wish(main.data->warning, strings[i], alias_other_buffer, "failed during execution");
+                      controller_rule_error_print_cache(main.data->warning, process->cache.action, F_true);
 
-                    controller_print_unlock_flush(main.data->output.stream, &main.thread->lock.print);
+                      controller_print_unlock_flush(main.data->output.stream, &main.thread->lock.print);
+                    }
                   }
                 }
               }
+              else {
+                f_thread_unlock(&main.thread->lock.rule);
+                f_thread_unlock(&process_other->lock);
+              }
             }
 
             if (!main.thread->enabled) {
@@ -1942,7 +1948,7 @@ extern "C" {
     }
 
     if ((process->options & controller_rule_option_wait) && F_status_is_error_not(status)) {
-      controller_rule_wait_all(main, process); // @fixme review this, it needs to check anything depending on itself!
+      controller_rule_wait_all(main, process); // @fixme review this, it needs to check anything depending on this!
 
       if (!main.thread->enabled) {
         return F_signal;
diff --git a/level_3/controller/data/settings/example/entries/serial-alternate.entry b/level_3/controller/data/settings/example/entries/serial-alternate.entry
new file mode 100644 (file)
index 0000000..5b26299
--- /dev/null
@@ -0,0 +1,11 @@
+# fss-0005
+
+main:
+  rule serial s_1
+  rule serial s_2
+  rule serial s_3
+  rule serial s_4
+  rule serial s_5
+  rule serial s_6
+
+  ready
index fcfcc82b4252cfe5206e11bb7026b73f5fbdcf94..8d6ee333d49420f5b870e86fdd3ca6e7a522939f 100644 (file)
@@ -1,7 +1,6 @@
 # fss-0005
 
 main:
-
   consider serial s_1
   consider serial s_2
   consider serial s_3
index e055c16293ea7df2557dc5615f61319cdcbb6ca3..de7c6962cb4d071dd4e84efa869a31ce1c6f9ff0 100644 (file)
@@ -7,7 +7,7 @@ setting:
   need asynchronous sleep_10
 
 script:
-  start echo "Sleeping 1: $(date -u)"
+  start echo "Sleeping 1: $(date -u), depends: 10"
 
 script:
   start sleep 1
index 63d644cc5e9d68ca14fef38cd48f1f99d9f2cf34..db6a70c79e09a1206a58ef9e6e39810f1f08a1f9 100644 (file)
@@ -6,7 +6,7 @@ setting:
   limit nice 1 2
 
 script:
-  start echo "Sleeping 10: $(date -u)"
+  start echo "Sleeping 10: $(date -u), depends: none"
 
 script:
   start sleep 10
index 77cbab58f77359d8da47441757b2fd54f54cd7ff..40f3f4c206562893fc3a2b0298d639cdaee0f2d4 100644 (file)
@@ -7,7 +7,7 @@ setting:
   need asynchronous sleep_10
 
 script:
-  start echo "Sleeping 2: $(date -u)"
+  start echo "Sleeping 2: $(date -u), depends: 10"
 
 script:
   start sleep 2
index de9141228f502f844ad71219d65bcf47a79d764c..de403b6a4bfe603da4e6864f97db0114c27c09f5 100644 (file)
@@ -7,7 +7,7 @@ setting:
   need asynchronous sleep_8
 
 script:
-  start echo "Sleeping 3: $(date -u)"
+  start echo "Sleeping 3: $(date -u), depends: 8"
 
 script:
   start sleep 3
index ecac2f525dc718d26d4b8bb7afd1f3042c79ce98..f40234bb751650435824a52924e7d3f2956941f9 100644 (file)
@@ -6,7 +6,7 @@ setting:
   limit nice 1 2
 
 script:
-  start echo "Sleeping 5: $(date -u)"
+  start echo "Sleeping 5: $(date -u), depends: none"
 
 script:
   start sleep 5
index 34d919befeca27428430909e0d9d573eaa7c1386..a05a2499ef56fd185784d4b1e78e17b07dbd44ca 100644 (file)
@@ -6,7 +6,7 @@ setting:
   limit nice 1 2
 
 script:
-  start echo "Sleeping 8: $(date -u)"
+  start echo "Sleeping 8: $(date -u), depends: none"
 
 script:
   start sleep 8
index f434357988c2c93d87cce4f0f0e8893005b96ef8..af975d1d7a8f7c656cb8fe21eabbf135599f698f 100644 (file)
@@ -5,6 +5,7 @@ setting:
 
 script:
   start {
-    echo "Serial 1: $(date -u)"
+    echo "Serial 1: sleeping $(date -u)"
     sleep 1
+    echo "Serial 1: slept    $(date -u)"
   }
index 1846b0925296430f25c90c752512dbe8ae0733e5..be526d7f8cd0d8c866e92c9badf48ac9d012e58c 100644 (file)
@@ -6,6 +6,7 @@ setting:
 
 script:
   start {
-    echo "Serial 2: $(date -u)"
+    echo "Serial 2: sleeping $(date -u)"
     sleep 1
+    echo "Serial 2: slept    $(date -u)"
   }
index 9b0ef02bad1469fc3e71c5c54ae0c3bd856bba18..124de75025bfa97c63e6aabedc9fa575a41ebc69 100644 (file)
@@ -6,6 +6,7 @@ setting:
 
 script:
   start {
-    echo "Serial 3: $(date -u)"
+    echo "Serial 3: sleeping $(date -u)"
     sleep 1
+    echo "Serial 3: slept    $(date -u)"
   }
index 46217aba2a94c04847ba2606bc91d29dab17fa33..beb52f7f225bb36d79d5d3eb001a2bc94a78d94f 100644 (file)
@@ -6,6 +6,7 @@ setting:
 
 script:
   start {
-    echo "Serial 4: $(date -u)"
+    echo "Serial 4: sleeping $(date -u)"
     sleep 1
+    echo "Serial 4: slept    $(date -u)"
   }
index f180252a115018a0f412114e796257d2da1e47c9..eb6aab82f6500b10c1809bf9e263465b76d06e13 100644 (file)
@@ -6,6 +6,7 @@ setting:
 
 script:
   start {
-    echo "Serial 5: $(date -u)"
+    echo "Serial 5: sleeping $(date -u)"
     sleep 1
+    echo "Serial 5: slept    $(date -u)"
   }
index ec3b0203fd66fb2a58ca411360fba046462fd184..af3bc822d7aa8dc277bbe3e2cc9b2e5b60518f0a 100644 (file)
@@ -6,6 +6,7 @@ setting:
 
 script:
   start {
-    echo "Serial 6: $(date -u)"
+    echo "Serial 6: sleeping $(date -u)"
     sleep 1
+    echo "Serial 6: slept    $(date -u)"
   }