From 7b4f55c96a9fe61104d76ce8ad4670c7c708207b Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Fri, 12 Jul 2024 23:57:20 -0500 Subject: [PATCH] Update: Add additional protection around assignment of global.thread.enabled during Controller exit process. Spend some time trying to ensure that the mutex lock can be achieved and then change the enabled state to disabled. Add a maximum retry as a fail safe but otherwise keep retrying unless certain error conditions are encountered. --- level_3/controller/c/common/private-lock.h | 10 ++++++++++ level_3/controller/c/thread/private-thread_process.c | 16 +++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/level_3/controller/c/common/private-lock.h b/level_3/controller/c/common/private-lock.h index 965e3ec..4ddaedc 100644 --- a/level_3/controller/c/common/private-lock.h +++ b/level_3/controller/c/common/private-lock.h @@ -13,6 +13,16 @@ extern "C" { #endif /** + * Controller lock defines. + * + * controller_lock_*_d: + * - mutex_max_retry: The maximum amount of times to retry the mutex lock before giving up. + */ +#ifndef _di_controller_lock_d_ + #define controller_lock_mutex_max_retry_d 1000000 +#endif // _di_controller_lock_d_ + +/** * A structure for sharing mutexes globally between different threads. * * The alert lock is intended for a generic waiting on alerts operations. diff --git a/level_3/controller/c/thread/private-thread_process.c b/level_3/controller/c/thread/private-thread_process.c index 5e5c87b..51954ab 100644 --- a/level_3/controller/c/thread/private-thread_process.c +++ b/level_3/controller/c/thread/private-thread_process.c @@ -61,7 +61,6 @@ extern "C" { controller_entry_t *entry = 0; controller_process_t *process = 0; - f_status_t status = F_none; f_array_length_t i = 0; f_array_length_t j = 0; pid_t pid = 0; @@ -99,13 +98,16 @@ extern "C" { } // for } - // Use the alert lock to toggle enabled (using it as if it is a write like and a signal lock). - status = f_thread_mutex_lock(&global->thread->lock.alert); + f_status_t status = F_none; - if (F_status_is_error(status)) { - global->thread->enabled = controller_thread_enabled_not_e; - } - else { + for (f_array_length_t i = 0; i < controller_lock_mutex_max_retry_d; ++i) { + + status = f_thread_mutex_lock(&global->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 + + 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) { global->thread->enabled = controller_thread_enabled_execute_e; } -- 1.8.3.1