From 2dc9cc6eca1dbbfffa646d1ae28f5df8662a2187 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 17 Apr 2021 23:44:38 -0500 Subject: [PATCH] Bugfix: asynchronous processes not executing properly according to dependencies. The controller_process_wait() function is returning immediately because the status is being changed and is only checking for F_time. Add status_lock to separate it from status. Return if status is an error. Require Rule status to be both not F_known_not and not one of "active" or "busy". If processes are waiting for a while and a signal is received, decrease the wait timer. --- level_3/controller/c/private-common.c | 29 +++++++++++++++++++++++++---- level_3/controller/c/private-rule.c | 6 ++++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/level_3/controller/c/private-common.c b/level_3/controller/c/private-common.c index cd5d5b7..6531c1c 100644 --- a/level_3/controller/c/private-common.c +++ b/level_3/controller/c/private-common.c @@ -322,6 +322,7 @@ extern "C" { struct timespec time; f_status_t status = F_none; + f_status_t status_lock = F_none; uint8_t count = 0; @@ -349,18 +350,38 @@ extern "C" { return F_signal; } - status = controller_lock_read(main.thread, &process->lock); - if (status == F_signal || F_status_is_error(status)) { - controller_lock_error_critical_print(main.data->error, F_status_set_fine(status), F_true, main.thread); + if (F_status_is_error(status)) { + break; + } + + status_lock = controller_lock_read(main.thread, &process->lock); + if (status_lock == F_signal || F_status_is_error(status_lock)) { + controller_lock_error_critical_print(main.data->error, F_status_set_fine(status_lock), F_true, main.thread); break; } - if (process->rule.status != F_known_not || !(process->state == controller_process_state_active || process->state == controller_process_state_busy)) { + if (process->rule.status != F_known_not && !(process->state == controller_process_state_active || process->state == controller_process_state_busy)) { f_thread_unlock(&process->lock); return F_none; } + else if (status != F_time) { + + // move up the wait timer after a trigger was received. + if (count < controller_thread_wait_timeout_1_before) { + count = 0; + } + else if (count < controller_thread_wait_timeout_2_before) { + count = controller_thread_wait_timeout_1_before; + } + else if (count < controller_thread_wait_timeout_3_before) { + count = controller_thread_wait_timeout_2_before; + } + else { + count = controller_thread_wait_timeout_3_before; + } + } f_thread_unlock(&process->lock); diff --git a/level_3/controller/c/private-rule.c b/level_3/controller/c/private-rule.c index 054814b..bf92e2d 100644 --- a/level_3/controller/c/private-rule.c +++ b/level_3/controller/c/private-rule.c @@ -1987,7 +1987,9 @@ extern "C" { else if (process_other->state == controller_process_state_active || process_other->state == controller_process_state_busy) { f_thread_unlock(&process_other->lock); - controller_process_wait(main, process_other); + status = controller_process_wait(main, process_other); + + if (F_status_is_error(status) && !(process->options & controller_process_option_simulate)) break; status = process_other->rule.status; } @@ -2078,7 +2080,7 @@ extern "C" { status = status_lock; } - if (F_status_is_error(main.setting->rules.array[id_rule].status)) { + else if (F_status_is_error(main.setting->rules.array[id_rule].status)) { f_thread_unlock(&main.thread->lock.rule); if (i == 0 || i == 1) { -- 1.8.3.1