From: Kevin Day Date: Sat, 13 Jul 2024 05:10:03 +0000 (-0500) Subject: Progress: Continue migrating the project. X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=ae9ab7e8fb40ed207badb6985cd612914957505e;p=controller Progress: Continue migrating the project. --- diff --git a/data/data/controller/example/miscellaneous/rules/utility/sleeper_1.rule b/data/data/controller/example/miscellaneous/rules/utility/sleeper_1.rule index 9aafe87..3a84e5f 100644 --- a/data/data/controller/example/miscellaneous/rules/utility/sleeper_1.rule +++ b/data/data/controller/example/miscellaneous/rules/utility/sleeper_1.rule @@ -19,7 +19,7 @@ utility: echo "$BASHPID" > /tmp/sleeper_1.pid echo "Sleeper 1, now sleeping." - sleep 20m + sleep 1m echo "Sleeper 1, done sleeping." rm -f /tmp/sleeper_1.pid diff --git a/data/data/controller/example/miscellaneous/rules/utility/sleeper_2.rule b/data/data/controller/example/miscellaneous/rules/utility/sleeper_2.rule index 2bc5cfc..d44d332 100644 --- a/data/data/controller/example/miscellaneous/rules/utility/sleeper_2.rule +++ b/data/data/controller/example/miscellaneous/rules/utility/sleeper_2.rule @@ -19,7 +19,7 @@ utility: echo "$BASHPID" > /tmp/sleeper_2.pid echo "Sleeper 2, now sleeping." - sleep 25m + sleep 2m echo "Sleeper 2, done sleeping." rm -f /tmp/sleeper_2.pid diff --git a/data/data/controller/example/miscellaneous/rules/utility/sleeper_3.rule b/data/data/controller/example/miscellaneous/rules/utility/sleeper_3.rule index 07ba570..04c8900 100644 --- a/data/data/controller/example/miscellaneous/rules/utility/sleeper_3.rule +++ b/data/data/controller/example/miscellaneous/rules/utility/sleeper_3.rule @@ -19,7 +19,7 @@ utility: echo "$BASHPID" > /tmp/sleeper_3.1.pid echo "Sleeper 3.1, now sleeping." - sleep 15 + sleep 10 echo "Sleeper 3.1, done sleeping." rm -f /tmp/sleeper_3.1.pid diff --git a/sources/c/main/common.c b/sources/c/main/common.c index d9360d5..907efdd 100644 --- a/sources/c/main/common.c +++ b/sources/c/main/common.c @@ -7,32 +7,44 @@ extern "C" { #ifndef _di_controller_error_simplify_ f_status_t controller_error_simplify(const f_status_t status) { - if (status == F_memory_not) { - return F_status_set_error(F_memory); - } - - if (status == F_file_open_max || status == F_space_not || status == F_busy) { - return F_status_set_error(F_resource); - } - - if (status == F_access_denied || status == F_filesystem_quota_block || status == F_prohibited || status == F_input_output) { - return F_status_set_error(F_access); - } - - if (status == F_complete_not_utf || status == F_complete_not_utf_block || status == F_complete_not_utf_eof || status == F_complete_not_utf_eol || status == F_complete_not_utf_eos || status == F_complete_not_utf_stop) { - return F_status_set_error(F_encoding); - } - - if (status == F_number || status == F_number_negative || status == F_number_positive || status == F_number_overflow) { - return F_status_set_error(F_number); - } - - if (status == F_parameter || status == F_found_not || status == F_interrupt || status == F_support_not || status == F_critical) { - return F_status_set_error(status); - } - - if (status == F_valid_not) { - return F_status_set_error(F_valid_not); + switch (status) { + case F_memory_not: + return F_status_set_error(F_memory); + + case F_file_open_max: + case F_space_not: + case F_busy: + return F_status_set_error(F_resource); + + case F_access_denied: + case F_filesystem_quota_block: + case F_prohibited: + case F_input_output: + return F_status_set_error(F_access); + + case F_complete_not_utf: + case F_complete_not_utf_block: + case F_complete_not_utf_eof: + case F_complete_not_utf_eol: + case F_complete_not_utf_eos: + case F_complete_not_utf_stop: + return F_status_set_error(F_encoding); + + case F_number: + case F_number_negative: + case F_number_positive: + case F_number_overflow: + return F_status_set_error(F_number); + + case F_parameter: + case F_found_not: + case F_interrupt: + case F_support_not: + case F_critical: + return F_status_set_error(status); + + case F_valid_not: + return F_status_set_error(F_valid_not); } return F_status_set_error(F_failure); @@ -127,7 +139,7 @@ extern "C" { memset(&main->process.control.server.address, 0, sizeof(f_socket_address_t)); { - const uint8_t codes[] = { + const f_number_unsigned_t codes[] = { controller_parameter_cgroup_e, controller_parameter_pid_e, controller_parameter_settings_e, @@ -141,16 +153,28 @@ extern "C" { controller_long_socket_s, }; + const uint16_t flags[] = { + 0, + controller_main_flag_pid_e, + 0, + 0, + }; + + main->setting.state.status = F_okay; + for (index = 0; index < 4; ++index) { if (main->program.parameters.array[codes[index]].result & f_console_result_found_e) { main->setting.state.status = F_status_set_error(F_parameter); fll_program_print_error_parameter_missing_value(&main->program.error, f_console_symbol_long_normal_s, strings[index]); - - return; + } + else if (main->program.parameters.array[codes[index]].result & f_console_result_value_e) { + if (flags[index]) main->setting.flag |= flags[index]; } } // for + + if (F_status_is_error(main->setting.state.status)) return; } // The first remaining argument represents the Entry name. @@ -170,6 +194,24 @@ extern "C" { return; } + { + const f_number_unsigned_t codes[] = { + controller_parameter_daemon_e, + controller_parameter_simulate_e, + controller_parameter_validate_e, + }; + + const uint16_t flags[] = { + controller_main_flag_daemon_e, + controller_main_flag_simulate_e, + controller_main_flag_validate_e, + }; + + for (index = 0; index < 3; ++index) { + if (main->program.parameters.array[codes[index]].result & f_console_result_value_e) main->setting.flag |= flags[index]; + } // for + } + main->process.path_setting.used = 0; if (main->program.parameters.array[controller_parameter_settings_e].locations.used) { @@ -193,10 +235,6 @@ extern "C" { } } - if (main->program.parameters.array[controller_parameter_pid_e].result & f_console_result_value_e) { - main->setting.flag |= controller_main_flag_pid_e; - } - if (!main->process.path_pid.used && !(main->setting.flag & controller_main_flag_pid_e)) { main->setting.state.status = f_string_dynamic_append(controller_default_path_pid_s, &main->process.path_pid); @@ -285,18 +323,6 @@ extern "C" { else if (main->program.parameters.array[controller_parameter_uninterruptible_e].result & f_console_result_found_e) { main->setting.flag &= ~controller_main_flag_interruptible_e; } - - if (main->program.parameters.array[controller_parameter_daemon_e].result & f_console_result_found_e) { - main->setting.flag |= controller_main_flag_daemon_e; - } - - if (main->program.parameters.array[controller_parameter_simulate_e].result & f_console_result_found_e) { - main->setting.flag |= controller_main_flag_simulate_e; - } - - if (main->program.parameters.array[controller_parameter_validate_e].result & f_console_result_found_e) { - main->setting.flag |= controller_main_flag_validate_e; - } } #endif // _di_controller_setting_load_ diff --git a/sources/c/main/common/define.h b/sources/c/main/common/define.h index 47898e4..817d1d9 100644 --- a/sources/c/main/common/define.h +++ b/sources/c/main/common/define.h @@ -66,6 +66,26 @@ extern "C" { #define controller_with_session_same_d 0x4 #endif // _di_controller_with_d_ +/** + * 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_ + +/** + * Flags associated with Controller locks. + * + * controller_lock_flag_*_d: + * - setup_not: No locks are initialized, so do not attempt to deallocate them. + */ +#ifndef _di_controller_lock_flag_d_ + #define controller_lock_flag_setup_not_d 0x1 +#endif // _di_controller_lock_flag_d_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/sources/c/main/common/type/lock.c b/sources/c/main/common/type/lock.c index 3882982..e7e4454 100644 --- a/sources/c/main/common/type/lock.c +++ b/sources/c/main/common/type/lock.c @@ -7,6 +7,8 @@ extern "C" { #ifndef _di_controller_lock_delete_ void controller_lock_delete(controller_lock_t * const lock) { + if (!lock || (lock->flag & controller_lock_flag_setup_not_d)) return; + f_thread_mutex_delete(&lock->alert); f_thread_mutex_delete(&lock->cancel); f_thread_mutex_delete(&lock->print); @@ -15,15 +17,6 @@ extern "C" { f_thread_lock_delete(&lock->rule); f_thread_condition_delete(&lock->alert_condition); - - memset(&lock->alert, 0, sizeof(f_thread_mutex_t)); - memset(&lock->cancel, 0, sizeof(f_thread_mutex_t)); - memset(&lock->print, 0, sizeof(f_thread_mutex_t)); - - memset(&lock->instance, 0, sizeof(f_thread_lock_t)); - memset(&lock->rule, 0, sizeof(f_thread_lock_t)); - - memset(&lock->alert_condition, 0, sizeof(f_thread_condition_t)); } #endif // _di_controller_lock_delete_ diff --git a/sources/c/main/common/type/lock.h b/sources/c/main/common/type/lock.h index 32f749b..0f368ee 100644 --- a/sources/c/main/common/type/lock.h +++ b/sources/c/main/common/type/lock.h @@ -26,6 +26,7 @@ extern "C" { * The Rule lock is intended to lock any activity on the rules structure. * * Properties: + * - flag: A set of flags associated with the locks. * - alert: The alert mutex lock for waking up on alerts. * - cancel: The cancel mutex lock for locking the cancel operation. * - print: The print mutex lock. @@ -35,6 +36,8 @@ extern "C" { */ #ifndef _di_controller_lock_t_ typedef struct { + uint8_t flag; + f_thread_mutex_t alert; f_thread_mutex_t cancel; f_thread_mutex_t print; @@ -46,6 +49,7 @@ extern "C" { } controller_lock_t; #define controller_lock_t_initialize { \ + 0, \ f_thread_mutex_t_initialize, \ f_thread_mutex_t_initialize, \ f_thread_mutex_t_initialize, \ diff --git a/sources/c/main/common/type/thread.h b/sources/c/main/common/type/thread.h index e33fb0e..1d17bae 100644 --- a/sources/c/main/common/type/thread.h +++ b/sources/c/main/common/type/thread.h @@ -23,6 +23,9 @@ extern "C" { * * The "enabled" and "signal" utilize the lock: lock.process. * + * The lock.alert must be used when writing to any of: + * - enabled. + * * The typedef for this is located in the defs.h header. * * Properties: diff --git a/sources/c/main/convert.h b/sources/c/main/convert.h index 7f26d45..6f7e6bb 100644 --- a/sources/c/main/convert.h +++ b/sources/c/main/convert.h @@ -19,15 +19,19 @@ extern "C" { /** * Convert the string from a string representation of an ID or a user name into the numeric representation of that ID or user name. * + * @param cache + * The cache. + * + * Must not be NULL. * @param buffer - * A string containing user name or ID. + * A string containing group name or ID. * @param range * The range within the buffer specifically containing the name or ID. - * @param cache - * The cache. * @param id * The determined user ID. * + * Must not be NULL. + * * @return * F_okay on success. * @@ -49,14 +53,18 @@ extern "C" { /** * Convert the string from a string representation of an ID or a group name into the numeric representation of that ID or group name. * + * @param cache + * The cache. + * + * Must not be NULL. * @param buffer * A string containing group name or ID. * @param range * The range within the buffer specifically containing the name or ID. - * @param cache - * The cache. * @param id - * The determined group ID. + * The determined user ID. + * + * Must not be NULL. * * @return * F_okay on success. diff --git a/sources/c/main/entry.c b/sources/c/main/entry.c index 363865e..9cf731c 100644 --- a/sources/c/main/entry.c +++ b/sources/c/main/entry.c @@ -5,11 +5,13 @@ extern "C" { #endif #ifndef _di_controller_entry_read_ - f_status_t controller_entry_read(controller_t * const main, controller_entry_t * const entry) { + f_status_t controller_entry_read(controller_t * const main, const uint8_t is_entry) { if (!main) return F_status_set_error(F_parameter); - controller_interrupt_t custom = macro_controller_interrupt_t_initialize_1(entry->flag & controller_entry_flag_is_e, main); + controller_entry_t * const entry = is_entry ? &main->process.entry : &main->process.exit; + + controller_interrupt_t custom = macro_controller_interrupt_t_initialize_1(is_entry, main); f_state_t state = macro_f_state_t_initialize_1(controller_allocation_large_d, controller_allocation_small_d, F_okay, 0, 0, 0, &controller_thread_signal_state_fss, 0, 0, 0); f_number_unsigned_t i = 0; @@ -55,12 +57,18 @@ extern "C" { main->thread.cache.action.name_item.used = 0; if (F_status_is_error_not(state.status)) { - if (entry->flag & controller_entry_flag_is_e) { + if (is_entry) { state.status = controller_file_load(main, F_true, controller_entries_s, main->process.name_entry, controller_entry_s); } else { state.status = controller_file_load(main, F_false, controller_exits_s, main->process.name_entry, controller_exit_s); - if (state.status == F_file_found_not) return F_file_found_not; + + // Immediately return on error whole loading the Exit. + if (state.status == F_file_found_not) { + entry->status = controller_status_simplify_error(F_file_found_not); + + return F_status_set_error(F_file_found_not); + } } } @@ -77,12 +85,12 @@ extern "C" { f_fss_apply_delimit(main->thread.cache.delimits, &main->thread.cache.buffer_file, &state); if (F_status_is_error(state.status)) { - controller_print_error_entry(&main->program.error, entry->flag & controller_entry_flag_is_e, F_status_set_fine(state.status), macro_controller_f(f_fss_apply_delimit), F_true); + controller_print_error_entry(&main->program.error, is_entry, F_status_set_fine(state.status), macro_controller_f(f_fss_apply_delimit), F_true); } } } else { - controller_print_error_file_status(&main->program.error, macro_controller_f(controller_file_load), (entry->flag & controller_entry_flag_is_e) ? controller_entry_s : controller_exit_s, f_file_operation_read_s, fll_error_file_type_file_e, F_status_set_fine(state.status)); + controller_print_error_file_status(&main->program.error, macro_controller_f(controller_file_load), is_entry ? controller_entry_s : controller_exit_s, f_file_operation_read_s, fll_error_file_type_file_e, F_status_set_fine(state.status)); } } @@ -90,7 +98,7 @@ extern "C" { state.status = f_memory_array_increase_by(main->thread.cache.object_items.used, sizeof(f_range_t), (void **) &main->thread.cache.object_items.array, &main->thread.cache.object_items.used, &main->thread.cache.object_items.size); if (F_status_is_error(state.status)) { - controller_print_error_entry(&main->program.error, entry->flag & controller_entry_flag_is_e, F_status_set_fine(state.status), macro_controller_f(f_memory_array_increase_by), F_true); + controller_print_error_entry(&main->program.error, is_entry, F_status_set_fine(state.status), macro_controller_f(f_memory_array_increase_by), F_true); } else { @@ -101,7 +109,7 @@ extern "C" { f_number_unsigned_t at = 0; f_number_unsigned_t j = 0; - for (i = 0; i < main->thread.cache.object_items.used && controller_thread_is_enabled(entry->flag & controller_entry_flag_is_e, &main->thread); ++i) { + for (i = 0; i < main->thread.cache.object_items.used && controller_thread_is_enabled(&main->thread, is_entry); ++i) { code &= ~0x2; at = 0; @@ -126,7 +134,7 @@ extern "C" { state.status = f_memory_array_increase(controller_allocation_small_d, sizeof(controller_entry_item_t), (void **) &entry->items.array, &entry->items.used, &entry->items.size); if (F_status_is_error(state.status)) { - controller_print_error_entry(&main->program.error, entry->flag & controller_entry_flag_is_e, F_status_set_fine(state.status), macro_controller_f(f_memory_array_increase), F_true); + controller_print_error_entry(&main->program.error, is_entry, F_status_set_fine(state.status), macro_controller_f(f_memory_array_increase), F_true); break; } @@ -134,7 +142,7 @@ extern "C" { state.status = f_string_dynamic_partial_append(main->thread.cache.buffer_file, main->thread.cache.object_items.array[i], &main->thread.cache.action.name_item); if (F_status_is_error(state.status)) { - controller_print_error_entry(&main->program.error, entry->flag & controller_entry_flag_is_e, F_status_set_fine(state.status), macro_controller_f(f_string_dynamic_partial_append), F_true); + controller_print_error_entry(&main->program.error, is_entry, F_status_set_fine(state.status), macro_controller_f(f_string_dynamic_partial_append), F_true); break; } @@ -142,7 +150,7 @@ extern "C" { f_fss_count_lines(main->thread.cache.buffer_file, main->thread.cache.object_items.array[i].start, &main->thread.cache.action.line_item, &state); if (F_status_is_error(state.status)) { - controller_print_error_entry(&main->program.error, entry->flag & controller_entry_flag_is_e, F_status_set_fine(state.status), macro_controller_f(f_fss_count_lines), F_true); + controller_print_error_entry(&main->program.error, is_entry, F_status_set_fine(state.status), macro_controller_f(f_fss_count_lines), F_true); break; } @@ -152,7 +160,7 @@ extern "C" { for (j = (code & 0x1) ? 1 : 0; j < entry->items.used; ++j) { if (f_compare_dynamic(entry->items.array[j].name, main->thread.cache.action.name_item) == F_equal_to) { - controller_print_warning_entry_item_duplicate_ignore(&main->program.warning, &main->thread.cache, entry->flag & controller_entry_flag_is_e, main->thread.cache.action.name_item); + controller_print_warning_entry_item_duplicate_ignore(&main->program.warning, &main->thread.cache, is_entry, main->thread.cache.action.name_item); code |= 0x2; @@ -173,7 +181,7 @@ extern "C" { } } else if (f_compare_dynamic(controller_settings_s, main->thread.cache.action.name_item) == F_equal_to) { - state.status = controller_entry_setting_read(main, entry->flag & controller_entry_flag_is_e, *range); + state.status = controller_entry_setting_read(main, is_entry, *range); continue; } @@ -205,7 +213,7 @@ extern "C" { if (F_status_set_fine(state.status) != F_interrupt) { controller_lock_print(main->program.error.to, &main->thread); - controller_print_error_entry_cache(&main->program.error, &main->thread.cache.action, entry->flag & controller_entry_flag_is_e); + controller_print_error_entry_cache(&main->program.error, &main->thread.cache.action, is_entry); controller_unlock_print_flush(main->program.error.to, &main->thread); } @@ -214,13 +222,17 @@ extern "C" { } } // for - if (entry->flag & controller_entry_flag_is_e && F_status_set_fine(state.status) == F_interrupt) return state.status; + if (is_entry && F_status_set_fine(state.status) == F_interrupt) { + entry->status = controller_status_simplify_error(F_status_set_fine(state.status)); + + return state.status; + } if (F_status_is_error_not(state.status)) { if (!(code & 0x1)) { state.status = F_status_set_error(F_found_not); - controller_print_message_entry_item_required(&main->program.error, entry->flag & controller_entry_flag_is_e, main->thread.cache.action.name_item, "is not found"); + controller_print_message_entry_item_required(&main->program.error, is_entry, main->thread.cache.action.name_item, "is not found"); } main->thread.cache.action.name_action.used = 0; @@ -228,7 +240,6 @@ extern "C" { if (F_status_is_error_not(state.status)) { controller_entry_action_t *action = 0; - f_number_unsigned_t k = 0; // 0x1 = missing or not, 0x2 = one or more missing. @@ -238,7 +249,9 @@ extern "C" { for (j = 0; j < entry->items.array[i].actions.used; ++j) { - if (!controller_thread_is_enabled(entry->flag & controller_entry_flag_is_e, &main->thread)) { + if (!controller_thread_is_enabled(&main->thread, is_entry)) { + entry->status = controller_status_simplify_error(F_interrupt); + return F_status_set_error(F_interrupt); } @@ -274,7 +287,7 @@ extern "C" { break; } - controller_print_message_entry_item_required(&main->program.error, entry->flag & controller_entry_flag_is_e, main->thread.cache.action.name_item, "does not exist"); + controller_print_message_entry_item_required(&main->program.error, is_entry, main->thread.cache.action.name_item, "does not exist"); action->number = 0; action->status = controller_status_simplify_error(F_found_not); @@ -297,7 +310,7 @@ extern "C" { entry->status = controller_status_simplify_error(F_status_set_fine(state.status)); if (F_status_set_fine(state.status) != F_interrupt) { - controller_print_error_entry_cache(&main->program.error, &main->thread.cache.action, entry->flag & controller_entry_flag_is_e); + controller_print_error_entry_cache(&main->program.error, &main->thread.cache.action, is_entry); } } else { diff --git a/sources/c/main/entry.h b/sources/c/main/entry.h index c4b2f32..dc37985 100644 --- a/sources/c/main/entry.h +++ b/sources/c/main/entry.h @@ -22,11 +22,12 @@ extern "C" { * @param main * The main program data. * - * Must not be NULL. - * @param entry - * The Entry data. + * This alters either main.process.entry.state or main.process.exit.state. * * Must not be NULL. + * @param is_entry + * If TRUE, then this operates as an Entry. + * If FALSE, then this operates as an Exit. * * @return * F_okay on success. @@ -63,7 +64,7 @@ extern "C" { * @see fll_fss_basic_list_read() */ #ifndef _di_controller_entry_read_ - extern f_status_t controller_entry_read(controller_t * const main, controller_entry_t * const entry); + extern f_status_t controller_entry_read(controller_t * const main, const uint8_t is_entry); #endif // _di_controller_entry_read_ #ifdef __cplusplus diff --git a/sources/c/main/entry/preprocess.c b/sources/c/main/entry/preprocess.c index 4f0abde..c61301e 100644 --- a/sources/c/main/entry/preprocess.c +++ b/sources/c/main/entry/preprocess.c @@ -56,11 +56,11 @@ extern "C" { return status; } - while (controller_thread_is_enabled(is_entry, &main->thread)) { + while (controller_thread_is_enabled(&main->thread, is_entry)) { actions = &entry->items.array[cache->ats.array[at_i]].actions; - for (; cache->ats.array[at_j] < actions->used && controller_thread_is_enabled(is_entry, &main->thread); ++cache->ats.array[at_j]) { + for (; cache->ats.array[at_j] < actions->used && controller_thread_is_enabled(&main->thread, is_entry); ++cache->ats.array[at_j]) { cache->action.line_action = actions->array[cache->ats.array[at_j]].line; cache->action.name_action.used = 0; @@ -85,15 +85,11 @@ extern "C" { error_has = F_false; // "main" is not allowed to be used for an "item" and "setting" is not an executable "item". - if (f_compare_dynamic(controller_main_s, actions->array[cache->ats.array[at_j]].parameters.array[0]) == F_equal_to) { - continue; - } - else if (f_compare_dynamic(controller_settings_s, actions->array[cache->ats.array[at_j]].parameters.array[0]) == F_equal_to) { - continue; - } + if (f_compare_dynamic(controller_main_s, actions->array[cache->ats.array[at_j]].parameters.array[0]) == F_equal_to) continue; + else if (f_compare_dynamic(controller_settings_s, actions->array[cache->ats.array[at_j]].parameters.array[0]) == F_equal_to) continue; // Walk though each items and check to see if the item actually exists. - for (i = 1; i < entry->items.used && controller_thread_is_enabled(is_entry, &main->thread); ++i) { + for (i = 1; i < entry->items.used && controller_thread_is_enabled(&main->thread, is_entry); ++i) { if (f_compare_dynamic(entry->items.array[i].name, actions->array[cache->ats.array[at_j]].parameters.array[0]) == F_equal_to) { @@ -195,7 +191,7 @@ extern "C" { } } // while - if (!controller_thread_is_enabled(is_entry, &main->thread)) return F_status_set_error(F_interrupt); + if (!controller_thread_is_enabled(&main->thread, is_entry)) return F_status_set_error(F_interrupt); // If ready is not found in the entry, then default to always ready. if (main->process.ready == controller_process_ready_no_e) { diff --git a/sources/c/main/entry/process.c b/sources/c/main/entry/process.c index 630932a..4bd84de 100644 --- a/sources/c/main/entry/process.c +++ b/sources/c/main/entry/process.c @@ -5,7 +5,7 @@ extern "C" { #endif #ifndef _di_controller_entry_process_ - f_status_t controller_entry_process(controller_t * const main, const uint8_t failsafe, const uint8_t is_entry) { + f_status_t controller_entry_process(controller_t * const main, const uint8_t is_entry, const uint8_t failsafe) { f_status_t status = F_okay; f_status_t status_lock = F_okay; @@ -66,11 +66,11 @@ extern "C" { if (F_status_is_error(status)) return status; } - while (controller_thread_is_enabled(is_entry, &main->thread)) { + while (controller_thread_is_enabled(&main->thread, is_entry)) { entry_actions = &entry->items.array[cache->ats.array[at_i]].actions; - for (; cache->ats.array[at_j] < entry_actions->used && controller_thread_is_enabled(is_entry, &main->thread); ++cache->ats.array[at_j]) { + for (; cache->ats.array[at_j] < entry_actions->used && controller_thread_is_enabled(&main->thread, is_entry); ++cache->ats.array[at_j]) { entry_action = &entry_actions->array[cache->ats.array[at_j]]; @@ -228,7 +228,7 @@ extern "C" { controller_print_message_entry_item_rule(&main->program.message, entry, entry_action, is_entry, alias_rule); } - if (!controller_thread_is_enabled(is_entry, &main->thread)) break; + if (!controller_thread_is_enabled(&main->thread, is_entry)) break; // The Rule is not yet loaded, ensure that it is loaded. if (status != F_true) { @@ -277,7 +277,7 @@ extern "C" { break; } - if (F_status_set_fine(status) == F_interrupt || !controller_thread_is_enabled(is_entry, &main->thread)) { + if (F_status_set_fine(status) == F_interrupt || !controller_thread_is_enabled(&main->thread, is_entry)) { f_thread_unlock(&main->thread.lock.rule); break; @@ -464,7 +464,7 @@ extern "C" { } } // while - if (!controller_thread_is_enabled(is_entry, &main->thread)) return F_status_set_error(F_interrupt); + if (!controller_thread_is_enabled(&main->thread, is_entry)) return F_status_set_error(F_interrupt); if (status == F_child) return status; if (F_status_is_error(status_lock)) return status_lock; diff --git a/sources/c/main/entry/process.h b/sources/c/main/entry/process.h index 79962c9..e4294f6 100644 --- a/sources/c/main/entry/process.h +++ b/sources/c/main/entry/process.h @@ -23,12 +23,12 @@ extern "C" { * The main program data. * * Must not be NULL. - * @param failsafe - * If TRUE, operate in failsafe mode (starts at designated failsafe Item). - * If FALSE, operate in normal mode (starts at "main" Item). * @param is_entry * If TRUE, then this operates as an Entry. * If FALSE, then this operates as an Exit. + * @param failsafe + * If TRUE, operate in failsafe mode (starts at designated failsafe Item). + * If FALSE, operate in normal mode (starts at "main" Item). * * @return * F_okay on success. @@ -49,7 +49,7 @@ extern "C" { * @see controller_perform_ready() */ #ifndef _di_controller_entry_process_ - extern f_status_t controller_entry_process(controller_t * const main, const uint8_t failsafe, const uint8_t is_entry); + extern f_status_t controller_entry_process(controller_t * const main, const uint8_t is_entry, const uint8_t failsafe); #endif // _di_controller_entry_process_ #ifdef __cplusplus diff --git a/sources/c/main/lock.c b/sources/c/main/lock.c index 59ff2c6..9bdaa3f 100644 --- a/sources/c/main/lock.c +++ b/sources/c/main/lock.c @@ -10,32 +10,62 @@ extern "C" { if (!lock) return F_status_set_error(F_parameter); f_status_t status = f_thread_mutex_create(0, &lock->alert); + if (F_status_is_error(status)) return status; - if (F_status_is_error_not(status)) { - status = f_thread_mutex_create(0, &lock->cancel); - } + status = f_thread_mutex_create(0, &lock->cancel); + + if (F_status_is_error(status)) { + f_thread_mutex_delete(&lock->alert); - if (F_status_is_error_not(status)) { - status = f_thread_mutex_create(0, &lock->print); + return status; } - if (F_status_is_error_not(status)) { - status = f_thread_lock_create(0, &lock->instance); + status = f_thread_mutex_create(0, &lock->print); + + if (F_status_is_error(status)) { + f_thread_mutex_delete(&lock->alert); + f_thread_mutex_delete(&lock->cancel); + + return status; } - if (F_status_is_error_not(status)) { - status = f_thread_lock_create(0, &lock->rule); + status = f_thread_lock_create(0, &lock->instance); + + if (F_status_is_error(status)) { + f_thread_mutex_delete(&lock->alert); + f_thread_mutex_delete(&lock->cancel); + f_thread_mutex_delete(&lock->print); + + return status; } - if (F_status_is_error_not(status)) { - status = f_thread_mutex_create(0, &lock->alert); + status = f_thread_lock_create(0, &lock->rule); + + if (F_status_is_error(status)) { + f_thread_mutex_delete(&lock->alert); + f_thread_mutex_delete(&lock->cancel); + f_thread_mutex_delete(&lock->print); + f_thread_lock_delete(&lock->instance); + + return status; } - if (F_status_is_error_not(status)) { - status = f_thread_condition_create(0, &lock->alert_condition); + + status = f_thread_condition_create(0, &lock->alert_condition); + + if (F_status_is_error(status)) { + f_thread_mutex_delete(&lock->alert); + f_thread_mutex_delete(&lock->cancel); + f_thread_mutex_delete(&lock->print); + f_thread_lock_delete(&lock->instance); + f_thread_lock_delete(&lock->rule); + + return status; } - return F_status_is_error(status) ? status : F_okay; + lock->flag &= ~controller_lock_flag_setup_not_d; + + return F_okay; } #endif // _di_controller_lock_create_ @@ -55,7 +85,7 @@ extern "C" { status = f_thread_lock_read_timed(&time, lock); if (status == F_time) { - if (check && !controller_thread_is_enabled(is_normal, thread)) return F_status_set_error(F_interrupt); + if (check && !controller_thread_is_enabled(thread, is_normal)) return F_status_set_error(F_interrupt); } else { break; @@ -89,7 +119,7 @@ extern "C" { status = f_thread_lock_write_timed(&time, lock); if (status == F_time) { - if (check && !controller_thread_is_enabled(is_normal, thread)) return F_status_set_error(F_interrupt); + if (check && !controller_thread_is_enabled(thread, is_normal)) return F_status_set_error(F_interrupt); } else { break; diff --git a/sources/c/main/process.c b/sources/c/main/process.c index 26a9a38..17f9267 100644 --- a/sources/c/main/process.c +++ b/sources/c/main/process.c @@ -114,7 +114,7 @@ extern "C" { return; } - if (F_status_is_error_not(status) && status != F_failure && !(main->setting.flag & controller_main_flag_validate_e) && controller_thread_is_enabled(F_true, &main->thread)) { + if (F_status_is_error_not(status) && status != F_failure && !(main->setting.flag & controller_main_flag_validate_e) && controller_thread_is_enabled(&main->thread, F_true)) { if (main->process.mode == controller_process_mode_service_e) { controller_thread_join(&main->thread.id_signal); } diff --git a/sources/c/main/rule/instance.c b/sources/c/main/rule/instance.c index af28dc6..4a46650 100644 --- a/sources/c/main/rule/instance.c +++ b/sources/c/main/rule/instance.c @@ -144,7 +144,7 @@ extern "C" { if (F_status_is_error(status)) { if (F_status_set_fine(status) == F_lock) { - if (!controller_thread_is_enabled_instance_type(instance->type, &main->thread)) return F_status_set_error(F_interrupt); + if (!controller_thread_is_enabled_instance_type(&main->thread, instance->type)) return F_status_set_error(F_interrupt); } controller_print_error_rule_item_rule_not_loaded(&main->program.error, &instance->cache.action, dynamics[i]->array[j]); @@ -475,7 +475,7 @@ extern "C" { if (!main || !cache) return F_status_set_error(F_parameter); - if (!controller_thread_is_enabled_instance_type(type, &main->thread)) { + if (!controller_thread_is_enabled_instance_type(&main->thread, type)) { return F_status_set_error(F_interrupt); } @@ -638,7 +638,7 @@ extern "C" { } } else { - status = controller_rule_instance_perform(options_force, instance); + status = controller_rule_instance_perform(instance, options_force); if (status == F_child || F_status_set_fine(status) == F_interrupt) { f_thread_unlock(&instance->active); @@ -682,7 +682,7 @@ extern "C" { #endif // _di_controller_rule_instance_begin_ #ifndef _di_controller_rule_instance_perform_ - f_status_t controller_rule_instance_perform(const uint8_t options_force, controller_instance_t * const instance) { + f_status_t controller_rule_instance_perform(controller_instance_t * const instance, const uint8_t options_force) { if (!instance || !instance->main) return F_status_set_error(F_parameter); diff --git a/sources/c/main/rule/instance.h b/sources/c/main/rule/instance.h index f2dd83b..e3fb6f8 100644 --- a/sources/c/main/rule/instance.h +++ b/sources/c/main/rule/instance.h @@ -107,15 +107,15 @@ extern "C" { * This does all the preparation work that needs to be synchronously performed within the same thread. * This will copy the Rule by the alias to the instance structure. * + * @param instance + * The instance data. + * + * Must not be NULL. * @param options_force * Force the given instance options, only supporting a subset of instance options. * * If controller_instance_option_asynchronous_e, then asynchronously execute. * If not controller_instance_option_asynchronous_e, then synchronously execute. - * @param instance - * The instance data. - * - * Must not be NULL. * * @return * F_okay on success. @@ -135,7 +135,7 @@ extern "C" { * @see controller_rule_instance_begin() */ #ifndef _di_controller_rule_instance_perform_ - extern f_status_t controller_rule_instance_perform(const uint8_t options_force, controller_instance_t * const instance); + extern f_status_t controller_rule_instance_perform(controller_instance_t * const instance, const uint8_t options_force); #endif // _di_controller_rule_instance_perform_ #ifdef __cplusplus diff --git a/sources/c/main/rule/wait.c b/sources/c/main/rule/wait.c index 3274a3e..314d17a 100644 --- a/sources/c/main/rule/wait.c +++ b/sources/c/main/rule/wait.c @@ -42,7 +42,7 @@ extern "C" { for (i = 0; i < instance_total; ++i) { - if (!controller_thread_is_enabled(is_normal, &main->thread)) break; + if (!controller_thread_is_enabled(&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); @@ -198,7 +198,7 @@ extern "C" { return status_lock; } - if (!controller_thread_is_enabled(is_normal, &main->thread)) return F_status_set_error(F_interrupt); + if (!controller_thread_is_enabled(&main->thread, is_normal)) return F_status_set_error(F_interrupt); if (F_status_set_fine(status) == F_require) return status; if (required_not_run) return F_require; diff --git a/sources/c/main/thread/cleanup.c b/sources/c/main/thread/cleanup.c index 03fa907..73cc28c 100644 --- a/sources/c/main/thread/cleanup.c +++ b/sources/c/main/thread/cleanup.c @@ -15,14 +15,12 @@ extern "C" { if (main->thread.enabled != controller_thread_enabled_e) return 0; - const f_time_spec_t delay = { - .tv_sec = (main->setting.flag & controller_main_flag_simulate_e) + const f_time_spec_t delay = macro_f_time_spec_t_initialize_1( + (main->setting.flag & controller_main_flag_simulate_e) ? controller_thread_cleanup_interval_short_d : controller_thread_cleanup_interval_long_d, - .tv_nsec = 0, - }; - - f_status_t status = F_okay; + 0 + ); while (main->thread.enabled == controller_thread_enabled_e) { @@ -31,6 +29,7 @@ extern "C" { if (main->thread.enabled != controller_thread_enabled_e) break; if (f_thread_lock_write_try(&main->thread.lock.instance) == F_okay) { + f_status_t status = F_okay; controller_instance_t *instance = 0; f_number_unsigned_t i = 0; diff --git a/sources/c/main/thread/entry.c b/sources/c/main/thread/entry.c index e9be5e7..898da4c 100644 --- a/sources/c/main/thread/entry.c +++ b/sources/c/main/thread/entry.c @@ -13,11 +13,11 @@ extern "C" { controller_t * const main = (controller_t *) argument; - if (!controller_thread_is_enabled(F_true, &main->thread)) return 0; + if (!controller_thread_is_enabled(&main->thread, F_true)) return 0; f_status_t * const status = &main->thread.status; - *status = controller_entry_read(main, &main->process.entry); + *status = controller_entry_read(main, F_true); if (F_status_set_fine(*status) == F_interrupt) { main->process.ready = controller_process_ready_abort_e; @@ -42,7 +42,7 @@ extern "C" { controller_print_error_file_pid_exists(&main->program.error, &main->thread, main->process.path_pid); } else { - *status = controller_entry_process(main, F_false, F_true); + *status = controller_entry_process(main, F_true, F_false); if (F_status_is_error(*status)) { main->process.ready = controller_process_ready_fail_e; @@ -94,12 +94,10 @@ extern "C" { } } - if (F_status_is_error_not(*status) && *status != F_child && main->program.parameters.array[controller_parameter_validate_e].result == f_console_result_none_e && main->process.mode == controller_process_mode_helper_e) { - f_time_spec_t time; - time.tv_sec = controller_thread_timeout_exit_helper_seconds_d; - time.tv_nsec = controller_thread_timeout_exit_helper_nanoseconds_d; + if (F_status_is_error_not(*status) && *status != F_child && !(main->setting.flag & controller_main_flag_validate_e) && main->process.mode == controller_process_mode_helper_e) { + const f_time_spec_t time = macro_f_time_spec_t_initialize_1(controller_thread_timeout_exit_helper_seconds_d, controller_thread_timeout_exit_helper_nanoseconds_d); - nanosleep(&time, 0); + f_time_sleep_spec(time, 0); controller_thread_instance_cancel(main, F_true, controller_thread_cancel_exit_e); } @@ -131,7 +129,7 @@ extern "C" { controller_t * const main = (controller_t *) argument; f_status_t * const status = &main->thread.status; - *status = controller_entry_read(main, &main->process.exit); + *status = controller_entry_read(main, F_false); if (F_status_set_fine(*status) == F_interrupt) { main->process.ready = controller_process_ready_abort_e; @@ -178,7 +176,7 @@ extern "C" { } } - const f_status_t status_failsafe = controller_entry_process(main, F_true, F_false); + const f_status_t status_failsafe = controller_entry_process(main, F_false, F_true); if (F_status_is_error(status_failsafe)) { *status = F_status_set_error(F_failure); diff --git a/sources/c/main/thread/instance.c b/sources/c/main/thread/instance.c index f6fa0ae..70685ff 100644 --- a/sources/c/main/thread/instance.c +++ b/sources/c/main/thread/instance.c @@ -5,12 +5,12 @@ extern "C" { #endif #ifndef _di_controller_thread_instance_ - void controller_thread_instance(const uint8_t is_normal, controller_instance_t * const instance) { + void controller_thread_instance(controller_instance_t * const instance, const uint8_t is_normal) { if (!instance || !instance->main) return; - if (!controller_thread_is_enabled(is_normal, &instance->main->thread)) return; + if (!controller_thread_is_enabled(&instance->main->thread, is_normal)) return; - const f_status_t status = controller_rule_instance_perform(controller_instance_option_asynchronous_e, instance); + const f_status_t status = controller_rule_instance_perform(instance, controller_instance_option_asynchronous_e); // A forked child Instance should de-allocate memory on exit. // It seems that this function doesn't return to the calling thread for a forked child Instance, even with the "return 0;" below. @@ -31,7 +31,7 @@ extern "C" { f_thread_mutex_lock(&main->thread.lock.cancel); // Only cancel when enabled. - if (!controller_thread_is_enabled(is_normal, &main->thread)) { + if (!controller_thread_is_enabled(&main->thread, is_normal)) { f_thread_mutex_unlock(&main->thread.lock.cancel); return; @@ -41,7 +41,6 @@ extern "C" { controller_instance_t *instance = 0; f_time_spec_t time = f_time_spec_t_initialize; - f_status_t status = F_okay; f_number_unsigned_t i = 0; f_number_unsigned_t j = 0; pid_t pid = 0; @@ -68,13 +67,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(&main->thread.lock.alert); + f_status_t status = F_okay; - if (F_status_is_error(status)) { - main->thread.enabled = controller_thread_enabled_not_e; - } - else { + for (f_number_unsigned_t i = 0; i < controller_lock_mutex_max_retry_d; ++i) { + + status = f_thread_mutex_lock(&main->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) { main->thread.enabled = controller_thread_enabled_execute_e; } @@ -411,7 +413,7 @@ extern "C" { f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); - controller_thread_instance(F_true, (controller_instance_t * const) argument); + controller_thread_instance((controller_instance_t * const) argument, F_true); return 0; } @@ -424,7 +426,7 @@ extern "C" { f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); - controller_thread_instance(F_false, (controller_instance_t * const) argument); + controller_thread_instance((controller_instance_t * const) argument, F_false); return 0; } diff --git a/sources/c/main/thread/instance.h b/sources/c/main/thread/instance.h index ff1e648..1215dec 100644 --- a/sources/c/main/thread/instance.h +++ b/sources/c/main/thread/instance.h @@ -19,18 +19,18 @@ extern "C" { /** * Asynchronously execute a Rule process. * - * @param is_normal - * If F_true, then process as if this operates during a normal operation (Entry and Control). - * If F_false, then process as if this operates during an Exit operation. * @param instance * The instance data. * * Must not be NULL. + * @param is_normal + * If F_true, then process as if this operates during a normal operation (Entry and Control). + * If F_false, then process as if this operates during an Exit operation. * * @see controller_rule_instance_perform() */ #ifndef _di_controller_thread_instance_ - extern void controller_thread_instance(const uint8_t is_normal, controller_instance_t * const instance); + extern void controller_thread_instance(controller_instance_t * const instance, const uint8_t is_normal); #endif // _di_controller_thread_instance_ /** diff --git a/sources/c/main/thread/is.c b/sources/c/main/thread/is.c index 57440f7..577d2e2 100644 --- a/sources/c/main/thread/is.c +++ b/sources/c/main/thread/is.c @@ -5,11 +5,13 @@ extern "C" { #endif #ifndef _di_controller_thread_is_enabled_ - f_status_t controller_thread_is_enabled(const uint8_t is_normal, controller_thread_t * const thread) { + f_status_t controller_thread_is_enabled(controller_thread_t * const thread, const uint8_t is_normal) { if (!thread) return F_false; - return is_normal ? thread->enabled == controller_thread_enabled_e : thread->enabled; + const uint8_t enabled = thread->enabled; + + return is_normal ? enabled == controller_thread_enabled_e : enabled; } #endif // _di_controller_thread_is_enabled_ @@ -18,14 +20,14 @@ extern "C" { if (!instance) return F_false; - return controller_thread_is_enabled_instance_type(instance->type, &instance->main->thread); + return controller_thread_is_enabled_instance_type(&instance->main->thread, instance->type); } #endif // _di_controller_thread_is_enabled_instance_ #ifndef _di_controller_thread_is_enabled_instance_type_ - f_status_t controller_thread_is_enabled_instance_type(const uint8_t type, controller_thread_t * const thread) { + f_status_t controller_thread_is_enabled_instance_type(controller_thread_t * const thread, const uint8_t type) { - return controller_thread_is_enabled(type != controller_instance_type_exit_e, thread); + return controller_thread_is_enabled(thread, type != controller_instance_type_exit_e); } #endif // _di_controller_thread_is_enabled_instance_type_ diff --git a/sources/c/main/thread/is.h b/sources/c/main/thread/is.h index a5dc028..d645816 100644 --- a/sources/c/main/thread/is.h +++ b/sources/c/main/thread/is.h @@ -19,20 +19,20 @@ extern "C" { /** * Check to see if thread is enabled for the normal operations like Entry and Control or for Exit operations. * - * @param is_normal - * If TRUE, then instance as if this operates during a normal operation (Entry and Control). - * If FALSE, then instance as if this operates during an Exit operation. * @param thread * The thread data. * * Must not be NULL. + * @param is_normal + * If TRUE, then instance as if this operates during a normal operation (Entry and Control). + * If FALSE, then instance as if this operates during an Exit operation. * * @return * F_true when enabled. * F_false when disabled. */ #ifndef _di_controller_thread_is_enabled_ - extern f_status_t controller_thread_is_enabled(const uint8_t is_normal, controller_thread_t * const thread); + extern f_status_t controller_thread_is_enabled(controller_thread_t * const thread, const uint8_t is_normal); #endif // _di_controller_thread_is_enabled_ /** @@ -56,12 +56,12 @@ extern "C" { /** * Check to see if thread is enabled for the normal operations like Entry and Control or for Exit operations for some instance type. * - * @param type - * The instance type to use when checking if thread is enabled. * @param thread * The thread data. * * Must not be NULL. + * @param type + * The instance type to use when checking if thread is enabled. * * @return * Success from controller_thread_is_enabled(). @@ -69,7 +69,7 @@ extern "C" { * @see controller_thread_is_enabled() */ #ifndef _di_controller_thread_is_enabled_instance_type_ - extern f_status_t controller_thread_is_enabled_instance_type(const uint8_t type, controller_thread_t * const thread); + extern f_status_t controller_thread_is_enabled_instance_type(controller_thread_t * const thread, const uint8_t type); #endif // _di_controller_thread_is_enabled_instance_type_ #ifdef __cplusplus diff --git a/sources/c/main/thread/rule.c b/sources/c/main/thread/rule.c index 6d5ffcb..7c54c04 100644 --- a/sources/c/main/thread/rule.c +++ b/sources/c/main/thread/rule.c @@ -13,7 +13,7 @@ extern "C" { controller_t * const main = (controller_t *) argument; - if (!controller_thread_is_enabled(F_true, &main->thread)) return 0; + if (!controller_thread_is_enabled(&main->thread, F_true)) return 0; return 0; } diff --git a/sources/c/main/thread/signal.c b/sources/c/main/thread/signal.c index 010c55d..b95b888 100644 --- a/sources/c/main/thread/signal.c +++ b/sources/c/main/thread/signal.c @@ -8,13 +8,13 @@ extern "C" { void controller_thread_signal(controller_t * const main, const uint8_t is_normal) { if (!main) return; - if (!controller_thread_is_enabled(is_normal, &main->thread)) return; + if (!controller_thread_is_enabled(&main->thread, is_normal)) return; if (!(main->setting.flag & controller_main_flag_interruptible_e)) return; siginfo_t information; f_time_spec_t time = f_time_spec_t_initialize; - while (controller_thread_is_enabled(is_normal, &main->thread)) { + while (controller_thread_is_enabled(&main->thread, is_normal)) { memset((void *) &information, 0, sizeof(siginfo_t)); @@ -42,7 +42,7 @@ extern "C" { if (!interrupt->main) return; - if (!controller_thread_is_enabled(interrupt->is_normal, &interrupt->main->thread)) { + if (!controller_thread_is_enabled(&interrupt->main->thread, interrupt->is_normal)) { interrupt->main->program.signal_received = F_signal_abort; interrupt->main->setting.state.status = F_status_set_error(F_interrupt); } @@ -62,7 +62,7 @@ extern "C" { if (!interrupt->main) return; - if (!controller_thread_is_enabled(interrupt->is_normal, &interrupt->main->thread)) { + if (!controller_thread_is_enabled(&interrupt->main->thread, interrupt->is_normal)) { interrupt->main->program.signal_received = F_signal_abort; interrupt->main->setting.state.status = F_status_set_error(F_interrupt); }