#endif // _di_controller_thread_process_
#ifndef _di_controller_thread_process_cancel_
- void controller_thread_process_cancel(const controller_global_t global, const bool is_normal, const uint8_t by, controller_process_t * const caller) {
+ void controller_thread_process_cancel(const controller_global_t * const global, const bool is_normal, const uint8_t by, controller_process_t * const caller) {
- f_thread_mutex_lock(&global.thread->lock.cancel);
+ if (!global) return;
+
+ f_thread_mutex_lock(&global->thread->lock.cancel);
// Only cancel when enabled.
- if (!controller_thread_is_enabled(is_normal, global.thread)) {
- f_thread_mutex_unlock(&global.thread->lock.cancel);
+ if (!controller_thread_is_enabled(is_normal, global->thread)) {
+ f_thread_mutex_unlock(&global->thread->lock.cancel);
return;
}
pid_t pid = 0;
if (is_normal) {
- entry = &global.setting->entry;
+ entry = &global->setting->entry;
}
else {
- entry = &global.setting->exit;
+ entry = &global->setting->exit;
}
// A simple but inaccurate interval counter (expect this to be replaced in the future).
time.tv_sec = 0;
time.tv_nsec = interval_nanoseconds;
- if (global.setting->mode == controller_setting_mode_helper_e && global.main->parameters.array[controller_parameter_validate_e].result == f_console_result_none_e) {
+ if (global->setting->mode == controller_setting_mode_helper_e && global->main->parameters.array[controller_parameter_validate_e].result == f_console_result_none_e) {
int value = 0;
f_number_unsigned_t lapsed = 0;
- for (i = 0; i < global.thread->processs.used; ++i) {
+ for (i = 0; i < global->thread->processs.used; ++i) {
- if (!global.thread->processs.array[i]) continue;
+ if (!global->thread->processs.array[i]) continue;
if (caller && i == caller->id) continue;
- process = global.thread->processs.array[i];
+ process = global->thread->processs.array[i];
if (!process->id_thread) continue;
}
// Use the alert lock to toggle enabled (using it as if it is a write like and a signal lock).
- status = f_thread_mutex_lock(&global.thread->lock.alert);
+ status = f_thread_mutex_lock(&global->thread->lock.alert);
if (F_status_is_error(status)) {
- global.thread->enabled = controller_thread_enabled_not_e;
+ global->thread->enabled = controller_thread_enabled_not_e;
}
else {
if (by == controller_thread_cancel_execute_e) {
- global.thread->enabled = controller_thread_enabled_execute_e;
+ global->thread->enabled = controller_thread_enabled_execute_e;
}
else if (by == controller_thread_cancel_exit_e) {
- global.thread->enabled = controller_thread_enabled_not_e;
+ global->thread->enabled = controller_thread_enabled_not_e;
}
else if (by == controller_thread_cancel_exit_execute_e) {
- global.thread->enabled = controller_thread_enabled_exit_execute_e;
+ global->thread->enabled = controller_thread_enabled_exit_execute_e;
}
else {
- global.thread->enabled = controller_thread_enabled_exit_e;
+ global->thread->enabled = controller_thread_enabled_exit_e;
}
- f_thread_mutex_unlock(&global.thread->lock.alert);
+ f_thread_mutex_unlock(&global->thread->lock.alert);
}
- if (global.thread->id_cleanup) {
- f_thread_cancel(global.thread->id_cleanup);
- f_thread_join(global.thread->id_cleanup, 0);
+ if (global->thread->id_cleanup) {
+ f_thread_cancel(global->thread->id_cleanup);
+ f_thread_join(global->thread->id_cleanup, 0);
- global.thread->id_cleanup = 0;
+ global->thread->id_cleanup = 0;
}
- if (global.thread->id_control) {
- f_thread_cancel(global.thread->id_control);
- f_thread_join(global.thread->id_control, 0);
+ if (global->thread->id_control) {
+ f_thread_cancel(global->thread->id_control);
+ f_thread_join(global->thread->id_control, 0);
- global.thread->id_control = 0;
+ global->thread->id_control = 0;
}
// The sigtimedwait() function that is run inside of signal must be interrupted via the f_thread_cancel().
- if (by != controller_thread_cancel_signal_e && global.thread->id_signal) {
- f_thread_cancel(global.thread->id_signal);
- f_thread_join(global.thread->id_signal, 0);
+ if (by != controller_thread_cancel_signal_e && global->thread->id_signal) {
+ f_thread_cancel(global->thread->id_signal);
+ f_thread_join(global->thread->id_signal, 0);
- global.thread->id_signal = 0;
+ global->thread->id_signal = 0;
}
- if (global.setting->mode == controller_setting_mode_helper_e && global.main->parameters.array[controller_parameter_validate_e].result == f_console_result_none_e) {
- f_thread_mutex_unlock(&global.thread->lock.cancel);
+ if (global->setting->mode == controller_setting_mode_helper_e && global->main->parameters.array[controller_parameter_validate_e].result == f_console_result_none_e) {
+ f_thread_mutex_unlock(&global->thread->lock.cancel);
return;
}
- for (; i < global.thread->processs.used; ++i) {
+ for (; i < global->thread->processs.used; ++i) {
- if (!global.thread->processs.array[i]) continue;
+ if (!global->thread->processs.array[i]) continue;
if (caller && i == caller->id) continue;
- process = global.thread->processs.array[i];
+ process = global->thread->processs.array[i];
// Do not cancel exit processes, when not performing "execute" during exit.
- if (process->type == controller_process_type_exit_e && global.thread->enabled != controller_thread_enabled_exit_execute_e) {
+ if (process->type == controller_process_type_exit_e && global->thread->enabled != controller_thread_enabled_exit_execute_e) {
continue;
}
for (j = 0; j < process->childs.used; ++j) {
if (process->childs.array[j] > 0) {
- f_signal_send(global.thread->signal ? global.thread->signal : F_signal_termination, process->childs.array[j]);
+ f_signal_send(global->thread->signal ? global->thread->signal : F_signal_termination, process->childs.array[j]);
}
} // for
status = controller_file_pid_read(process->path_pids.array[j], &pid);
if (pid) {
- f_signal_send(global.thread->signal ? global.thread->signal : F_signal_termination, pid);
+ f_signal_send(global->thread->signal ? global->thread->signal : F_signal_termination, pid);
}
}
} // for
if (entry->timeout_exit && !(entry->flag & controller_entry_flag_timeout_exit_no_e)) {
f_number_unsigned_t lapsed = 0;
- for (i = 0; i < global.thread->processs.used && lapsed < entry->timeout_exit; ++i) {
+ for (i = 0; i < global->thread->processs.used && lapsed < entry->timeout_exit; ++i) {
- if (!global.thread->processs.array[i]) continue;
+ if (!global->thread->processs.array[i]) continue;
if (caller && i == caller->id) continue;
- process = global.thread->processs.array[i];
+ process = global->thread->processs.array[i];
// Do not wait for processes, when not performing "execute" during exit.
- if (process->type == controller_process_type_exit_e && global.thread->enabled != controller_thread_enabled_exit_execute_e) {
+ if (process->type == controller_process_type_exit_e && global->thread->enabled != controller_thread_enabled_exit_execute_e) {
continue;
}
} // for
}
- for (i = 0; i < global.thread->processs.size; ++i) {
+ for (i = 0; i < global->thread->processs.size; ++i) {
- if (!global.thread->processs.array[i]) continue;
+ if (!global->thread->processs.array[i]) continue;
if (caller && i == caller->id) continue;
- process = global.thread->processs.array[i];
+ process = global->thread->processs.array[i];
// Do not kill exit processes, when not performing "execute" during exit.
- if (process->type == controller_process_type_exit_e && global.thread->enabled != controller_thread_enabled_exit_execute_e) continue;
+ if (process->type == controller_process_type_exit_e && global->thread->enabled != controller_thread_enabled_exit_execute_e) continue;
if (process->id_thread) {
if (process->childs.used) {
for (j = 0; j < process->childs.size; ++j) {
// Do not kill exit processes, when not performing "execute" during exit.
- if (process->type == controller_process_type_exit_e && global.thread->enabled != controller_thread_enabled_exit_execute_e) continue;
+ if (process->type == controller_process_type_exit_e && global->thread->enabled != controller_thread_enabled_exit_execute_e) continue;
if (process->childs.array[j]) {
for (j = 0; j < process->path_pids.used; ++j) {
// Do not kill exit processes, when not performing "execute" during exit.
- if (process->type == controller_process_type_exit_e && global.thread->enabled != controller_thread_enabled_exit_execute_e) continue;
+ if (process->type == controller_process_type_exit_e && global->thread->enabled != controller_thread_enabled_exit_execute_e) continue;
if (f_file_exists(process->path_pids.array[j], F_true) == F_true) {
status = controller_file_pid_read(process->path_pids.array[j], &pid);
while (process->childs.used) {
// Do not shrink below an exit processes, when not performing "execute" during exit.
- if (process->type == controller_process_type_exit_e && global.thread->enabled != controller_thread_enabled_exit_execute_e) break;
+ if (process->type == controller_process_type_exit_e && global->thread->enabled != controller_thread_enabled_exit_execute_e) break;
if (process->childs.array[j] > 0) break;
--process->childs.used;
while (process->path_pids.used) {
// Do not shrink below an exit processes, when not performing "execute" during exit.
- if (process->type == controller_process_type_exit_e && global.thread->enabled != controller_thread_enabled_exit_execute_e) break;
+ if (process->type == controller_process_type_exit_e && global->thread->enabled != controller_thread_enabled_exit_execute_e) break;
if (process->path_pids.array[j].used) break;
--process->path_pids.used;
} // while
} // for
- f_thread_mutex_unlock(&global.thread->lock.cancel);
+ f_thread_mutex_unlock(&global->thread->lock.cancel);
}
#endif // _di_controller_thread_process_cancel_
controller_print_error(global->thread, global->main->error, F_status_set_fine(status), "f_thread_create", F_true);
}
- if (F_status_is_error_not(f_thread_mutex_lock(&global->thread->lock.alert))) {
- global->thread->enabled = controller_thread_enabled_not_e;
-
- f_thread_mutex_unlock(&global->thread->lock.alert);
- }
+ controller_thread_process_exit_force_set_disable(global);
}
else {
struct timespec time;
} while (F_status_is_error_not(status) && global->thread->enabled == controller_thread_enabled_exit_e);
- if (F_status_is_error(status)) {
- if (F_status_is_error_not(f_thread_mutex_lock(&global->thread->lock.alert))) {
- global->thread->enabled = controller_thread_enabled_not_e;
-
- f_thread_mutex_unlock(&global->thread->lock.alert);
- }
- }
+ if (F_status_is_error(status)) controller_thread_process_exit_force_set_disable(global);
}
// The sigtimedwait() function that is run inside of signal must be interrupted via the f_thread_cancel().
global->thread->id_signal = 0;
}
- controller_thread_process_cancel(*global, F_false, controller_thread_cancel_exit_e, 0);
+ controller_thread_process_cancel(global, F_false, controller_thread_cancel_exit_e, 0);
}
else {
- if (F_status_is_error_not(f_thread_mutex_lock(&global->thread->lock.alert))) {
+ controller_thread_process_exit_force_set_disable(global);
+ }
+ }
+#endif // _di_controller_thread_process_exit_
+
+#ifndef _di_controller_thread_process_exit_force_set_disable_
+ void controller_thread_process_exit_force_set_disable(const controller_global_t * const global) {
+
+ if (!global) return;
+
+ if (F_status_is_error_not(f_thread_mutex_lock(&global->thread->lock.alert))) {
+ global->thread->enabled = controller_thread_enabled_not_e;
+
+ f_thread_mutex_unlock(&global->thread->lock.alert);
+
+ return;
+ }
+
+ struct timespec time;
+
+ for (uint8_t i = 0; i < controller_thread_exit_disable_force_times; ++i) {
+
+ memset((void *) &time, 0, sizeof(struct timespec));
+
+ controller_time(controller_thread_exit_disable_force_timeout_seconds_d, controller_thread_exit_disable_force_timeout_nanoseconds_d, &time);
+
+ if (F_status_is_error_not(f_thread_mutex_lock_timed(&time, &global->thread->lock.alert))) {
global->thread->enabled = controller_thread_enabled_not_e;
f_thread_mutex_unlock(&global->thread->lock.alert);
+
+ return;
}
- }
+ } // for
+
+ // Forcibly set disable regardless of the risk.
+ global->thread->enabled = controller_thread_enabled_not_e;
}
-#endif // _di_controller_thread_process_exit_
+#endif // _di_controller_thread_process_exit_force_set_disable_
#ifndef _di_controller_thread_process_normal_
void * controller_thread_process_normal(void * const arguments) {