From: Kevin Day Date: Mon, 3 Apr 2023 00:17:48 +0000 (-0500) Subject: Update: Implement threaded signal handler in Featureless Make. X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=9e0529297bfdb1529be685eacd3ca5784ea8e946;p=fll Update: Implement threaded signal handler in Featureless Make. Bring in the threaded signal handler design that I experimented with in the Kevux Tools project. This works by creating a thread that waits for the signal and nothing else. The threaded design avoids the signal check and therefore avoids period calls to kernel space. When thread support is diabled, this falls back to the traditional approach. This will be done for other programs as well. --- diff --git a/build/stand_alone/fake.settings b/build/stand_alone/fake.settings index 25cae79..c7b225e 100644 --- a/build/stand_alone/fake.settings +++ b/build/stand_alone/fake.settings @@ -69,7 +69,7 @@ build_sources_program fll/level_2/fss.c fll/level_2/fss/basic.c fll/level_2/fss/ build_sources_program fll/level_2/print.c build_sources_program fll/level_2/program.c fll/level_2/program/common.c fll/level_2/program/print.c fll/level_2/private-program.c -build_sources_program program/fake/main/build.c program/fake/main/clean.c program/fake/main/common.c program/fake/main/fake.c program/fake/main/make.c program/fake/main/print/common.c program/fake/main/print/context.c program/fake/main/print/error.c program/fake/main/print/message.c program/fake/main/print/operation.c program/fake/main/print/warning.c program/fake/main/print/verbose.c program/fake/main/skeleton.c +build_sources_program program/fake/main/build.c program/fake/main/clean.c program/fake/main/common.c program/fake/main/fake.c program/fake/main/make.c program/fake/main/print/common.c program/fake/main/print/context.c program/fake/main/print/error.c program/fake/main/print/message.c program/fake/main/print/operation.c program/fake/main/print/warning.c program/fake/main/print/verbose.c program/fake/main/signal.c program/fake/main/skeleton.c program/fake/main/thread.c build_sources_program program/fake/main/build/enumeration.c program/fake/main/build/library.c program/fake/main/build/load.c program/fake/main/build/object.c program/fake/main/build/objects.c program/fake/main/build/print/compile.c program/fake/main/build/print/error.c program/fake/main/build/print/message.c program/fake/main/build/print/verbose.c program/fake/main/build/print/warning.c program/fake/main/build/program.c program/fake/main/build/skeleton.c program/fake/main/build/string.c build_sources_program program/fake/main/common/define.c program/fake/main/common/enumeration.c program/fake/main/common/print.c program/fake/main/common/string.c program/fake/main/common/type.c build_sources_program program/fake/main/fake/path_generate.c diff --git a/level_3/fake/c/main/build.c b/level_3/fake/c/main/build.c index 8d767ac..1622588 100644 --- a/level_3/fake/c/main/build.c +++ b/level_3/fake/c/main/build.c @@ -163,19 +163,10 @@ extern "C" { if (!data || !data->main) return; if (data->main->setting.state.status == F_child) return; if (F_status_is_error(data->main->setting.state.status) || f_file_exists(file_stage, F_true) == F_true) return; + if (fake_signal_check(data->main)) return; fake_main_t * const main = data->main; - if (!((++main->program.signal_check) % fake_signal_check_d)) { - if (fll_program_standard_signal_received(&main->program)) { - fll_program_print_signal_received(&main->program.warning, main->program.signal_received); - - main->setting.state.status = F_status_set_error(F_interrupt); - - return; - } - } - f_directory_statuss_t failures = f_directory_statuss_t_initialize; f_string_dynamic_t path_source = f_string_dynamic_t_initialize; // @todo move this to a shared buffer. f_string_dynamic_t destination_file = f_string_dynamic_t_initialize; @@ -531,12 +522,9 @@ extern "C" { main->setting.state.status = fll_execute_program(main->cache_argument, main->cache_arguments, ¶meter, 0, (void *) &return_code); - if (!((++main->program.signal_check) % fake_signal_check_d) && fll_program_standard_signal_received(&main->program)) { - fll_program_print_signal_received(&main->program.warning, main->program.signal_received); + if (fake_signal_check(main)) return return_code; - main->setting.state.status = F_status_set_error(F_interrupt); - } - else if (main->setting.state.status != F_child) { + if (main->setting.state.status != F_child) { if (F_status_is_error(main->setting.state.status)) { if (F_status_set_fine(main->setting.state.status) == F_failure) { fake_print_error_failure_script(&main->program.error, main->cache_argument); @@ -633,19 +621,10 @@ extern "C" { void fake_build_operate(fake_data_t * const data, const f_string_statics_t * const build_arguments, const bool process_pipe) { if (!data || !data->main) return; + if (fake_signal_check(data->main)) return; fake_main_t * const main = data->main; - if (!((++main->program.signal_check) % fake_signal_check_d)) { - if (fll_program_standard_signal_received(&main->program)) { - fll_program_print_signal_received(&main->program.warning, main->program.signal_received); - - main->setting.state.status = F_status_set_error(F_interrupt); - - return; - } - } - main->setting.state.status = F_none; f_mode_t mode = f_mode_t_initialize; @@ -875,19 +854,10 @@ extern "C" { if (!data || !data->main) return; if (F_status_is_error(data->main->setting.state.status)) return; + if (fake_signal_check(data->main)) return; fake_main_t * const main = data->main; - if (!((++main->program.signal_check) % fake_signal_check_d)) { - if (fll_program_standard_signal_received(&main->program)) { - fll_program_print_signal_received(&main->program.warning, main->program.signal_received); - - main->setting.state.status = F_status_set_error(F_interrupt); - - return; - } - } - f_mode_t mode = f_mode_t_initialize; macro_f_mode_t_set_default_umask(mode, main->program.umask); diff --git a/level_3/fake/c/main/build/load.c b/level_3/fake/c/main/build/load.c index 19e9eef..b20ecdc 100644 --- a/level_3/fake/c/main/build/load.c +++ b/level_3/fake/c/main/build/load.c @@ -66,19 +66,10 @@ extern "C" { if (!data || !data->main || !setting) return; if (F_status_is_error(data->main->setting.state.status)) return; + if (fake_signal_check(data->main)) return; fake_main_t * const main = data->main; - if (!((++main->program.signal_check) % fake_signal_check_d)) { - if (fll_program_standard_signal_received(&main->program)) { - fll_program_print_signal_received(&main->program.warning, main->program.signal_received); - - main->setting.state.status = F_status_set_error(F_interrupt); - - return; - } - } - // Strip the build settings name from the build arguments to generate a list of modes. f_string_statics_t modes_custom = f_string_statics_t_initialize; modes_custom.used = build_arguments && build_arguments->used > 1 ? build_arguments->used - 1 : 0; @@ -211,19 +202,10 @@ extern "C" { if (!data || !data->main || !setting) return; if (F_status_is_error(data->main->setting.state.status) && buffer.used) return; + if (fake_signal_check(data->main)) return; fake_main_t * const main = data->main; - if (!((++main->program.signal_check) % fake_signal_check_d)) { - if (fll_program_standard_signal_received(&main->program)) { - fll_program_print_signal_received(&main->program.warning, main->program.signal_received); - - main->setting.state.status = F_status_set_error(F_interrupt); - - return; - } - } - bool error_printed = F_false; f_string_dynamics_t build_compiler = f_string_dynamics_t_initialize; @@ -1335,19 +1317,10 @@ extern "C" { if (!data || !data->main || !stage) return; if (F_status_is_error(data->main->setting.state.status)) return; + if (fake_signal_check(data->main)) return; fake_main_t * const main = data->main; - if (!((++main->program.signal_check) % fake_signal_check_d)) { - if (fll_program_standard_signal_received(&main->program)) { - fll_program_print_signal_received(&main->program.warning, main->program.signal_received); - - main->setting.state.status = F_status_set_error(F_interrupt); - - return; - } - } - const f_string_static_t names[] = { fake_build_stage_library_script_s, fake_build_stage_library_shared_s, diff --git a/level_3/fake/c/main/build/skeleton.c b/level_3/fake/c/main/build/skeleton.c index 5853343..948db67 100644 --- a/level_3/fake/c/main/build/skeleton.c +++ b/level_3/fake/c/main/build/skeleton.c @@ -65,16 +65,7 @@ extern "C" { for (j = 0; j < directorys[i].used; ++j) { if (f_path_separator_s.used && directorys[i].string[j] != f_path_separator_s.string[0]) continue; - - if (!((++main->program.signal_check) % fake_signal_check_d)) { - if (fll_program_standard_signal_received(&main->program)) { - fll_program_print_signal_received(&main->program.warning, main->program.signal_received); - - main->setting.state.status = F_status_set_error(F_interrupt); - - return; - } - } + if (fake_signal_check(data->main)) return; directorys[i].string[j] = 0; diff --git a/level_3/fake/c/main/common/define.h b/level_3/fake/c/main/common/define.h index b1746e6..059ec84 100644 --- a/level_3/fake/c/main/common/define.h +++ b/level_3/fake/c/main/common/define.h @@ -36,14 +36,16 @@ extern "C" { * The program signal defines. * * fake_signal_*_d: - * - check: Number of iterations before performing signal check in non-threaded signal handling. - * - check_tiny: The tiny check. - * - check_short: The short signal check. + * - check: Number of iterations before performing signal check in non-threaded signal handling. + * - check_failsafe: When using threads, how many consecutive failures to check signal before aborting (as a recursion failsafe). + * - check_tiny: The tiny check. + * - check_short: The short signal check. */ #ifndef _di_fake_signal_d_ - #define fake_signal_check_d 500000 - #define fake_signal_check_tiny_d 4 - #define fake_signal_check_short_d 16 + #define fake_signal_check_d 500000 + #define fake_signal_check_failsafe_d 20000 + #define fake_signal_check_tiny_d 4 + #define fake_signal_check_short_d 16 #endif // _di_fake_signal_d_ /** diff --git a/level_3/fake/c/main/common/print.c b/level_3/fake/c/main/common/print.c index 26e5995..28ba08c 100644 --- a/level_3/fake/c/main/common/print.c +++ b/level_3/fake/c/main/common/print.c @@ -9,6 +9,7 @@ extern "C" { "f_account_group_id_by_name", "f_account_id_by_name", "f_array_lengths_increase", + "f_compare_dynamic_partial", "f_console_parameter_prioritize_right", "f_console_parameter_process", "f_conversion_number_signed_to_string", @@ -64,6 +65,7 @@ extern "C" { "f_string_dynamics_increase_by", "f_string_dynamics_resize", "f_string_map_multis_resize", + "f_thread_create", "f_uint8s_increase", "f_uint8s_increase_by", "f_utf_is_word_dash_plus", @@ -73,7 +75,6 @@ extern "C" { "fl_environment_load_name", "fl_environment_load_names", "fl_iki_read", - "f_compare_dynamic_partial", "fll_execute_arguments_add", "fll_execute_arguments_add_parameter_set", "fll_execute_program", @@ -97,7 +98,6 @@ extern "C" { "fake_make_assure_inside_project", "fake_make_get_id", "fake_make_get_id_mode", - "fake_make_get_id", "fake_make_operate_expand_build", "fake_make_operate_expand_context", "fake_make_operate_expand_environment", diff --git a/level_3/fake/c/main/common/print.h b/level_3/fake/c/main/common/print.h index b9ec7b0..7db7373 100644 --- a/level_3/fake/c/main/common/print.h +++ b/level_3/fake/c/main/common/print.h @@ -42,6 +42,7 @@ extern "C" { fake_f_f_account_group_id_by_name_e, fake_f_f_account_id_by_name_e, fake_f_f_array_lengths_increase_e, + fake_f_f_compare_dynamic_partial_e, fake_f_f_console_parameter_prioritize_right_e, fake_f_f_console_parameter_process_e, fake_f_f_conversion_number_signed_to_string_e, @@ -97,6 +98,7 @@ extern "C" { fake_f_f_string_dynamics_increase_by_e, fake_f_f_string_dynamics_resize_e, fake_f_f_string_map_multis_resize_e, + fake_f_f_thread_create_e, fake_f_f_uint8s_increase_e, fake_f_f_uint8s_increase_by_e, fake_f_f_utf_is_word_dash_plus_e, @@ -106,7 +108,6 @@ extern "C" { fake_f_fl_environment_load_name_e, fake_f_fl_environment_load_names_e, fake_f_fl_iki_read_e, - fake_f_f_compare_dynamic_partial_e, fake_f_fll_execute_arguments_add_e, fake_f_fll_execute_arguments_add_parameter_set_e, fake_f_fll_execute_program_e, diff --git a/level_3/fake/c/main/common/type.h b/level_3/fake/c/main/common/type.h index 3374b68..e155574 100644 --- a/level_3/fake/c/main/common/type.h +++ b/level_3/fake/c/main/common/type.h @@ -60,7 +60,8 @@ extern "C" { * * flag: Flags passed to the main function. * - * state: The state data used when processing the FSS data. + * status_thread: A status used eclusively by the threaded signal handler. + * state: The state data used when processing the FSS data. * * build: The build directory. * data: The data directory. @@ -79,6 +80,7 @@ extern "C" { typedef struct { uint32_t flag; + f_status_t status_thread; f_state_t state; f_string_dynamic_t build; @@ -100,6 +102,7 @@ extern "C" { #define fake_setting_t_initialize \ { \ 0, \ + F_none, \ f_state_t_initialize, \ f_string_dynamic_t_initialize, \ f_string_dynamic_t_initialize, \ diff --git a/level_3/fake/c/main/fake.c b/level_3/fake/c/main/fake.c index 26a30a4..71a2559 100644 --- a/level_3/fake/c/main/fake.c +++ b/level_3/fake/c/main/fake.c @@ -285,17 +285,7 @@ extern "C" { fl_execute_parameter_t parameter = macro_fl_execute_parameter_t_initialize(0, 0, &environment, &signals, 0); main->setting.state.status = fll_execute_program(program, main->cache_arguments, ¶meter, 0, (void *) &return_code); - - if (!((++main->program.signal_check) % fake_signal_check_d)) { - if (fll_program_standard_signal_received(&main->program)) { - fll_program_print_signal_received(&main->program.warning, main->program.signal_received); - - main->setting.state.status = F_status_set_error(F_interrupt); - - return 0; - } - } - + if (fake_signal_check(data->main)) return return_code; if (main->setting.state.status == F_child) return return_code; } else { @@ -324,19 +314,10 @@ extern "C" { void fake_file_buffer(fake_data_t * const data, const f_string_static_t path_file, const bool required, f_string_dynamic_t * const buffer) { if (!data || !data->main || !buffer) return; + if (fake_signal_check(data->main)) return; fake_main_t * const main = data->main; - if (!((++main->program.signal_check) % fake_signal_check_d)) { - if (fll_program_standard_signal_received(&main->program)) { - fll_program_print_signal_received(&main->program.warning, main->program.signal_received); - - main->setting.state.status = F_status_set_error(F_interrupt); - - return; - } - } - main->setting.state.status = f_file_exists(path_file, F_true); if (F_status_is_error(main->setting.state.status)) { @@ -432,15 +413,7 @@ extern "C" { clearerr(F_type_input_d); do { - if (!((++main->program.signal_check) % fake_signal_check_d)) { - if (fll_program_standard_signal_received(&main->program)) { - fll_program_print_signal_received(&main->program.warning, main->program.signal_received); - - main->setting.state.status = F_status_set_error(F_interrupt); - - return; - } - } + if (fake_signal_check(main)) return; main->setting.state.status = f_file_stream_read_block(file, buffer); @@ -459,19 +432,10 @@ extern "C" { void fake_validate_parameter_paths(fake_data_t * const data) { if (!data || !data->main) return; + if (fake_signal_check(data->main)) return; fake_main_t * const main = data->main; - if (!((++main->program.signal_check) % fake_signal_check_d)) { - if (fll_program_standard_signal_received(&main->program)) { - fll_program_print_signal_received(&main->program.warning, main->program.signal_received); - - main->setting.state.status = F_status_set_error(F_interrupt); - - return; - } - } - const f_string_static_t names[] = { fake_long_build_s, fake_long_data_s, diff --git a/level_3/fake/c/main/fake.h b/level_3/fake/c/main/fake.h index 228d888..4e5f42f 100644 --- a/level_3/fake/c/main/fake.h +++ b/level_3/fake/c/main/fake.h @@ -141,7 +141,9 @@ #include #include #include +#include #include +#include #ifdef __cplusplus extern "C" { diff --git a/level_3/fake/c/main/main.c b/level_3/fake/c/main/main.c index 6696743..f1eefe1 100644 --- a/level_3/fake/c/main/main.c +++ b/level_3/fake/c/main/main.c @@ -36,13 +36,41 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) { f_file_umask_get(&data.program.umask); - { - const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp); + #ifdef _di_thread_support_ + { + const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp); - fake_setting_load(arguments, &data); - } + fake_setting_load(arguments, &data); + } + + fake_main(&data); + #else + { + f_thread_id_t id_signal; + + memset(&id_signal, 0, sizeof(f_thread_id_t)); + + data.setting.state.status = f_thread_create(0, &id_signal, &fake_thread_signal, (void *) &data); + + if (F_status_is_error(data.setting.state.status)) { + fake_print_error(&data.program.error, macro_fake_f(f_thread_create)); + } + else { + { + const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp); + + fake_setting_load(arguments, &data); + } + + if (!fake_signal_check(&data)) { + fake_main(&data); + } - fake_main(&data); + f_thread_cancel(id_signal); + f_thread_join(id_signal, 0); + } + } + #endif // _di_thread_support_ fake_main_delete(&data); diff --git a/level_3/fake/c/main/make/operate.c b/level_3/fake/c/main/make/operate.c index 59a7b4d..19dd6dd 100644 --- a/level_3/fake/c/main/make/operate.c +++ b/level_3/fake/c/main/make/operate.c @@ -8,19 +8,10 @@ extern "C" { void fake_make_operate(fake_data_t * const data) { if (!data || !data->main) return; + if (fake_signal_check(data->main)) return; fake_main_t * const main = data->main; - if (!((++main->program.signal_check) % fake_signal_check_d)) { - if (fll_program_standard_signal_received(&main->program)) { - fll_program_print_signal_received(&main->program.warning, main->program.signal_received); - - main->setting.state.status = F_status_set_error(F_interrupt); - - return; - } - } - fake_make_print_message_now_making(&main->program.message, main->setting.fakefile); f_array_lengths_t section_stack = f_array_lengths_t_initialize; diff --git a/level_3/fake/c/main/signal.c b/level_3/fake/c/main/signal.c new file mode 100644 index 0000000..a401144 --- /dev/null +++ b/level_3/fake/c/main/signal.c @@ -0,0 +1,113 @@ +#include "fake.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_di_fake_signal_check_) && defined(_di_thread_support_) + f_status_t fake_signal_check(fake_main_t * const main) { + + if (!main) return F_false; + if (main->program.signal.id == -1) return F_false; + + if (!((++main->program.signal_check) % fake_signal_check_d)) { + if (fll_program_standard_signal_received(&main->program)) { + fll_program_print_signal_received(&main->program.warning, main->program.signal_received); + + main->setting.state.status = F_status_set_error(F_interrupt); + + return F_true; + } + + main->program.signal_check = 0; + } + + return F_false; + } +#endif // !defined(_di_fake_signal_check_) && defined(_di_thread_support_) + +#if !defined(_di_fake_signal_check_) && !defined(_di_thread_support_) + f_status_t fake_signal_check(fake_main_t * const main) { + + if (!main) return F_false; + if (main->program.signal.id == -1) return F_false; + + if (main->program.signal_received) { + fll_program_print_signal_received(&main->program.warning, main->program.signal_received); + + main->setting.state.status = F_status_set_error(F_interrupt); + + return F_true; + } + + return F_false; + } +#endif // !defined(_di_fake_signal_check_) && !defined(_di_thread_support_) + +#if !defined(_di_fake_signal_handler_) && !defined(_di_thread_support_) + void fake_signal_handler(fake_main_t * const main) { + + if (!main) return; + + siginfo_t information; + f_array_length_t failsafe = 0; + + memset(&information, 0, sizeof(siginfo_t)); + + main->program.signal_received = 0; + + f_signal_set_empty(&main->program.signal.set); + f_signal_set_add(F_signal_abort, &main->program.signal.set); + f_signal_set_add(F_signal_broken_pipe, &main->program.signal.set); + f_signal_set_add(F_signal_hangup, &main->program.signal.set); + f_signal_set_add(F_signal_interrupt, &main->program.signal.set); + f_signal_set_add(F_signal_quit, &main->program.signal.set); + f_signal_set_add(F_signal_termination, &main->program.signal.set); + + if (main->program.signal.id == -1) { + main->setting.status_thread = f_signal_open(&main->program.signal); + + if (F_status_is_error(main->setting.status_thread)) { + main->program.signal_received = F_signal_abort; + + return; + } + } + + do { + memset(&information, 0, sizeof(siginfo_t)); + + main->setting.status_thread = f_signal_wait(&main->program.signal.set, &information); + + if (F_status_is_error(main->setting.status_thread) && F_status_set_fine(main->setting.status_thread) != F_interrupt) { + if (++failsafe >= fake_signal_check_failsafe_d) break; + } + + switch (information.si_signo) { + case F_signal_abort: + case F_signal_broken_pipe: + case F_signal_hangup: + case F_signal_interrupt: + case F_signal_quit: + case F_signal_termination: + main->program.signal_received = information.si_signo; + + break; + } + + failsafe = 0; + main->setting.status_thread = F_none; + + } while (!main->program.signal_received); + + f_signal_close(&main->program.signal); + + if (F_status_is_error(main->setting.status_thread)) { + main->program.signal_received = F_signal_abort; + } + } +#endif // !defined(_di_fake_signal_handler_) && !defined(_di_thread_support_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fake/c/main/signal.h b/level_3/fake/c/main/signal.h new file mode 100644 index 0000000..a40c0da --- /dev/null +++ b/level_3/fake/c/main/signal.h @@ -0,0 +1,86 @@ +/** + * FLL - Level 3 + * + * Project: Featureless Make + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Provides signal functionality. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _fake_signal_h +#define _fake_signal_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Check to see if a signal is received. + * + * If main.signal is non-zero, then this handles the following signals: + * - F_signal_abort + * - F_signal_broken_pipe + * - F_signal_hangup + * - F_signal_interrupt + * - F_signal_quit + * - F_signal_termination + * + * There is a threaded and a non-threaded version of this. + * The non-threaded version checks periodically using fake_signal_check_d and updates main->signal_check as needed. + * The threaded version checks the flag state which is set by a separate thread that is blocking until signal is received. + * + * @param main + * The main program and settings data. + * + * This does not alter main.setting.state.status. + * + * @return + * F_true on signal received. + * F_false otherwise. + * + * @see fake_signal_handler() + * + * @see fll_program_standard_signal_received() + */ +#ifndef _di_fake_signal_check_ + extern f_status_t fake_signal_check(fake_main_t * const main); +#endif // _di_fake_signal_check_ + +/** + * Signal handler for signals/interrupts. + * + * This blocks until an expected signal is recieved. + * When an expected signal is received it then sets the + * + * If main.signal is non-zero, then this handles the following signals: + * - F_signal_abort + * - F_signal_broken_pipe + * - F_signal_hangup + * - F_signal_interrupt + * - F_signal_quit + * - F_signal_termination + * + * @param main + * The main program and settings data. + * + * This alters main.program.signal_received, setting it to a received signal. + * + * This alters setting.status: + * Errors with (error bit set) from: f_signal_open() + * Errors with (error bit set) from: f_signal_wait() + * + * @see f_signal_close() + * @see f_signal_open() + * @see f_signal_wait() + */ +#if !defined(_di_fake_signal_handler_) && !defined(_di_thread_support_) + extern void fake_signal_handler(fake_main_t * const main); +#endif // !defined(_di_fake_signal_handler_) && !defined(_di_thread_support_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _fake_signal_h diff --git a/level_3/fake/c/main/thread.c b/level_3/fake/c/main/thread.c new file mode 100644 index 0000000..110e0f7 --- /dev/null +++ b/level_3/fake/c/main/thread.c @@ -0,0 +1,26 @@ +#include "fake.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_di_fake_thread_signal_) && !defined(_di_thread_support_) + void * fake_thread_signal(void * const main) { + + f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); + + if (main) { + fake_signal_handler((fake_main_t *) main); + } + + return 0; + } +#endif // !defined(_di_fake_thread_signal_) && !defined(_di_thread_support_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fake/c/main/thread.h b/level_3/fake/c/main/thread.h new file mode 100644 index 0000000..3053403 --- /dev/null +++ b/level_3/fake/c/main/thread.h @@ -0,0 +1,46 @@ +/** + * FLL - Level 3 + * + * Project: Featureless Make + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Provides thread functionality. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _fake_thread_h +#define _fake_thread_h + +/** + * Thread handler for signals/interrupts. + * + * If main.signal is non-zero, then this handles the following signals: + * - F_signal_abort + * - F_signal_broken_pipe + * - F_signal_hangup + * - F_signal_interrupt + * - F_signal_quit + * - F_signal_termination + * + * @param main + * The program and settings data. + * + * Must be of type fake_main_t. + * + * @return + * 0, always. + * + * @see f_thread_cancel_state_set() + * + * @see fake_signal_handler() + */ +#if !defined(_di_fake_thread_signal_) && !defined(_di_thread_support_) + extern void * fake_thread_signal(void * const main); +#endif // !defined(_di_fake_thread_signal_) && !defined(_di_thread_support_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _fake_thread_h diff --git a/level_3/fake/data/build/defines b/level_3/fake/data/build/defines index 546ad61..e998952 100644 --- a/level_3/fake/data/build/defines +++ b/level_3/fake/data/build/defines @@ -1,6 +1,7 @@ # fss-0000 _di_libcap_ Disable libcap support, allow for compiling and linking without libcap (-lcap). +_di_thread_support_ Disables thread support. _libcap_legacy_only_ Disable functionality provided by later versions of libcap (2.43 and later). _pthread_attr_unsupported_ Disable non-portable functionality associated with pthread_attr. diff --git a/level_3/fake/data/build/settings b/level_3/fake/data/build/settings index ffa6a65..b82ecd6 100644 --- a/level_3/fake/data/build/settings +++ b/level_3/fake/data/build/settings @@ -27,7 +27,7 @@ build_libraries-individual -lf_account -lf_capability -lf_color -lf_compare -lf_ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll -build_sources_library main/build.c main/clean.c main/common.c main/fake.c main/make.c main/print/common.c main/print/context.c main/print/error.c main/print/message.c main/print/operation.c main/print/warning.c main/print/verbose.c main/skeleton.c +build_sources_library main/build.c main/clean.c main/common.c main/fake.c main/make.c main/print/common.c main/print/context.c main/print/error.c main/print/message.c main/print/operation.c main/print/warning.c main/print/verbose.c main/signal.c main/skeleton.c main/thread.c build_sources_library main/build/enumeration.c main/build/library.c main/build/load.c main/build/object.c main/build/objects.c main/build/print/compile.c main/build/print/error.c main/build/print/message.c main/build/print/verbose.c main/build/print/warning.c main/build/program.c main/build/skeleton.c main/build/string.c build_sources_library main/common/define.c main/common/enumeration.c main/common/print.c main/common/string.c main/common/type.c build_sources_library main/fake/path_generate.c @@ -35,7 +35,7 @@ build_sources_library main/make/load_fakefile.c main/make/load_parameters.c main build_sources_program main/main.c -build_sources_headers main/build.h main/clean.h main/common.h main/fake.h main/make.h main/print/common.h main/print/context.h main/print/error.h main/print/message.h main/print/operation.h main/print/warning.h main/print/verbose.h main/skeleton.h +build_sources_headers main/build.h main/clean.h main/common.h main/fake.h main/make.h main/print/common.h main/print/context.h main/print/error.h main/print/message.h main/print/operation.h main/print/warning.h main/print/verbose.h main/signal.h main/skeleton.h main/thread.h build_sources_headers main/build/enumeration.h main/build/library.h main/build/load.h main/build/object.h main/build/objects.h main/build/print/compile.h main/build/print/error.h main/build/print/message.h main/build/print/verbose.h main/build/print/warning.h main/build/program.h main/build/skeleton.h main/build/string.h build_sources_headers main/common/define.h main/common/enumeration.h main/common/print.h main/common/string.h main/common/type.h build_sources_headers main/fake/path_generate.h