]> Kevux Git Server - fll/commitdiff
Regression: Entry error after failure or during validation is not propogating.
authorKevin Day <thekevinday@gmail.com>
Tue, 27 Apr 2021 04:09:09 +0000 (23:09 -0500)
committerKevin Day <thekevinday@gmail.com>
Tue, 27 Apr 2021 04:09:09 +0000 (23:09 -0500)
When an Entry fails and successfully executes a failsafe, the failure is not propagated.
The failsafe is meant to bail out and not continue onward, so after a successful or failed failsafe, return F_failure (with error bit as appropriate).

When passing --validate without --test, the program is not exiting as it should.
This is because the state is not being handled just like the status is not being handled.

When joining threads, be sure to reset the identifiers.

Remove now extra Exit processing block.
This is now handled fully by the cancellation function.

Restore the thread enabled state after operating failsafe.

Get rid of simulate variable, instead use the console parameter directly.
This saves memory by a trivial amount.

level_3/controller/c/private-controller.c
level_3/controller/c/private-rule.c
level_3/controller/c/private-thread.c

index 01212195503ff84d96d3af8321762d5695e862a0..7ead0498985e9bf4420666704346aad7cfff76ca 100644 (file)
@@ -710,8 +710,6 @@ extern "C" {
     // an empty stack is used here because each rule here is the first rule run in the rule's scope.
     const f_array_lengths_t stack = f_array_lengths_t_initialize;
 
-    const bool simulate = main->data->parameters[controller_parameter_test].result == f_console_result_found;
-
     cache->ats.used = 0;
     cache->stack.used = 0;
 
@@ -749,7 +747,7 @@ extern "C" {
       return status;
     }
 
-    if (simulate || main->data->error.verbosity == f_console_verbosity_verbose) {
+    if (main->data->parameters[controller_parameter_test].result == f_console_result_found || main->data->error.verbosity == f_console_verbosity_verbose) {
       if (main->data->error.verbosity != f_console_verbosity_quiet) {
         f_thread_mutex_lock(&main->thread->lock.print);
 
@@ -783,7 +781,7 @@ extern "C" {
 
         if (F_status_is_error(entry_action->status)) {
           if (controller_entry_action_type_is_rule(entry_action->type)) {
-            if (simulate) {
+            if (main->data->parameters[controller_parameter_test].result == f_console_result_found) {
               if (main->data->error.verbosity != f_console_verbosity_quiet) {
                 f_thread_mutex_lock(&main->thread->lock.print);
 
@@ -853,7 +851,7 @@ extern "C" {
             }
           }
           else {
-            if (simulate) {
+            if (main->data->parameters[controller_parameter_test].result == f_console_result_found) {
               if (main->data->error.verbosity != f_console_verbosity_quiet) {
                 f_thread_mutex_lock(&main->thread->lock.print);
 
@@ -900,7 +898,7 @@ extern "C" {
 
         if (entry_action->type == controller_entry_action_type_ready) {
           if (entry_action->code & controller_entry_rule_code_wait) {
-            if (simulate || main->data->error.verbosity == f_console_verbosity_verbose) {
+            if (main->data->parameters[controller_parameter_test].result == f_console_result_found || main->data->error.verbosity == f_console_verbosity_verbose) {
               if (main->data->error.verbosity != f_console_verbosity_quiet) {
                 f_thread_mutex_lock(&main->thread->lock.print);
 
@@ -919,7 +917,7 @@ extern "C" {
           }
 
           if (main->setting->ready == controller_setting_ready_wait) {
-            if (simulate || main->data->error.verbosity == f_console_verbosity_verbose) {
+            if (main->data->parameters[controller_parameter_test].result == f_console_result_found || main->data->error.verbosity == f_console_verbosity_verbose) {
               if (main->data->error.verbosity != f_console_verbosity_quiet) {
                 f_thread_mutex_lock(&main->thread->lock.print);
 
@@ -932,7 +930,7 @@ extern "C" {
               }
             }
 
-            if (!simulate) {
+            if (main->data->parameters[controller_parameter_test].result == f_console_result_none) {
               status = controller_perform_ready(is_entry, *main, cache);
 
               if (F_status_is_error(status)) return status;
@@ -940,7 +938,7 @@ extern "C" {
 
             main->setting->ready = controller_setting_ready_yes;
           }
-          else if (simulate || main->data->error.verbosity == f_console_verbosity_verbose) {
+          else if (main->data->parameters[controller_parameter_test].result == f_console_result_found || main->data->error.verbosity == f_console_verbosity_verbose) {
             if (main->data->error.verbosity != f_console_verbosity_quiet) {
               f_thread_mutex_lock(&main->thread->lock.print);
 
@@ -1004,7 +1002,7 @@ extern "C" {
             return status;
           }
 
-          if (simulate || main->data->error.verbosity == f_console_verbosity_verbose) {
+          if (main->data->parameters[controller_parameter_test].result == f_console_result_found || main->data->error.verbosity == f_console_verbosity_verbose) {
             if (main->data->error.verbosity != f_console_verbosity_quiet) {
               f_thread_mutex_lock(&main->thread->lock.print);
 
@@ -1061,7 +1059,7 @@ extern "C" {
 
           f_thread_unlock(&main->thread->lock.rule);
 
-          if (simulate || main->data->error.verbosity == f_console_verbosity_verbose) {
+          if (main->data->parameters[controller_parameter_test].result == f_console_result_found || main->data->error.verbosity == f_console_verbosity_verbose) {
             if (main->data->error.verbosity != f_console_verbosity_quiet) {
               f_thread_mutex_lock(&main->thread->lock.print);
 
@@ -1139,7 +1137,7 @@ extern "C" {
                 controller_print_unlock_flush(main->data->output.stream, &main->thread->lock.print);
               }
 
-              if (!simulate) {
+              if (main->data->parameters[controller_parameter_test].result == f_console_result_none) {
                 f_thread_unlock(&main->thread->lock.rule);
 
                 break;
@@ -1156,7 +1154,7 @@ extern "C" {
             options_force = 0;
             options_process = 0;
 
-            if (simulate) {
+            if (main->data->parameters[controller_parameter_test].result == f_console_result_found) {
               options_process |= controller_process_option_simulate;
             }
 
@@ -1173,7 +1171,7 @@ extern "C" {
             }
 
             if (entry_action->code & controller_entry_rule_code_asynchronous) {
-              if (main->data->parameters[controller_parameter_validate].result != f_console_result_found) {
+              if (main->data->parameters[controller_parameter_validate].result == f_console_result_none) {
                 options_force |= controller_process_option_asynchronous;
               }
 
@@ -1186,13 +1184,13 @@ extern "C" {
               break;
             }
 
-            if (F_status_is_error(status) && !simulate && (entry_action->code & controller_entry_rule_code_require)) {
+            if (F_status_is_error(status) && main->data->parameters[controller_parameter_test].result == f_console_result_none && (entry_action->code & controller_entry_rule_code_require)) {
               return F_status_set_error(F_require);
             }
           }
         }
         else if (entry_action->type == controller_entry_action_type_execute) {
-          if (simulate || main->data->error.verbosity == f_console_verbosity_verbose) {
+          if (main->data->parameters[controller_parameter_test].result == f_console_result_found || main->data->error.verbosity == f_console_verbosity_verbose) {
             if (main->data->error.verbosity != f_console_verbosity_quiet) {
               f_thread_mutex_lock(&main->thread->lock.print);
 
@@ -1214,7 +1212,7 @@ extern "C" {
             }
           }
 
-          if (simulate) {
+          if (main->data->parameters[controller_parameter_test].result == f_console_result_found) {
             return F_execute;
           }
 
@@ -1266,7 +1264,7 @@ extern "C" {
         }
         else if (entry_action->type == controller_entry_action_type_timeout) {
 
-          if (simulate || main->data->error.verbosity == f_console_verbosity_verbose) {
+          if (main->data->parameters[controller_parameter_test].result == f_console_result_found || main->data->error.verbosity == f_console_verbosity_verbose) {
             f_string_t code = "";
 
             if (entry_action->code == controller_entry_timeout_code_kill) {
@@ -1342,7 +1340,7 @@ extern "C" {
               main->setting->failsafe_enabled = F_true;
               main->setting->failsafe_item_id = entry_action->number;
 
-              if (simulate || main->data->error.verbosity == f_console_verbosity_verbose) {
+              if (main->data->parameters[controller_parameter_test].result == f_console_result_found || main->data->error.verbosity == f_console_verbosity_verbose) {
                 if (main->data->error.verbosity != f_console_verbosity_quiet) {
                   f_thread_mutex_lock(&main->thread->lock.print);
 
@@ -1409,7 +1407,7 @@ extern "C" {
       return status_lock;
     }
 
-    // check to see if any requied processes failed, but do not do this if already operating in failsafe.
+    // 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->data->parameters[controller_parameter_validate].result == f_console_result_none) {
       const f_status_t status_wait = controller_rule_wait_all(is_entry, *main, F_true, 0);
 
@@ -1422,7 +1420,7 @@ extern "C" {
       }
     }
 
-    if ((simulate && main->data->error.verbosity != f_console_verbosity_quiet) || main->data->error.verbosity == f_console_verbosity_verbose) {
+    if ((main->data->parameters[controller_parameter_test].result == f_console_result_found && main->data->error.verbosity != f_console_verbosity_quiet) || main->data->error.verbosity == f_console_verbosity_verbose) {
       f_thread_mutex_lock(&main->thread->lock.print);
 
       fprintf(main->data->output.stream, "%c", f_string_eol_s[0]);
index aca775639419651e3febf041bfcc4ee27d3de5c4..32eb0fdbce594096eac986cfd12b878a0236a71a 100644 (file)
@@ -1917,7 +1917,7 @@ extern "C" {
       return status;
     }
 
-    if ((process->options & controller_process_option_simulate) && main.data->parameters[controller_parameter_validate].result == f_console_result_found) {
+    if ((process->options & controller_process_option_simulate) && (process->options & controller_process_option_validate)) {
       controller_rule_validate(process->rule, process->action, process->options, main, &process->cache);
     }
 
@@ -2129,7 +2129,7 @@ extern "C" {
                   options_process |= controller_process_option_simulate;
                 }
 
-                if (main.data->parameters[controller_parameter_validate].result == f_console_result_found) {
+                if (process->options & controller_process_option_validate) {
                   options_process |= controller_process_option_validate;
                 }
 
@@ -2252,7 +2252,7 @@ extern "C" {
       return F_signal;
     }
 
-    if ((process->options & controller_process_option_wait) && F_status_is_error_not(status) && main.data->parameters[controller_parameter_validate].result == f_console_result_none) {
+    if ((process->options & controller_process_option_wait) && F_status_is_error_not(status) && (process->options & controller_process_option_validate)) {
 
       status_lock = controller_rule_wait_all_process_type(process->type, main, F_false, process);
 
index 2e1623810fe1765b3daa7e1fb0e0ba5318aaced4..bc6ee7935f698410d26b4e0e7c96282b03b42379 100644 (file)
@@ -234,12 +234,13 @@ extern "C" {
           controller_thread_join(&thread.id_entry);
 
           status = thread.status;
+          thread.id_entry = 0;
         }
       }
     }
 
     // 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 == controller_thread_enabled) {
+    if (F_status_is_error_not(status) && status != F_signal && status != F_failure && status != F_child && thread.enabled == controller_thread_enabled) {
 
       if (data->parameters[controller_parameter_validate].result == f_console_result_none) {
 
@@ -280,30 +281,12 @@ extern "C" {
       return F_child;
     }
 
-    if (F_status_is_error(status) || status == F_signal || !(data->parameters[controller_parameter_validate].result == f_console_result_none || data->parameters[controller_parameter_test].result == f_console_result_found)) {
+    if (F_status_is_error_not(status) && status != F_signal && status != F_failure && data->parameters[controller_parameter_validate].result == f_console_result_none && controller_thread_is_enabled(F_true, &thread)) {
 
-      if (main.data->parameters[controller_parameter_validate].result == f_console_result_found) {
-        const controller_main_entry_t entry = controller_macro_main_entry_t_initialize(&main, main.setting);
-
-        status = f_thread_create(0, &thread.id_entry, &controller_thread_exit, (void *) &entry);
-
-        if (F_status_is_error(status)) {
-          if (data->error.verbosity != f_console_verbosity_quiet) {
-            controller_error_print(data->error, F_status_set_fine(status), "f_thread_create", F_true, &thread);
-          }
-        }
-        else {
-          controller_thread_join(&thread.id_entry);
-
-          status = thread.status;
-        }
-      }
-    }
-    else {
-      if (data->parameters[controller_parameter_validate].result == f_console_result_none && setting->mode == controller_setting_mode_service) {
+      if (setting->mode == controller_setting_mode_service) {
         controller_thread_join(&thread.id_signal);
       }
-      else if (data->parameters[controller_parameter_validate].result == f_console_result_none && setting->mode == controller_setting_mode_program) {
+      else if (setting->mode == controller_setting_mode_program) {
         controller_rule_wait_all(F_true, main, F_false, 0);
       }
     }
@@ -732,6 +715,8 @@ extern "C" {
 
             if ((F_status_set_fine(*status) == F_execute || F_status_set_fine(*status) == F_require) && entry->main->setting->failsafe_enabled) {
 
+              const uint8_t original_enabled = entry->main->thread->enabled;
+
               // restore operating mode so that the failsafe can execute.
               *status = f_thread_mutex_lock(&entry->main->thread->lock.alert);
 
@@ -759,6 +744,21 @@ extern "C" {
 
                   controller_print_unlock_flush(data->error.to.stream, &entry->main->thread->lock.print);
                 }
+
+                *status = F_status_set_error(F_failure);
+              }
+              else {
+
+                // restore operating mode to value prior to failsafe mode.
+                *status = f_thread_mutex_lock(&entry->main->thread->lock.alert);
+
+                if (F_status_is_error_not(*status)) {
+                  entry->main->thread->enabled = original_enabled;
+
+                  f_thread_mutex_unlock(&entry->main->thread->lock.alert);
+                }
+
+                *status = F_failure;
               }
             }
           }
@@ -824,6 +824,8 @@ extern "C" {
 
           if ((F_status_set_fine(*status) == F_execute || F_status_set_fine(*status) == F_require) && entry->main->setting->failsafe_enabled) {
 
+            const uint8_t original_enabled = entry->main->thread->enabled;
+
             // restore operating mode so that the failsafe can execute.
             if (F_status_set_fine(*status) == F_execute) {
               *status = f_thread_mutex_lock(&entry->main->thread->lock.alert);
@@ -853,6 +855,21 @@ extern "C" {
 
                 controller_print_unlock_flush(data->error.to.stream, &entry->main->thread->lock.print);
               }
+
+              *status = F_status_set_error(F_failure);
+            }
+            else {
+
+              // restore operating mode to value prior to failsafe mode.
+              *status = f_thread_mutex_lock(&entry->main->thread->lock.alert);
+
+              if (F_status_is_error_not(*status)) {
+                entry->main->thread->enabled = original_enabled;
+
+                f_thread_mutex_unlock(&entry->main->thread->lock.alert);
+              }
+
+              *status = F_failure;
             }
           }
         }