instance->id_thread = 0;
}
- // TODO: Review how the project uses locks and how to safely delete them.
- // The POSIX standard might quite horribly provide undefined behavior on double de-allocaton without providing a way to tell if the data is already de-allocated or not.
- // There may need to be a boolean/flag on each instance to designate whether or not the locks were initialized or not.
- // Actually, the instances is a double-pointer so that double-point can act as a boolean/flag.
f_thread_condition_delete(&instance->wait);
f_thread_lock_delete(&instance->lock);
f_thread_lock_delete(&instance->active);
#ifndef _di_controller_instance_initialize_
f_status_t controller_instance_initialize(controller_instance_t ** restrict const instance) {
+ if (!instance) return F_status_set_error(F_parameter);
+ if (*instance) return F_okay;
+
f_status_t status = f_memory_new(1, sizeof(controller_instance_t), (void **) instance);
if (F_status_is_error_not(status)) {
(*instance)->rule.status[i] = F_known_not;
} // for
- // TODO: There probably should be a boolean/flag to represent that the locks were initialized.
- // And on allocation failure on any lock before all locks are allocated should require that any allocated locks be de-allocated before returning on error.
-
return F_status_is_error(status) ? status : F_okay;
}
#endif // _di_controller_instance_initialize_
* @return
* F_okay on success.
*
+ * F_parameter (with error bit) on invalid parameter.
+ *
* Errors (with error bit) from: f_thread_condition_create().
* Errors (with error bit) from: f_thread_lock_create().
* Errors (with error bit) from: f_thread_mutex_create().
status = f_memory_array_increase(controller_allocation_small_d, sizeof(controller_instance_t), (void **) &main->thread.instances.array, &main->thread.instances.used, &main->thread.instances.size);
}
- printf("\nDEBUG: instances = (%lu, %lu), status=%d, %lu\n", main->thread.instances.used, main->thread.instances.size, F_status_set_fine(status), main->thread.instances.array[main->thread.instances.used]);
-
// The Instances array has instance as a double-pointer.
if (F_status_is_error_not(status) && !main->thread.instances.array[main->thread.instances.used]) {
status = controller_instance_initialize(&main->thread.instances.array[main->thread.instances.used]);
}
if (F_status_is_error_not(status)) {
- printf("\nDEBUG: instances before initialization = (%lu, %lu)\n", main->thread.instances.used, main->thread.instances.size);
// The Instances array has instance as a double-pointer.
status = controller_instance_initialize(&main->thread.instances.array[main->thread.instances.used]);
- printf("\nDEBUG: initialized instance at %lu, status = %d\n", main->thread.instances.used, F_status_set_fine(status));
-
controller_instance_t * const instance = F_status_is_error_not(status) ? main->thread.instances.array[main->thread.instances.used] : 0;
if (F_status_is_error_not(status)) {
return;
}
- // The locks must be initialized, but only once, so initialize immediately upon allocation.
- f_status_t status = controller_lock_create(&main->thread.lock);
-
- if (F_status_is_error(status)) {
- controller_print_error_status(&main->program.error, macro_controller_f(controller_lock_create), status);
- }/* else { // TODO: Is this block needed here, given allocation will also happen later on as needed?
- status = f_memory_array_increase(controller_allocation_small_d, sizeof(controller_instance_t), (void **) &main->thread.instances.array, &main->thread.instances.used, &main->thread.instances.size);
+ f_signal_set_fill(&main->program.signal.set);
- if (F_status_is_error(status)) {
- controller_print_error_status(&main->program.error, macro_controller_f(f_memory_array_increase), status);
- }
- }*/
+ f_status_t status = f_thread_signal_mask(SIG_BLOCK, &main->program.signal.set, 0);
if (F_status_is_error_not(status)) {
- status = f_thread_create(0, &main->thread.id_signal, &controller_thread_signal_normal, (void *) main);
+ status = f_signal_open(&main->program.signal);
}
+ // If there is an error opening a signal descriptor, then do not handle signals.
if (F_status_is_error(status)) {
- main->thread.id_signal = 0;
+ f_thread_signal_mask(SIG_UNBLOCK, &main->program.signal.set, 0);
+ f_signal_close(&main->program.signal);
+ }
+
+ // The locks must be initialized, but only once, so initialize immediately upon allocation.
+ status = controller_lock_create(&main->thread.lock);
- controller_print_error_status(&main->program.error, macro_controller_f(f_thread_create), status);
+ if (F_status_is_error(status)) {
+ controller_print_error_status(&main->program.error, macro_controller_f(controller_lock_create), status);
}
else {
- if (main->setting.flag & controller_main_flag_daemon_e) {
- main->process.ready = controller_process_ready_done_e;
+ status = f_thread_create(0, &main->thread.id_signal, &controller_thread_signal_normal, (void *) main);
- if (f_file_exists(main->process.path_pid, F_true) == F_true) {
- status = F_status_set_error(F_available_not);
- main->process.ready = controller_process_ready_abort_e;
+ if (F_status_is_error(status)) {
+ main->thread.id_signal = 0;
- controller_print_error_file_pid_exists(&main->program.error, &main->thread, main->process.path_pid);
- }
+ controller_print_error_status(&main->program.error, macro_controller_f(f_thread_create), status);
}
- else if (main->process.name_entry.used) {
- status = f_thread_create(0, &main->thread.id_entry, &controller_thread_entry, (void *) main);
+ else {
+ if (main->setting.flag & controller_main_flag_daemon_e) {
+ main->process.ready = controller_process_ready_done_e;
- if (F_status_is_error(status)) {
- controller_print_error_status(&main->program.error, macro_controller_f(f_thread_create), status);
+ if (f_file_exists(main->process.path_pid, F_true) == F_true) {
+ status = F_status_set_error(F_available_not);
+ main->process.ready = controller_process_ready_abort_e;
+
+ controller_print_error_file_pid_exists(&main->program.error, &main->thread, main->process.path_pid);
+ }
}
- else {
- controller_thread_join(&main->thread.id_entry);
+ else if (main->process.name_entry.used) {
+ status = f_thread_create(0, &main->thread.id_entry, &controller_thread_entry, (void *) main);
- status = main->thread.status;
- main->thread.id_entry = 0;
+ if (F_status_is_error(status)) {
+ controller_print_error_status(&main->program.error, macro_controller_f(f_thread_create), status);
+ }
+ else {
+ controller_thread_join(&main->thread.id_entry);
+
+ status = main->thread.status;
+ main->thread.id_entry = 0;
+ }
}
}
}
#endif
#ifndef _di_controller_rule_copy_
- f_status_t controller_rule_copy(const controller_rule_t source, controller_rule_t *destination) {
+ f_status_t controller_rule_copy(const controller_rule_t source, controller_rule_t * const destination) {
+
+ if (!destination) return F_status_set_error(F_parameter);
// Delete the third party structures.
f_memory_array_resize(0, sizeof(f_char_t), (void **) &destination->cgroup.path.string, &destination->cgroup.path.used, &destination->cgroup.path.size);
destination->ons.used = source.ons.used;
}
- status = f_memory_array_append_all(source.affinity.array, source.affinity.used, sizeof(int32_t), (void **) &destination->affinity.array, &destination->affinity.used, &destination->affinity.size);
+ status = f_memory_array_append_all((void *) source.affinity.array, source.affinity.used, sizeof(int32_t), (void **) &destination->affinity.array, &destination->affinity.used, &destination->affinity.size);
if (F_status_is_error(status)) return status;
if (source.capability) {
#endif // _di_controller_rule_copy_
#ifndef _di_controller_rule_find_
- f_status_t controller_rule_find(const f_string_static_t alias, const controller_rules_t rules, f_number_unsigned_t *at) {
+ f_status_t controller_rule_find(const f_string_static_t alias, const controller_rules_t rules, f_number_unsigned_t * const at) {
+ if (!at) return F_status_set_error(F_parameter);
if (!alias.used) return F_okay;
if (!rules.used) return F_false;
* @param destination
* The destination rule to copy to.
*
+ * Must not be NULL.
+ *
* @return
* F_okay on success.
*
* @see f_string_maps_append_all()
*/
#ifndef _di_controller_rule_copy_
- extern f_status_t controller_rule_copy(const controller_rule_t source, controller_rule_t *destination);
+ extern f_status_t controller_rule_copy(const controller_rule_t source, controller_rule_t * const destination);
#endif // _di_controller_rule_copy_
/**
* @param rules
* The rules to search through.
* @param at
- * The index the rule was found at.
- * (optional) Set to NULL to disable.
+ * (optional) The index the rule was found at.
+ *
+ * Set to NULL to disable.
*
* @return
* F_okay on success, but the id.used is 0.
* F_false on success and rule was not found.
*/
#ifndef _di_controller_rule_find_
- extern f_status_t controller_rule_find(const f_string_static_t alias, const controller_rules_t rules, f_number_unsigned_t *at);
+ extern f_status_t controller_rule_find(const f_string_static_t alias, const controller_rules_t rules, f_number_unsigned_t * const at);
#endif // _di_controller_rule_find_
/**
if (!controller_thread_is_enabled(is_normal, &main->thread)) return;
if (!(main->setting.flag & controller_main_flag_interruptible_e)) return;
- f_status_t status = F_okay;
siginfo_t information;
f_time_spec_t time = f_time_spec_t_initialize;
while (controller_thread_is_enabled(is_normal, &main->thread)) {
- controller_time_now(controller_thread_exit_ready_timeout_seconds_d, controller_thread_exit_ready_timeout_nanoseconds_d, &time);
-
memset((void *) &information, 0, sizeof(siginfo_t));
- status = f_signal_wait_until(&main->program.signal.set, &time, &information);
- if (status == F_time_out) continue;
+ controller_time_now(controller_thread_exit_ready_timeout_seconds_d, controller_thread_exit_ready_timeout_nanoseconds_d, &time);
+
+ if (f_signal_wait_until(&main->program.signal.set, &time, &information) == F_time_out) continue;
if (information.si_signo == F_signal_interrupt || information.si_signo == F_signal_abort || information.si_signo == F_signal_quit || information.si_signo == F_signal_termination) {
main->thread.signal = information.si_signo;
f_time_of_day_get(&now);
time->tv_sec = now.tv_sec + seconds;
- time->tv_nsec = (now.tv_usec * 1000) + nanoseconds;
+ time->tv_nsec = (now.tv_usec * 1000);
}
- // If tv_nsec is 1 second or greater, then increment seconds.
- if (time->tv_nsec >= 1000000000) {
+ // If result would be greater than 1 second, then increment seconds without overflowing.
+ if (time->tv_nsec > 500000000 && nanoseconds > 500000000) {
++(time->tv_sec);
- time->tv_nsec -= 1000000000;
+ time->tv_nsec = (time->tv_nsec - 500000000) + (nanoseconds - 500000000);
}
}
#endif // _di_controller_time_now_