From: Kevin Day Date: Thu, 14 Aug 2025 03:50:08 +0000 (-0500) Subject: Update: Add additional locking to the instance cancel. X-Git-Tag: 0.7.3~32 X-Git-Url: https://www.git.kevux.org/?a=commitdiff_plain;h=11f30c6b7533e9bd78b22052878c04faec7934a6;p=controller Update: Add additional locking to the instance cancel. Expand the locking functions to accept the seconds and nanoseconds. Provide standard locking functions that do not need the seconds and nanoseconds passed. Add locking with fail out status checks to the instance clean up function. --- diff --git a/sources/c/program/controller/main/entry/process.c b/sources/c/program/controller/main/entry/process.c index 402bf48..ab13094 100644 --- a/sources/c/program/controller/main/entry/process.c +++ b/sources/c/program/controller/main/entry/process.c @@ -186,7 +186,7 @@ extern "C" { break; } else if (entry_action->type == controller_entry_action_type_consider_e || controller_entry_action_type_is_rule(entry_action->type)) { - status_lock = controller_lock_write(is_entry, F_true, &main->thread, &main->thread.lock.rule); + status_lock = controller_lock_write_standard(is_entry, F_true, &main->thread, &main->thread.lock.rule); if (status_lock != F_okay) { controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false); @@ -214,7 +214,7 @@ extern "C" { id_rule_name[entry_action->parameters.array[0].used] = f_path_separator_s.string[0]; id_rule_name[id_rule_length] = 0; - status_lock = controller_lock_read(is_entry, F_true, &main->thread, &main->thread.lock.rule); + status_lock = controller_lock_read_standard(is_entry, F_true, &main->thread, &main->thread.lock.rule); if (status_lock != F_okay) { controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_true); @@ -251,7 +251,7 @@ extern "C" { memcpy(cache_name_item, cache->action.name_item.string, sizeof(f_char_t) * cache->action.name_item.used); memcpy(cache_name_file, cache->action.name_file.string, sizeof(f_char_t) * cache->action.name_file.used); - status_lock = controller_lock_write(is_entry, F_true, &main->thread, &main->thread.lock.rule); + status_lock = controller_lock_write_standard(is_entry, F_true, &main->thread, &main->thread.lock.rule); if (status_lock == F_okay) { status = controller_rule_read(main, cache, is_entry, alias_rule, entry, &main->process.rules.array[main->process.rules.used]); diff --git a/sources/c/program/controller/main/instance/prepare.c b/sources/c/program/controller/main/instance/prepare.c index 078f233..ffa0012 100644 --- a/sources/c/program/controller/main/instance/prepare.c +++ b/sources/c/program/controller/main/instance/prepare.c @@ -14,7 +14,7 @@ extern "C" { if (controller_instance_find(action, alias, main->thread.instances, id) == F_false) { f_thread_unlock(&main->thread.lock.instance); - status = controller_lock_write(is_normal, F_true, &main->thread, &main->thread.lock.instance); + status = controller_lock_write_standard(is_normal, F_true, &main->thread, &main->thread.lock.instance); if (status != F_okay) { controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status), F_false); @@ -35,7 +35,7 @@ extern "C" { controller_instance_t * const instance = F_status_is_error_not(status) ? main->thread.instances.array[main->thread.instances.used] : 0; if (status == F_okay) { - status = controller_lock_write(is_normal, F_true, &main->thread, &instance->lock); + status = controller_lock_write_standard(is_normal, F_true, &main->thread, &instance->lock); } if (F_status_is_error(status)) { @@ -65,7 +65,7 @@ extern "C" { } // The read lock must be restored on return. - const f_status_t status_restore = F_status_is_error(controller_lock_read(is_normal, F_false, &main->thread, &main->thread.lock.instance)) + const f_status_t status_restore = F_status_is_error(controller_lock_read_standard(is_normal, F_false, &main->thread, &main->thread.lock.instance)) ? F_status_set_error(F_lock_read) : F_okay; diff --git a/sources/c/program/controller/main/lock.c b/sources/c/program/controller/main/lock.c index ebb4412..93c5604 100644 --- a/sources/c/program/controller/main/lock.c +++ b/sources/c/program/controller/main/lock.c @@ -83,7 +83,7 @@ extern "C" { #endif // _di_controller_lock_create_ #ifndef _di_controller_lock_mutex_ - f_status_t controller_lock_mutex(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_mutex_t * const mutex) { + f_status_t controller_lock_mutex(const uint8_t is_normal, const uint8_t check, const time_t seconds, const long nanoseconds, controller_thread_t * const thread, f_thread_mutex_t * const mutex) { if (!thread || !mutex) return F_status_set_error(F_parameter); @@ -98,7 +98,12 @@ extern "C" { status = f_thread_mutex_lock_timed(&time, mutex); if (status == F_time) { - if (check && !controller_thread_enable_is(thread, is_normal)) return F_status_set_error(F_interrupt); + if (check) { + if (check == 0x2) { + if (F_status_is_error(status)) return status; + } + else if (!controller_thread_enable_is(thread, is_normal)) return F_status_set_error(F_interrupt); + } } else if (status == F_okay) { break; @@ -109,17 +114,24 @@ extern "C" { } #endif // _di_controller_lock_mutex_ +#ifndef _di_controller_lock_mutex_standard_ + f_status_t controller_lock_mutex_standard(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_mutex_t * const mutex) { + + return controller_lock_mutex(is_normal, check, controller_thread_timeout_lock_read_seconds_d, controller_thread_timeout_lock_read_nanoseconds_d, thread, mutex); + } +#endif // _di_controller_lock_mutex_standard_ + #ifndef _di_controller_lock_mutex_instance_ f_status_t controller_lock_mutex_instance(controller_instance_t * const instance, f_thread_mutex_t * const mutex) { - if (!instance || !mutex) return F_status_set_error(F_parameter); + if (!instance) return F_status_set_error(F_parameter); - return controller_lock_mutex(instance->type != controller_instance_type_exit_e, F_true, &instance->main->thread, mutex); + return controller_lock_mutex_standard(instance->type != controller_instance_type_exit_e, F_true, &instance->main->thread, mutex); } #endif // _di_controller_lock_mutex_instance_ #ifndef _di_controller_lock_read_ - f_status_t controller_lock_read(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_lock_t * const lock) { + f_status_t controller_lock_read(const uint8_t is_normal, const uint8_t check, const time_t seconds, const long nanoseconds, controller_thread_t * const thread, f_thread_lock_t * const lock) { if (!thread || !lock) return F_status_set_error(F_parameter); @@ -129,12 +141,17 @@ extern "C" { memset(&time, 0, sizeof(f_time_spec_t)); - controller_time_now(controller_thread_timeout_lock_read_seconds_d, controller_thread_timeout_lock_read_nanoseconds_d, &time); + controller_time_now(seconds, nanoseconds, &time); status = f_thread_lock_read_timed(&time, lock); if (status == F_time) { - if (check && !controller_thread_enable_is(thread, is_normal)) return F_status_set_error(F_interrupt); + if (check) { + if (check == 0x2) { + if (F_status_is_error(status)) return status; + } + else if (!controller_thread_enable_is(thread, is_normal)) return F_status_set_error(F_interrupt); + } } else if (status == F_okay) { break; @@ -145,17 +162,24 @@ extern "C" { } #endif // _di_controller_lock_read_ +#ifndef _di_controller_lock_read_standard_ + f_status_t controller_lock_read_standard(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_lock_t * const lock) { + + return controller_lock_read(is_normal, check, controller_thread_timeout_lock_read_seconds_d, controller_thread_timeout_lock_read_nanoseconds_d, thread, lock); + } +#endif // _di_controller_lock_read_standard_ + #ifndef _di_controller_lock_read_instance_ f_status_t controller_lock_read_instance(controller_instance_t * const instance, f_thread_lock_t * const lock) { - if (!instance || !instance->main || !lock) return F_status_set_error(F_parameter); + if (!instance || !instance->main) return F_status_set_error(F_parameter); - return controller_lock_read(instance->type != controller_instance_type_exit_e, F_true, &instance->main->thread, lock); + return controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_true, &instance->main->thread, lock); } #endif // _di_controller_lock_read_instance_ #ifndef _di_controller_lock_write_ - f_status_t controller_lock_write(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_lock_t * const lock) { + f_status_t controller_lock_write(const uint8_t is_normal, const uint8_t check, const time_t seconds, const long nanoseconds, controller_thread_t * const thread, f_thread_lock_t * const lock) { if (!thread || !lock) return F_status_set_error(F_parameter); @@ -163,12 +187,17 @@ extern "C" { for (f_time_spec_t time; ; ) { - controller_time_now(controller_thread_timeout_lock_write_seconds_d, controller_thread_timeout_lock_write_nanoseconds_d, &time); + controller_time_now(seconds, nanoseconds, &time); status = f_thread_lock_write_timed(&time, lock); if (status == F_time) { - if (check && !controller_thread_enable_is(thread, is_normal)) return F_status_set_error(F_interrupt); + if (check) { + if (check == 0x2) { + if (F_status_is_error(status)) return status; + } + else if (!controller_thread_enable_is(thread, is_normal)) return F_status_set_error(F_interrupt); + } } else if (status == F_okay) { break; @@ -179,12 +208,19 @@ extern "C" { } #endif // _di_controller_lock_write_ +#ifndef _di_controller_lock_write_standard_ + f_status_t controller_lock_write_standard(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_lock_t * const lock) { + + return controller_lock_write(is_normal, check, controller_thread_timeout_lock_write_seconds_d, controller_thread_timeout_lock_write_nanoseconds_d, thread, lock); + } +#endif // _di_controller_lock_write_standard_ + #ifndef _di_controller_lock_write_instance_ f_status_t controller_lock_write_instance(controller_instance_t * const instance, f_thread_lock_t * const lock) { - if (!instance || !lock) return F_status_set_error(F_parameter); + if (!instance) return F_status_set_error(F_parameter); - return controller_lock_write(instance->type != controller_instance_type_exit_e, F_true, &instance->main->thread, lock); + return controller_lock_write_standard(instance->type != controller_instance_type_exit_e, F_true, &instance->main->thread, lock); } #endif // _di_controller_lock_write_instance_ diff --git a/sources/c/program/controller/main/lock.h b/sources/c/program/controller/main/lock.h index 6f53642..4c33330 100644 --- a/sources/c/program/controller/main/lock.h +++ b/sources/c/program/controller/main/lock.h @@ -47,9 +47,14 @@ extern "C" { * @param is_normal * If TRUE, then perform as if this operates during a normal operation (Entry and Control). * If FALSE, then perform as if this operates during a an Exit operation. + * IF 0x2, then this is is also TRUE, but it does not call controller_thread_enable_is() and returns on any lock error. * @param check * If TRUE, then check if the state is enabled and if it is not then abort. * If FALSE, then do not check if the state is enabled and keep looping. + * @param seconds + * The seconds to add to current time. + * @param nanoseconds + * The nanoseconds to add to current time. * @param thread * The thread data used to determine if the main thread is disabled or not. * @@ -72,10 +77,42 @@ extern "C" { * @see f_thread_mutex_lock_timed() */ #ifndef _di_controller_lock_mutex_ - extern f_status_t controller_lock_mutex(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_mutex_t * const mutex); + extern f_status_t controller_lock_mutex(const uint8_t is_normal, const uint8_t check, const time_t seconds, const long nanoseconds, controller_thread_t * const thread, f_thread_mutex_t * const mutex); #endif // _di_controller_lock_mutex_ /** + * Wait to get a mutex lock, using standard seconds and nanoseconds. + * + * Given a mutex lock, periodically check to see if main thread is disabled while waiting. + * + * @param is_normal + * If TRUE, then perform as if this operates during a normal operation (Entry and Control). + * If FALSE, then perform as if this operates during a an Exit operation. + * IF 0x2, then this is is also TRUE, but it does not call controller_thread_enable_is() and returns on any lock error. + * @param check + * If TRUE, then check if the state is enabled and if it is not then abort. + * If FALSE, then do not check if the state is enabled and keep looping. + * @param thread + * The thread data used to determine if the main thread is disabled or not. + * + * Must not be NULL. + * @param mutex + * The mutex to lock. + * + * Must not be NULL. + * + * @return + * Status from: controller_lock_mutex(). + * + * Errors (with error bit) from: controller_lock_mutex(). + * + * @see controller_lock_mutex() + */ +#ifndef _di_controller_lock_mutex_standard_ + extern f_status_t controller_lock_mutex_standard(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_mutex_t * const mutex); +#endif // _di_controller_lock_mutex_standard_ + +/** * Wait to get a mutex lock for some instance. * * Given a mutex lock, periodically check to see if main thread is disabled while waiting. @@ -113,6 +150,11 @@ extern "C" { * @param check * If TRUE, then check if the state is enabled and if it is not then abort. * If FALSE, then do not check if the state is enabled and keep looping. + * IF 0x2, then this is is also TRUE, but it does not call controller_thread_enable_is() and returns on any lock error. + * @param seconds + * The seconds to add to current time. + * @param nanoseconds + * The nanoseconds to add to current time. * @param thread * The thread data used to determine if the main thread is disabled or not. * @@ -135,10 +177,42 @@ extern "C" { * @see f_thread_lock_read_timed() */ #ifndef _di_controller_lock_read_ - extern f_status_t controller_lock_read(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_lock_t * const lock); + extern f_status_t controller_lock_read(const uint8_t is_normal, const uint8_t check, const time_t seconds, const long nanoseconds, controller_thread_t * const thread, f_thread_lock_t * const lock); #endif // _di_controller_lock_read_ /** + * Wait to get a read lock, using standard seconds and nanoseconds. + * + * Given a r/w lock, periodically check to see if main thread is disabled while waiting. + * + * @param is_normal + * If TRUE, then perform as if this operates during a normal operation (Entry and Control). + * If FALSE, then perform as if this operates during a an Exit operation. + * @param check + * If TRUE, then check if the state is enabled and if it is not then abort. + * If FALSE, then do not check if the state is enabled and keep looping. + * IF 0x2, then this is is also TRUE, but it does not call controller_thread_enable_is() and returns on any lock error. + * @param thread + * The thread data used to determine if the main thread is disabled or not. + * + * Must not be NULL. + * @param lock + * The r/w lock to obtain a read lock on. + * + * Must not be NULL. + * + * @return + * Status from: controller_lock_read(). + * + * Errors (with error bit) from: controller_lock_read(). + * + * @see controller_lock_read() + */ +#ifndef _di_controller_lock_read_standard_ + extern f_status_t controller_lock_read_standard(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_lock_t * const lock); +#endif // _di_controller_lock_read_standard_ + +/** * Wait to get a read lock for some instance. * * Given a r/w lock, periodically check to see if main thread is disabled while waiting. @@ -176,6 +250,11 @@ extern "C" { * @param check * If TRUE, then check if the state is enabled and if it is not then abort. * If FALSE, then do not check if the state is enabled and keep looping. + * IF 0x2, then this is is also TRUE, but it does not call controller_thread_enable_is() and returns on any lock error. + * @param seconds + * The seconds to add to current time. + * @param nanoseconds + * The nanoseconds to add to current time. * @param thread * The thread data used to determine if the main thread is disabled or not. * @@ -198,10 +277,42 @@ extern "C" { * @see f_thread_lock_write_timed() */ #ifndef _di_controller_lock_write_ - extern f_status_t controller_lock_write(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_lock_t * const lock); + extern f_status_t controller_lock_write(const uint8_t is_normal, const uint8_t check, const time_t seconds, const long nanoseconds, controller_thread_t * const thread, f_thread_lock_t * const lock); #endif // _di_controller_lock_write_ /** + * Wait to get a write lock, using standard seconds and nanoseconds. + * + * Given a r/w lock, periodically check to see if main thread is disabled while waiting. + * + * @param is_normal + * If TRUE, then perform as if this operates during a normal operation (Entry and Control). + * If FALSE, then perform as if this operates during a an Exit operation. + * @param check + * If TRUE, then check if the state is enabled and if it is not then abort. + * If FALSE, then do not check if the state is enabled and keep looping. + * IF 0x2, then this is is also TRUE, but it does not call controller_thread_enable_is() and returns on any lock error. + * @param thread + * The thread data used to determine if the main thread is disabled or not. + * + * Must not be NULL. + * @param lock + * The r/w lock to obtain a write lock on. + * + * Must not be NULL. + * + * @return + * Status from: controller_lock_write(). + * + * Errors (with error bit) from: controller_lock_write(). + * + * @see controller_lock_write() + */ +#ifndef _di_controller_lock_write_standard_ + extern f_status_t controller_lock_write_standard(const uint8_t is_normal, const uint8_t check, controller_thread_t * const thread, f_thread_lock_t * const lock); +#endif // _di_controller_lock_write_standard_ + +/** * Wait to get a write lock for some instance. * * Given a r/w lock, periodically check to see if main thread is disabled while waiting. diff --git a/sources/c/program/controller/main/rule/execute.c b/sources/c/program/controller/main/rule/execute.c index 93b72cb..94bd07d 100644 --- a/sources/c/program/controller/main/rule/execute.c +++ b/sources/c/program/controller/main/rule/execute.c @@ -410,7 +410,7 @@ extern "C" { success = F_false; if (F_status_set_fine(status) == F_lock_read) { - status = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock); + status = controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock); if (status != F_okay) return F_status_set_error(F_lock_read); status = F_status_set_error(F_lock); @@ -440,7 +440,7 @@ extern "C" { f_execute_result_t result = f_execute_result_t_initialize; // @fixme Lock the instance.childs.used with write access. (active should already have a read lock) - //status = controller_lock_write(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock); + //status = controller_lock_write_standard(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock); //if (status != F_okay) return F_status_set_error(F_lock_read); status = f_memory_array_increase(controller_allocation_small_d, sizeof(pid_t), (void **) &instance->childs.array, &instance->childs.used, &instance->childs.size); @@ -491,7 +491,7 @@ extern "C" { if (F_status_is_error(status_lock)) { controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false); - status_lock = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &instance->main->thread, &instance->lock); + status_lock = controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_false, &instance->main->thread, &instance->lock); if (status_lock != F_okay) return F_status_set_error(F_lock_read); return F_status_set_error(F_lock); @@ -510,7 +510,7 @@ extern "C" { // Try again, after the first interrupt. if (F_status_set_fine(status_lock) == F_interrupt) { - status_lock = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &instance->main->thread, &instance->lock); + status_lock = controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_false, &instance->main->thread, &instance->lock); } if (status_lock != F_okay) { @@ -606,7 +606,7 @@ extern "C" { f_execute_result_t result = f_execute_result_t_initialize; // @fixme Lock the instance.childs.used with write access. (active should already have a read lock) - //status = controller_lock_write(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock); + //status = controller_lock_write_standard(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock); //if (status != F_okay) return F_status_set_error(F_lock_read); status = f_memory_array_increase(controller_allocation_small_d, sizeof(pid_t), (void **) &instance->childs.array, &instance->childs.used, &instance->childs.size); @@ -685,7 +685,7 @@ extern "C" { if (status_lock != F_okay) { controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false); - status_lock = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &instance->main->thread, &instance->lock); + status_lock = controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_false, &instance->main->thread, &instance->lock); if (status_lock != F_okay) return F_status_set_error(F_lock_read); return F_status_set_error(F_lock); @@ -710,7 +710,7 @@ extern "C" { if (status_lock != F_okay) { controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false); - status_lock = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &instance->main->thread, &instance->lock); + status_lock = controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_false, &instance->main->thread, &instance->lock); if (status_lock != F_okay) return F_status_set_error(F_lock_read); return F_status_set_error(F_lock); diff --git a/sources/c/program/controller/main/rule/instance.c b/sources/c/program/controller/main/rule/instance.c index 932c087..717185f 100644 --- a/sources/c/program/controller/main/rule/instance.c +++ b/sources/c/program/controller/main/rule/instance.c @@ -407,7 +407,7 @@ extern "C" { if (F_status_is_error(status_lock)) { controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false); - status_lock = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock); + status_lock = controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock); if (status_lock != F_okay) return F_status_set_error(F_lock_read); return F_status_set_error(F_lock); @@ -428,7 +428,7 @@ extern "C" { // Remove the write lock and restore the read lock. f_thread_unlock(&instance->lock); - status_lock = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock); + status_lock = controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock); if (status_lock != F_okay) return F_status_set_error(F_lock_read); return F_status_set_error(F_lock); @@ -459,7 +459,7 @@ extern "C" { if (F_status_is_error(status_lock)) { controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_true); - status_lock = controller_lock_read(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock); + status_lock = controller_lock_read_standard(instance->type != controller_instance_type_exit_e, F_false, &main->thread, &instance->lock); if (status_lock != F_okay) return F_status_set_error(F_lock_read); return F_status_set_error(F_lock); @@ -475,7 +475,7 @@ extern "C" { if (!main || !cache) return F_status_set_error(F_parameter); if (!controller_thread_is_enabled_instance_type(&main->thread, type)) return F_status_set_error(F_interrupt); - f_status_t status = controller_lock_read(type != controller_instance_type_exit_e, F_true, &main->thread, &main->thread.lock.instance); + f_status_t status = controller_lock_read_standard(type != controller_instance_type_exit_e, F_true, &main->thread, &main->thread.lock.instance); if (status != F_okay) { controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status), F_true); @@ -497,7 +497,7 @@ extern "C" { controller_instance_t * const instance = main->thread.instances.array[at]; - status = controller_lock_read(type != controller_instance_type_exit_e, F_true, &main->thread, &instance->active); + status = controller_lock_read_standard(type != controller_instance_type_exit_e, F_true, &main->thread, &instance->active); if (status != F_okay) { controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status), F_true); diff --git a/sources/c/program/controller/main/rule/instance.h b/sources/c/program/controller/main/rule/instance.h index e3fb6f8..6b1b371 100644 --- a/sources/c/program/controller/main/rule/instance.h +++ b/sources/c/program/controller/main/rule/instance.h @@ -42,8 +42,11 @@ extern "C" { * F_lock (with error bit) if failed to establish a lock, and the instance->lock read lock is already restored. * F_lock_read (with error bit) if failed to re-establish read lock on instance->lock while returning. * - * Errors (with error bit) from: controller_lock_read(). - * Errors (with error bit) from: controller_lock_write(). + * Errors (with error bit) from: controller_lock_read_standard(). + * Errors (with error bit) from: controller_lock_write_instance(). + * + * @see controller_lock_read_standard(). + * @see controller_lock_write_instance(). */ #ifndef _di_controller_rule_instance_ extern f_status_t controller_rule_instance(controller_instance_t * const instance); diff --git a/sources/c/program/controller/main/rule/wait.c b/sources/c/program/controller/main/rule/wait.c index 93ecae2..701e0d1 100644 --- a/sources/c/program/controller/main/rule/wait.c +++ b/sources/c/program/controller/main/rule/wait.c @@ -9,7 +9,7 @@ extern "C" { if (!main) return F_status_set_error(F_parameter); - f_status_t status_lock = controller_lock_read(is_normal, F_false, &main->thread, &main->thread.lock.instance); + f_status_t status_lock = controller_lock_read_standard(is_normal, F_false, &main->thread, &main->thread.lock.instance); if (status_lock != F_okay) { controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_true); @@ -45,7 +45,7 @@ extern "C" { if (!controller_thread_enable_is(&main->thread, is_normal)) break; // Re-establish instance read lock to wait for or protect from the cleanup thread while checking the read instance. - status_lock = controller_lock_read(is_normal, F_true, &main->thread, &main->thread.lock.instance); + status_lock = controller_lock_read_standard(is_normal, F_true, &main->thread, &main->thread.lock.instance); if (status_lock != F_okay) break; if (!instance_list[i]) { @@ -54,7 +54,7 @@ extern "C" { continue; } - status_lock = controller_lock_read(is_normal, F_true, &main->thread, &instance_list[i]->active); + status_lock = controller_lock_read_standard(is_normal, F_true, &main->thread, &instance_list[i]->active); if (status_lock != F_okay) { f_thread_unlock(&main->thread.lock.instance); @@ -65,7 +65,7 @@ extern "C" { // Once the active lock is obtained, then the main instance read lock can be safely released. f_thread_unlock(&main->thread.lock.instance); - status_lock = controller_lock_read(is_normal, F_true, &main->thread, &instance_list[i]->lock); + status_lock = controller_lock_read_standard(is_normal, F_true, &main->thread, &instance_list[i]->lock); if (status_lock != F_okay) { f_thread_unlock(&instance_list[i]->active); @@ -87,7 +87,7 @@ extern "C" { if (instance_list[i]->state == controller_instance_state_done_e) { f_thread_unlock(&instance_list[i]->lock); - status_lock = controller_lock_write(is_normal, F_true, &main->thread, &instance_list[i]->lock); + status_lock = controller_lock_write_standard(is_normal, F_true, &main->thread, &instance_list[i]->lock); if (status_lock != F_okay) { controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false); @@ -109,7 +109,7 @@ extern "C" { f_thread_condition_signal_all(&instance_list[i]->wait_condition); } - status_lock = controller_lock_read(is_normal, F_true, &main->thread, &instance_list[i]->active); + status_lock = controller_lock_read_standard(is_normal, F_true, &main->thread, &instance_list[i]->active); if (status_lock != F_okay) { f_thread_unlock(&instance_list[i]->lock); @@ -120,7 +120,7 @@ extern "C" { f_thread_unlock(&instance_list[i]->lock); - status_lock = controller_lock_read(is_normal, F_true, &main->thread, &instance_list[i]->lock); + status_lock = controller_lock_read_standard(is_normal, F_true, &main->thread, &instance_list[i]->lock); if (status_lock != F_okay) break; } @@ -157,7 +157,7 @@ extern "C" { break; } - status_lock = controller_lock_read(is_normal, F_true, &main->thread, &instance_list[i]->lock); + status_lock = controller_lock_read_standard(is_normal, F_true, &main->thread, &instance_list[i]->lock); if (status_lock != F_okay) { f_thread_unlock(&instance_list[i]->active); diff --git a/sources/c/program/controller/main/thread/instance.c b/sources/c/program/controller/main/thread/instance.c index e446e65..df4ab6e 100644 --- a/sources/c/program/controller/main/thread/instance.c +++ b/sources/c/program/controller/main/thread/instance.c @@ -28,25 +28,8 @@ extern "C" { if (!main) return; - f_status_t status = F_okay; - - { - f_time_spec_t time; - - do { - if (!controller_thread_enable_is(&main->thread, is_normal)) return; - - memset((void *) &time, 0, sizeof(struct timespec)); - - controller_time_now(controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &time); - - status = f_thread_mutex_lock_timed(&time, &main->thread.lock.cancel); - if (F_status_is_error(status)) return; - - } while (status != F_okay); - - status = F_okay; - } + f_status_t status = controller_lock_mutex(is_normal, 0x2, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &main->thread.lock.cancel); + if (F_status_is_error(status)) return; // Only cancel when enabled. if (!controller_thread_enable_is(&main->thread, is_normal)) { @@ -71,6 +54,8 @@ extern "C" { time.tv_nsec = interval_nanoseconds; if (main->process.mode == controller_process_mode_helper_e && !(main->setting.flag & controller_main_flag_validate_d)) { + controller_lock_read(is_normal, F_false, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &main->thread.lock.instance); + for (i = 0; i < main->thread.instances.used; ++i) { if (!main->thread.instances.array[i]) continue; @@ -83,6 +68,8 @@ extern "C" { instance->id_thread = 0; } // for + + f_thread_unlock(&main->thread.lock.instance); } { @@ -129,6 +116,14 @@ extern "C" { return; } + status = controller_lock_read(is_normal, F_false, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &main->thread.lock.instance); + + if (F_status_is_error(status)) { + f_thread_mutex_unlock(&main->thread.lock.cancel); + + return; + } + for (int signal = 0; i < main->thread.instances.used; ++i) { if (!main->thread.instances.array[i]) continue; @@ -152,7 +147,7 @@ extern "C" { for (j = 0; j < instance->path_pids.used; ++j) { if (instance->path_pids.array[j].used && f_file_exists(instance->path_pids.array[j], F_true) == F_true) { - status = controller_file_pid_read(instance->path_pids.array[j], &pid); + controller_file_pid_read(instance->path_pids.array[j], &pid); if (pid) { signal = controller_thread_signal_get(&main->thread); @@ -163,9 +158,13 @@ extern "C" { } // for } // for + f_thread_unlock(&main->thread.lock.instance); + if (entry->timeout_exit && !(entry->flag & controller_entry_flag_timeout_exit_no_e)) { f_number_unsigned_t lapsed = 0; + controller_lock_read(is_normal, F_false, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &main->thread.lock.instance); + for (i = 0; i < main->thread.instances.used && lapsed < entry->timeout_exit; ++i) { if (!main->thread.instances.array[i]) continue; @@ -201,7 +200,7 @@ extern "C" { for (j = 0; j < instance->path_pids.used && lapsed < entry->timeout_exit; ++j) { if (instance->path_pids.array[j].used && f_file_exists(instance->path_pids.array[j], F_true) == F_true) { - status = controller_file_pid_read(instance->path_pids.array[j], &pid); + controller_file_pid_read(instance->path_pids.array[j], &pid); if (pid) { while (lapsed < entry->timeout_exit) { @@ -225,16 +224,33 @@ extern "C" { } } // for } // for + + f_thread_unlock(&main->thread.lock.instance); + } + + status = controller_lock_read(is_normal, F_false, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &main->thread.lock.instance); + + if (F_status_is_error(status)) { + f_thread_mutex_unlock(&main->thread.lock.cancel); + + return; } for (i = 0; i < main->thread.instances.size; ++i) { if (!main->thread.instances.array[i]) continue; + status = controller_lock_read(is_normal, F_false, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &main->thread.instances.array[i]->active); + if (F_status_is_error(status)) continue; + instance = main->thread.instances.array[i]; // Do not kill Exit Instances, when not performing "execute" during exit. - if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) continue; + if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) { + f_thread_unlock(&instance->active); + + continue; + } if (instance->id_thread) { if (instance->childs.used) { @@ -271,7 +287,11 @@ extern "C" { f_signal_send(F_signal_kill, instance->childs.array[j]); } + status = controller_lock_write(is_normal, F_false, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &instance->lock); + instance->childs.array[j] = 0; + + if (F_status_is_error_not(status)) f_thread_unlock(&instance->lock); } } // for } @@ -283,39 +303,53 @@ extern "C" { if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) continue; if (f_file_exists(instance->path_pids.array[j], F_true) == F_true) { - status = controller_file_pid_read(instance->path_pids.array[j], &pid); + controller_file_pid_read(instance->path_pids.array[j], &pid); if (pid) { f_signal_send(F_signal_kill, pid); } + status = controller_lock_write(is_normal, F_false, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &instance->lock); + f_file_remove(instance->path_pids.array[j]); instance->path_pids.array[j].used = 0; + + if (F_status_is_error_not(status)) f_thread_unlock(&instance->lock); } } // for } - // Shrink the child pids as much as possible. - while (instance->childs.used) { + status = controller_lock_write(is_normal, F_false, controller_thread_timeout_cancel_seconds_d, controller_thread_timeout_cancel_nanoseconds_d, &main->thread, &instance->lock); - // Do not shrink below an Exit Instances, when not performing "execute" during exit. - if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) break; - if (instance->childs.array[j] > 0) break; + if (F_status_is_error_not(status)) { - --instance->childs.used; - } // while + // Shrink the child pids as much as possible. + while (instance->childs.used) { - // Shrink the path pids as much as possible. - while (instance->path_pids.used) { + // Do not shrink below an Exit Instances, when not performing "execute" during exit. + if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) break; + if (instance->childs.array[j] > 0) break; - // Do not shrink below an Exit Instances, when not performing "execute" during exit. - if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) break; - if (instance->path_pids.array[j].used) break; + --instance->childs.used; + } // while + + // Shrink the path pids as much as possible. + while (instance->path_pids.used) { + + // Do not shrink below an Exit Instances, when not performing "execute" during exit. + if (instance->type == controller_instance_type_exit_e && controller_thread_enable_get(&main->thread) != controller_thread_enable_exit_execute_e) break; + if (instance->path_pids.array[j].used) break; + + --instance->path_pids.used; + } // while + + f_thread_unlock(&instance->lock); + } - --instance->path_pids.used; - } // while + f_thread_unlock(&instance->active); } // for + f_thread_unlock(&main->thread.lock.instance); f_thread_mutex_unlock(&main->thread.lock.cancel); } #endif // _di_controller_thread_instance_cancel_