From 576e49fc375c7e73864adc6dcc518273af792578 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Wed, 12 Jul 2023 22:35:41 -0500 Subject: [PATCH] Progress: Implement the threads for the receive and send. This ignores the non-thread version at this time. --- data/build/tacocat/settings | 4 +- sources/c/tacocat/main/common.c | 12 +++ sources/c/tacocat/main/common.h | 6 +- sources/c/tacocat/main/common/define.h | 5 ++ sources/c/tacocat/main/common/type.c | 10 +++ sources/c/tacocat/main/common/type.h | 50 ++++++++++- sources/c/tacocat/main/process.c | 151 +++++++++++++++++---------------- sources/c/tacocat/main/process.h | 20 +++-- sources/c/tacocat/main/receive.c | 47 ++++++++++ sources/c/tacocat/main/receive.h | 38 +++++++++ sources/c/tacocat/main/send.c | 36 ++++++++ sources/c/tacocat/main/send.h | 38 +++++++++ sources/c/tacocat/main/signal.c | 12 +-- sources/c/tacocat/main/tacocat.h | 2 + 14 files changed, 341 insertions(+), 90 deletions(-) create mode 100644 sources/c/tacocat/main/receive.c create mode 100644 sources/c/tacocat/main/receive.h create mode 100644 sources/c/tacocat/main/send.c create mode 100644 sources/c/tacocat/main/send.h diff --git a/data/build/tacocat/settings b/data/build/tacocat/settings index 3e234b7..fdbf0cb 100644 --- a/data/build/tacocat/settings +++ b/data/build/tacocat/settings @@ -37,9 +37,9 @@ build_libraries-individual_thread -lf_thread build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll -build_sources_library main/common.c main/common/define.c main/common/enumeration.c main/common/print.c main/common/string.c main/common/type.c main/print/error.c main/print/message.c main/print/verbose.c main/print/warning.c main/process.c main/signal.c main/tacocat.c main/thread.c +build_sources_library main/common.c main/common/define.c main/common/enumeration.c main/common/print.c main/common/string.c main/common/type.c main/print/error.c main/print/message.c main/print/verbose.c main/print/warning.c main/process.c main/receive.c main/send.c main/signal.c main/tacocat.c main/thread.c -build_sources_headers main/common.h main/common/define.h main/common/enumeration.h main/common/print.h main/common/string.h main/common/type.h main/print/error.h main/print/message.h main/print/verbose.h main/print/warning.h main/process.h main/signal.h main/tacocat.h main/thread.h +build_sources_headers main/common.h main/common/define.h main/common/enumeration.h main/common/print.h main/common/string.h main/common/type.h main/print/error.h main/print/message.h main/print/verbose.h main/print/warning.h main/process.h main/receive.h main/send.h main/signal.h main/tacocat.h main/thread.h build_sources_program main/main.c diff --git a/sources/c/tacocat/main/common.c b/sources/c/tacocat/main/common.c index 074994b..9fee6f0 100644 --- a/sources/c/tacocat/main/common.c +++ b/sources/c/tacocat/main/common.c @@ -162,6 +162,11 @@ extern "C" { kt_tacocat_parameter_send_e, }; + const uint64_t flags[] = { + kt_tacocat_main_flag_receive_e, + kt_tacocat_main_flag_send_e, + }; + const f_string_static_t longs[] = { kt_tacocat_long_receive_s, kt_tacocat_long_send_s, @@ -190,6 +195,8 @@ extern "C" { for (uint8_t i = 0; i < 2; ++i) { if (main->program.parameters.array[parameters[i]].result & f_console_result_value_e) { + main->setting.flag |= flags[i]; + if (main->program.parameters.array[parameters[i]].values.used % 2) { main->setting.state.status = F_status_set_error(F_parameter); @@ -475,6 +482,8 @@ extern "C" { } // for } else if (main->program.parameters.array[parameters[i]].result & f_console_result_found_e) { + main->setting.flag -= main->setting.flag & flags[i]; + main->setting.state.status = F_status_set_error(F_parameter); macro_setting_load_print_first(); @@ -487,6 +496,9 @@ extern "C" { continue; } + else { + main->setting.flag -= main->setting.flag & flags[i]; + } } // for if (F_status_is_error(failed)) { diff --git a/sources/c/tacocat/main/common.h b/sources/c/tacocat/main/common.h index b7a4aaf..80fa7e1 100644 --- a/sources/c/tacocat/main/common.h +++ b/sources/c/tacocat/main/common.h @@ -31,7 +31,7 @@ extern "C" { * This alters setting.state.status: * F_none on success. * - * F_parameter (with error bit) on parameter error. + * F_parameter (with error bit) if a parameter is invalid. * * Errors (with error bit) from: f_console_parameter_process(). * Errors (with error bit) from: f_string_dynamic_append_nulless(). @@ -70,7 +70,7 @@ extern "C" { * This alters main.setting.state.status: * F_none on success. * - * F_parameter (with error bit) on parameter error. + * F_parameter (with error bit) if a parameter is invalid. * * Errors (with error bit) from: f_file_exists(). * Errors (with error bit) from: f_file_open(). @@ -111,7 +111,7 @@ extern "C" { * F_data_not on success but there is nothing in the address string (address.used is 0). * F_number_not on success but there is no port number. * - * F_parameter (with error bit) on parameter error. + * F_parameter (with error bit) if a parameter is invalid. * * Errors (with error bit) from: fl_conversion_dynamic_to_unsigned_detect(). * @param address diff --git a/sources/c/tacocat/main/common/define.h b/sources/c/tacocat/main/common/define.h index 771ccf2..491cae3 100644 --- a/sources/c/tacocat/main/common/define.h +++ b/sources/c/tacocat/main/common/define.h @@ -35,6 +35,9 @@ extern "C" { * kt_tacocat_signal_*_d: * - check: When not using threads, this is how often to perform the check (lower numbers incur more kernel I/O). * - check_failsafe: When using threads, how many consecutive failures to check signal before aborting (as a recursion failsafe). + * + * kt_tacocat_interval_*_d: + * - poll: The time in milliseconds to poll for before returning (this is the amount of time poll() blocks). */ #ifndef _di_kt_tacocat_d_ #define kt_tacocat_allocation_console_d 4 @@ -49,6 +52,8 @@ extern "C" { #define kt_tacocat_signal_check_d 20000 #define kt_tacocat_signal_check_failsafe_d 20000 + + #define kt_tacocat_interval_poll_d 1400 // 1.4 second. #endif // _di_kt_tacocat_d_ /** diff --git a/sources/c/tacocat/main/common/type.c b/sources/c/tacocat/main/common/type.c index 9afdfc2..df227fc 100644 --- a/sources/c/tacocat/main/common/type.c +++ b/sources/c/tacocat/main/common/type.c @@ -11,6 +11,7 @@ extern "C" { fll_program_data_delete(&main->program); kt_tacocat_setting_delete(main->program, &main->setting); + kt_tacocat_thread_delete(main->program, &main->thread); } #endif // _di_kt_tacocat_main_delete_ @@ -53,6 +54,15 @@ extern "C" { } #endif // _di_kt_tacocat_setting_delete_ +#ifndef _di_kt_tacocat_thread_delete_ + f_status_t kt_tacocat_thread_delete(const fll_program_data_t program, kt_tacocat_thread_t * const thread) { + + if (!thread) return F_status_set_error(F_parameter); + + return F_none; + } +#endif // _di_kt_tacocat_thread_delete_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/sources/c/tacocat/main/common/type.h b/sources/c/tacocat/main/common/type.h index 1ca5726..f91767d 100644 --- a/sources/c/tacocat/main/common/type.h +++ b/sources/c/tacocat/main/common/type.h @@ -73,8 +73,11 @@ extern "C" { * * flag: Flags passed to the main function. * - * status_thread: A status used eclusively by the threaded signal handler. - * state: The state data used when processing data. + * status_receive: A status used eclusively by the receive thread. + * status_send: A status used eclusively by the send thread. + * status_signal: A status used eclusively by the threaded signal handler. + * + * state: The state data used when processing data. * * receive: The socket set for receiving data receive clients. * send: The socket set for sending data send clients. @@ -85,7 +88,10 @@ extern "C" { typedef struct { uint64_t flag; - f_status_t status_thread; + f_status_t status_receive; + f_status_t status_send; + f_status_t status_signal; + f_state_t state; kt_tacocat_socket_set_t receive; @@ -98,6 +104,8 @@ extern "C" { { \ kt_tacocat_main_flag_none_e, \ F_none, \ + F_none, \ + F_none, \ macro_f_state_t_initialize_1(kt_tacocat_allocation_large_d, kt_tacocat_allocation_small_d, F_none, 0, 0, &fll_program_standard_signal_handle, 0, 0, 0, 0), \ macro_kt_tacocat_setting_t_initialize_1(kt_tacocat_block_size_receive_d), \ macro_kt_tacocat_setting_t_initialize_1(kt_tacocat_block_size_send_d), \ @@ -122,17 +130,35 @@ extern "C" { #endif // _di_kt_tacocat_callback_t_ /** + * The main thread settings. + */ +#ifndef _di_kt_tacocat_thread_t_ + typedef struct { + f_thread_id_t id_receive; + f_thread_id_t id_send; + } kt_tacocat_thread_t; + + #define kt_tacocat_thread_t_initialize \ + { \ + f_thread_id_t_initialize, \ + f_thread_id_t_initialize, \ + } +#endif // _di_kt_tacocat_thread_t_ + +/** * The main program data as a single structure. * * program: The main program data. * setting: The settings data. * callback: The program callbacks. + * thread: The program thread data. */ #ifndef _di_kt_tacocat_main_t_ typedef struct { fll_program_data_t program; kt_tacocat_setting_t setting; kt_tacocat_callback_t callback; + kt_tacocat_thread_t thread; } kt_tacocat_main_t; #define kt_tacocat_main_t_initialize \ @@ -140,6 +166,7 @@ extern "C" { fll_program_data_t_initialize, \ kt_tacocat_setting_t_initialize, \ kt_tacocat_callback_t_initialize, \ + kt_tacocat_thread_t_initialize, \ } #endif // _di_kt_tacocat_main_t_ @@ -174,6 +201,23 @@ extern "C" { extern f_status_t kt_tacocat_setting_delete(const fll_program_data_t program, kt_tacocat_setting_t * const setting); #endif // _di_kt_tacocat_setting_delete_ +/** + * Delete the program main thread data. + * + * @param program + * The main program data. + * @param thread + * The program main thread data. + * + * @return + * F_none on success. + * + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_kt_tacocat_thread_delete_ + extern f_status_t kt_tacocat_thread_delete(const fll_program_data_t program, kt_tacocat_thread_t * const thread); +#endif // _di_kt_tacocat_thread_delete_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/sources/c/tacocat/main/process.c b/sources/c/tacocat/main/process.c index c7f71d9..9b1c8c3 100644 --- a/sources/c/tacocat/main/process.c +++ b/sources/c/tacocat/main/process.c @@ -8,84 +8,97 @@ extern "C" { void kt_tacocat_process_main(kt_tacocat_main_t * const main) { if (!main) return; - if (F_status_is_error(kt_tacocat_process_socket_set_error_has(main, kt_tacocat_long_receive_s, main->setting.receive))) return; - if (F_status_is_error(kt_tacocat_process_socket_set_error_has(main, kt_tacocat_long_send_s, main->setting.send))) return; - - // @todo Make this threaded, if threading is enabled (if threading is disabled then fork). - // TacocaT is intended to be simple, so be lazy and create a thread/fork for every single receive and send. - - kt_tacocat_process_socket_set_receive(main); - kt_tacocat_process_socket_set_send(main); - - // domain - // PF_INET = ipv4 - // PF_INET6 = ipv6 - // type - // SOCK_STREAM - // SOCK_DGRAM - // "struct sockaddr", "struct sockaddr_un", or "struct sockaddr_in" - // protocol - // f_socket_protocol_tcp - // f_socket_protocol_udp - - //f_socket_connect - - // @todo: - // 1: Establish connections. - // 2: read / write from files. - // 3: work or wait until told to terminate. - // 4: terminate. - - kt_tacocat_process_socket_set_disconnect(main, &main->setting.receive); - kt_tacocat_process_socket_set_disconnect(main, &main->setting.send); - - kt_tacocat_process_socket_set_error_handle(main, main->setting.receive); - kt_tacocat_process_socket_set_error_handle(main, main->setting.send); - } -#endif // _di_kt_tacocat_process_main_ + if (F_status_is_error(kt_tacocat_process_socket_set_error_has(main, kt_tacocat_long_receive_s, main->setting.receive, &main->setting.status_receive))) return; + if (F_status_is_error(kt_tacocat_process_socket_set_error_has(main, kt_tacocat_long_send_s, main->setting.send, &main->setting.status_send))) return; + + #ifdef _di_thread_support_ + // @todo implement fork and wait for both receive and send. + #else + { + if (main->setting.flag & kt_tacocat_main_flag_receive_e) { + memset(&main->thread.id_receive, 0, sizeof(f_thread_id_t)); + + main->setting.state.status = f_thread_create(0, &main->thread.id_receive, kt_tacocat_receive, (void *) main); + } + + if (F_status_is_error_not(main->setting.state.status)) { + if (main->setting.flag & kt_tacocat_main_flag_send_e) { + memset(&main->thread.id_send, 0, sizeof(f_thread_id_t)); + + main->setting.state.status = f_thread_create(0, &main->thread.id_send, kt_tacocat_send, (void *) main); + + if (F_status_is_error(main->setting.state.status) && (main->setting.flag & kt_tacocat_main_flag_receive_e)) { + f_thread_cancel(main->thread.id_receive); + } + } + } + + if (F_status_is_error(main->setting.state.status)) { + kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_thread_create)); + } + } -#ifndef _di_kt_tacocat_process_socket_set_disconnect_ - void kt_tacocat_process_socket_set_disconnect(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) { + if (main->setting.flag & kt_tacocat_main_flag_receive_e) { + f_thread_join(main->thread.id_receive, 0); - if (!main) return; + if (F_status_is_error(main->setting.status_receive)) { + main->setting.state.status = main->setting.status_receive; + } + } + + if (main->setting.flag & kt_tacocat_main_flag_send_e) { + f_thread_join(main->thread.id_send, 0); - if (!set) { - main->setting.state.status = F_status_set_error(F_parameter); + if (F_status_is_error(main->setting.status_send) && F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = main->setting.status_send; + } + } + #endif // _di_thread_support_ - return; + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = F_none; } + } +#endif // _di_kt_tacocat_process_main_ + +#ifndef _di_kt_tacocat_process_socket_set_disconnect_ + f_status_t kt_tacocat_process_socket_set_disconnect(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) { + + if (!main || !set) return F_status_set_error(F_parameter); f_status_t status = F_none; for (f_number_unsigned_t i = 0; i < set->sockets.used; ++i) { - if (kt_tacocat_signal_check(main)) return; + if (kt_tacocat_signal_check(main)) return F_status_set_error(F_interrupt); status = f_socket_disconnect(&set->sockets.array[i], f_socket_close_read_write_e); - if (F_status_is_error_not(set->statuss.array[i]) && F_status_is_error(main->setting.state.status)) { + if (F_status_is_error_not(set->statuss.array[i]) && F_status_is_error(status)) { set->statuss.array[i] = status; kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_socket_disconnect)); } } // for + + return F_none; } #endif // _di_kt_tacocat_process_socket_set_disconnect_ #ifndef _di_kt_tacocat_process_socket_set_error_handle_ - void kt_tacocat_process_socket_set_error_handle(kt_tacocat_main_t * const main, const kt_tacocat_socket_set_t set) { + void kt_tacocat_process_socket_set_error_handle(kt_tacocat_main_t * const main, const kt_tacocat_socket_set_t set, f_status_t * const status) { - if (!main) return; - if (F_status_is_error(main->setting.state.status)) return; + if (!main || !status) return; + if (F_status_is_error(*status)) return; - main->setting.state.status = F_none; + *status = F_none; for (f_number_unsigned_t i = 0; i < set.statuss.used; ++i) { if (kt_tacocat_signal_check(main)) return; if (F_status_is_error(set.statuss.array[i])) { - main->setting.state.status = set.statuss.array[i]; + *status = set.statuss.array[i]; return; } @@ -94,22 +107,24 @@ extern "C" { #endif // _di_kt_tacocat_process_socket_set_error_handle_ #ifndef _di_kt_tacocat_process_socket_set_error_has_ - f_status_t kt_tacocat_process_socket_set_error_has(kt_tacocat_main_t * const main, const f_string_static_t parameter, const kt_tacocat_socket_set_t set) { + f_status_t kt_tacocat_process_socket_set_error_has(kt_tacocat_main_t * const main, const f_string_static_t parameter, const kt_tacocat_socket_set_t set, f_status_t * const status) { - if (!main) { - main->setting.state.status = F_status_set_error(F_parameter); + if (!main || !status) { + if (status) { + *status = F_status_set_error(F_parameter); + } kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(kt_tacocat_process_socket_set_error_has)); - return main->setting.state.status; + return F_status_set_error(F_parameter); } if (set.sockets.used != set.files.used || set.sockets.used != set.files.used || set.sockets.used != set.statuss.used || set.sockets.used != set.names.used || set.sockets.used != set.buffers.used) { - main->setting.state.status = F_status_set_error(F_parameter); + *status = F_status_set_error(F_parameter); kt_tacocat_print_error_setting_socket_lengths_must_match(&main->program.error, parameter, set); - return main->setting.state.status; + return *status; } return F_none; @@ -119,9 +134,8 @@ extern "C" { #ifndef _di_kt_tacocat_process_socket_set_receive_ void kt_tacocat_process_socket_set_receive(kt_tacocat_main_t * const main) { - if (!main) return; + if (!main || F_status_is_error(main->setting.status_receive)) return; - // Create, bind, and listen to the socket. for (f_number_unsigned_t i = 0; i < main->setting.receive.sockets.used; ++i) { if (kt_tacocat_signal_check(main)) return; @@ -130,7 +144,7 @@ extern "C" { main->setting.receive.statuss.array[i] = f_socket_create(&main->setting.receive.sockets.array[i]); if (F_status_is_error(main->setting.receive.statuss.array[i])) { - main->setting.state.status = main->setting.receive.statuss.array[i]; + main->setting.status_receive = main->setting.receive.statuss.array[i]; kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_socket_create)); @@ -147,7 +161,7 @@ extern "C" { main->setting.receive.statuss.array[i] = f_socket_bind_local(&main->setting.receive.sockets.array[i]); } else { - main->setting.state.status = F_status_set_error(F_parameter); + main->setting.status_receive = F_status_set_error(F_parameter); kt_tacocat_print_error_socket_protocol_unsupported(&main->program.error, main->setting.receive.names.array[i], main->setting.receive.sockets.array[i].domain); @@ -155,7 +169,7 @@ extern "C" { } if (F_status_is_error(main->setting.receive.statuss.array[i])) { - main->setting.state.status = main->setting.receive.statuss.array[i]; + main->setting.status_receive = main->setting.receive.statuss.array[i]; kt_tacocat_print_error(&main->program.error, main->setting.receive.sockets.array[i].domain == f_socket_protocol_family_inet4_e ? macro_kt_tacocat_f(f_socket_bind_inet4) @@ -170,7 +184,7 @@ extern "C" { main->setting.receive.statuss.array[i] = f_socket_listen(&main->setting.receive.sockets.array[i], kt_tacocat_backlog_max_d); if (F_status_is_error(main->setting.receive.statuss.array[i])) { - main->setting.state.status = main->setting.receive.statuss.array[i]; + main->setting.status_receive = main->setting.receive.statuss.array[i]; kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_socket_listen)); @@ -189,13 +203,8 @@ extern "C" { } } // for - if (F_status_is_error_not(main->setting.state.status)) { - // @todo this is where another process should poll/wait for connections and such (in another thread/fork). - main->setting.state.status = f_file_poll(main->setting.receive.polls, 9000); // @todo temporarily set to 9 second(s). - - // @todo handle errors, but this will be in a fork/thread. - - main->setting.state.status = F_none; + if (F_status_is_error_not(main->setting.status_receive)) { + main->setting.status_receive = F_none; } } #endif // _di_kt_tacocat_process_socket_set_receive_ @@ -203,7 +212,7 @@ extern "C" { #ifndef _di_kt_tacocat_process_socket_set_send_ void kt_tacocat_process_socket_set_send(kt_tacocat_main_t * const main) { - if (!main) return; + if (!main || F_status_is_error(main->setting.status_send)) return; for (f_number_unsigned_t i = 0; i < main->setting.send.sockets.used; ++i) { @@ -213,7 +222,7 @@ extern "C" { main->setting.send.statuss.array[i] = f_socket_create(&main->setting.send.sockets.array[i]); if (F_status_is_error(main->setting.send.statuss.array[i])) { - main->setting.state.status = main->setting.send.statuss.array[i]; + main->setting.status_send = main->setting.send.statuss.array[i]; kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(f_socket_create)); @@ -223,8 +232,8 @@ extern "C" { // @todo f_socket_bind(). } // for - if (F_status_is_error_not(main->setting.state.status)) { - main->setting.state.status = F_none; + if (F_status_is_error_not(main->setting.status_send)) { + main->setting.status_send = F_none; } } #endif // _di_kt_tacocat_process_socket_set_send_ diff --git a/sources/c/tacocat/main/process.h b/sources/c/tacocat/main/process.h index 7a4af94..167533f 100644 --- a/sources/c/tacocat/main/process.h +++ b/sources/c/tacocat/main/process.h @@ -39,9 +39,14 @@ extern "C" { * This does not set parameter error on success or any socket disconnect error. * @param set * The socket set to disconnect all sockets of. + * + * @return + * F_none on success. + * + * F_parameter (with error bit) on invalid parameter. */ #ifndef _di_kt_tacocat_process_socket_set_disconnect_ - extern void kt_tacocat_process_socket_set_disconnect(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set); + extern f_status_t kt_tacocat_process_socket_set_disconnect(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set); #endif // _di_kt_tacocat_process_socket_set_disconnect_ /** @@ -60,9 +65,11 @@ extern "C" { * If this already has the error bit set, then no changes are performed. * @param set * The socket set to handle the errors of. + * @param status + * The status to update with the status code from the given set. */ #ifndef _di_kt_tacocat_process_socket_set_error_handle_ - extern void kt_tacocat_process_socket_set_error_handle(kt_tacocat_main_t * const main, const kt_tacocat_socket_set_t set); + extern void kt_tacocat_process_socket_set_error_handle(kt_tacocat_main_t * const main, const kt_tacocat_socket_set_t set, f_status_t * const status); #endif // _di_kt_tacocat_process_socket_set_error_handle_ /** @@ -72,21 +79,24 @@ extern "C" { * The main program and settings data. * * This alters main.setting.state.status: - * F_parameter (with error bit) on parameter error. + * F_parameter (with error bit) if a parameter is invalid. * * This is not altered on success. * @param parameter * The parameter long name to use when printing errors. * @param set * The socket set to handle the errors of. + * @param status + * The status to update with the status code from the given set. * * @return * F_none on no error. * - * F_parameter (with error bit) on parameter error. + * F_interrupt (with error bit) if interrupt was received. + * F_parameter (with error bit) if a parameter is invalid. */ #ifndef _di_kt_tacocat_process_socket_set_error_has_ - extern f_status_t kt_tacocat_process_socket_set_error_has(kt_tacocat_main_t * const main, const f_string_static_t parameter, const kt_tacocat_socket_set_t set); + extern f_status_t kt_tacocat_process_socket_set_error_has(kt_tacocat_main_t * const main, const f_string_static_t parameter, const kt_tacocat_socket_set_t set, f_status_t * const status); #endif // _di_kt_tacocat_process_socket_set_error_has_ /** diff --git a/sources/c/tacocat/main/receive.c b/sources/c/tacocat/main/receive.c new file mode 100644 index 0000000..7300ec9 --- /dev/null +++ b/sources/c/tacocat/main/receive.c @@ -0,0 +1,47 @@ +#include "tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_kt_tacocat_receive_ + void * kt_tacocat_receive(void * const void_main) { + + f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); + + if (!void_main) return 0; + + kt_tacocat_main_t * const main = (kt_tacocat_main_t *) void_main; + + kt_tacocat_process_socket_set_receive(main); + + if (F_status_is_error_not(main->setting.status_receive)) { + do { + main->setting.status_receive = f_file_poll(main->setting.receive.polls, kt_tacocat_interval_poll_d); + + if (main->program.signal_received) { + main->setting.status_receive = F_status_set_error(F_interrupt); + + return 0; + } + + // @todo handle errors + + } while (F_status_is_error_not(main->setting.status_receive)); + } + + kt_tacocat_process_socket_set_disconnect(main, &main->setting.receive); + + kt_tacocat_process_socket_set_error_handle(main, main->setting.receive, &main->setting.status_receive); + + if (F_status_is_error_not(main->setting.status_receive)) { + main->setting.status_receive = F_none; + } + + return 0; + } +#endif // _di_kt_tacocat_receive_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/tacocat/main/receive.h b/sources/c/tacocat/main/receive.h new file mode 100644 index 0000000..702a93f --- /dev/null +++ b/sources/c/tacocat/main/receive.h @@ -0,0 +1,38 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _kt_tacocat_receive_h +#define _kt_tacocat_receive_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Perform the receive operation for the receive sockets. + * + * @param main + * The main program and settings data. + * + * Must be of type kt_tacocat_main_t. + * + * This alters main.setting.state.status: + * F_none on success. + * F_child on child process exiting. + * + * @return + * 0, always. + */ +#ifndef _di_kt_tacocat_receive_ + extern void * kt_tacocat_receive(void * const main); +#endif // _di_kt_tacocat_receive_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_receive_h diff --git a/sources/c/tacocat/main/send.c b/sources/c/tacocat/main/send.c new file mode 100644 index 0000000..d7efc05 --- /dev/null +++ b/sources/c/tacocat/main/send.c @@ -0,0 +1,36 @@ +#include "tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_kt_tacocat_send_ + void * kt_tacocat_send(void * const void_main) { + + f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); + + if (!void_main) return 0; + + kt_tacocat_main_t * const main = (kt_tacocat_main_t *) void_main; + + kt_tacocat_process_socket_set_send(main); + + if (F_status_is_error_not(main->setting.status_send)) { + // @todo + } + + kt_tacocat_process_socket_set_disconnect(main, &main->setting.send); + + kt_tacocat_process_socket_set_error_handle(main, main->setting.send, &main->setting.status_send); + + if (F_status_is_error_not(main->setting.status_send)) { + main->setting.status_send = F_none; + } + + return 0; + } +#endif // _di_kt_tacocat_send_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/tacocat/main/send.h b/sources/c/tacocat/main/send.h new file mode 100644 index 0000000..55c4260 --- /dev/null +++ b/sources/c/tacocat/main/send.h @@ -0,0 +1,38 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _kt_tacocat_send_h +#define _kt_tacocat_send_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Perform the send operation for the send sockets. + * + * @param main + * The main program and settings data. + * + * Must be of type kt_tacocat_main_t. + * + * This alters main.setting.state.status: + * F_none on success. + * F_child on child process exiting. + * + * @return + * 0, always. + */ +#ifndef _di_kt_tacocat_send_ + extern void * kt_tacocat_send(void * const main); +#endif // _di_kt_tacocat_send_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_send_h diff --git a/sources/c/tacocat/main/signal.c b/sources/c/tacocat/main/signal.c index 46a47d6..026691a 100644 --- a/sources/c/tacocat/main/signal.c +++ b/sources/c/tacocat/main/signal.c @@ -52,9 +52,9 @@ extern "C" { 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); + main->setting.status_signal = f_signal_open(&main->program.signal); - if (F_status_is_error(main->setting.status_thread)) { + if (F_status_is_error(main->setting.status_signal)) { main->program.signal_received = F_signal_abort; return; @@ -64,9 +64,9 @@ extern "C" { do { memset(&information, 0, sizeof(siginfo_t)); - main->setting.status_thread = f_signal_wait(&main->program.signal.set, &information); + main->setting.status_signal = 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 (F_status_is_error(main->setting.status_signal) && F_status_set_fine(main->setting.status_signal) != F_interrupt) { if (++failsafe >= kt_tacocat_signal_check_failsafe_d) break; } @@ -83,13 +83,13 @@ extern "C" { } failsafe = 0; - main->setting.status_thread = F_none; + main->setting.status_signal = F_none; } while (!main->program.signal_received); f_signal_close(&main->program.signal); - if (F_status_is_error(main->setting.status_thread)) { + if (F_status_is_error(main->setting.status_signal)) { main->program.signal_received = F_signal_abort; } } diff --git a/sources/c/tacocat/main/tacocat.h b/sources/c/tacocat/main/tacocat.h index f0c837c..e7f066a 100644 --- a/sources/c/tacocat/main/tacocat.h +++ b/sources/c/tacocat/main/tacocat.h @@ -57,6 +57,8 @@ #include #include #include +#include +#include #include #include -- 1.8.3.1