The program appears to run and work for simple scripts.
I have not done an extensive code review.
I have not done an extensive runtime test.
This reduces the small allocation down from 16 to 8 which shows a closer allocation level to that of the 0.6 version of Controller.
The number of allocations is still fewer even with this change, so that is real good.
Add some missing code and handle other problems such as allocation problems.
An incorrect lock is being used on the execution.
I need to look out for other accidental lock migration mistakes.
This performs the time calculation changes that I recently added as a separate commit in the 0.6 version of Controller.
#define controller_allocation_iki_small_d 8
#define controller_allocation_large_d 256
#define controller_allocation_pipe_d 16384
- #define controller_allocation_small_d 16
+ #define controller_allocation_small_d 8
#endif // _di_controller_allocation_d_
/**
if (instances[i]) {
controller_instance_delete(instances[i]);
+ f_memory_delete(1, sizeof(controller_instance_t), (void **) &instances[i]);
+
instances[i] = 0;
}
} // for
if (!rule) return;
+ f_memory_array_resize(0, sizeof(f_char_t), (void **) &rule->alias.string, &rule->alias.used, &rule->alias.size);
f_memory_array_resize(0, sizeof(f_char_t), (void **) &rule->engine.string, &rule->engine.used, &rule->engine.size);
f_memory_array_resize(0, sizeof(f_char_t), (void **) &rule->name.string, &rule->name.used, &rule->name.size);
f_memory_array_resize(0, sizeof(f_char_t), (void **) &rule->path.string, &rule->path.used, &rule->path.size);
}
else {
if ((entry_action->code & controller_entry_rule_code_require_d) && main->program.error.verbosity > f_console_verbosity_quiet_e || !(entry_action->code & controller_entry_rule_code_require_d) && (main->program.warning.verbosity == f_console_verbosity_verbose_e || main->program.warning.verbosity == f_console_verbosity_debug_e)) {
- fl_print_t *print = 0;
-
- if (entry_action->code & controller_entry_rule_code_require_d) {
- print = &main->program.error;
- }
- else if (main->program.error.verbosity != f_console_verbosity_error_e) {
- print = &main->program.warning;
- }
+ fl_print_t * const print = (entry_action->code & controller_entry_rule_code_require_d)
+ ? &main->program.error
+ : (main->program.error.verbosity != f_console_verbosity_error_e)
+ ? &main->program.warning
+ : 0;
if (print) {
controller_print_message_entry_action_state(print, cache, entry_action, is_entry);
}
}
else if (entry_action->type == controller_entry_action_type_failsafe_e) {
-
if (failsafe) {
controller_print_warning_entry_action_failsafe_twice(&main->program.warning, cache, is_entry);
}
for (j = 0; j < instance->rule.environment.used; ++j) {
if (f_compare_dynamic(entry->define.array[i].key, instance->rule.environment.array[j]) == F_equal_to) {
-
for (k = 0; k < environment.used; ++k) {
if (f_compare_dynamic(entry->define.array[i].key, environment.array[k].key) == F_equal_to) {
-
environment.array[k].value.used = 0;
status = f_string_dynamic_append(entry->define.array[i].value, &environment.array[k].value);
}
}
+ // @fixme don't actually execute as even executing "bash" could be bad if the shell being run is something nefarious.
if (options & controller_instance_option_simulate_e) {
controller_print_entry_output_execute_simulate(&main->program.output, instance, program, arguments);
status = controller_time_sleep_nanoseconds(instance->main, delay);
}
}
-
- if (F_status_set_fine(status) != F_interrupt) {
- fl_execute_parameter_t simulated_parameter = macro_fl_execute_parameter_t_initialize_1(execute_set->parameter.option, execute_set->parameter.wait, instance->rule.has & controller_rule_has_environment_d ? execute_set->parameter.environment : 0, execute_set->parameter.signals, &f_string_empty_s);
-
- status = fll_execute_program(controller_default_engine_s, instance->rule.engine_arguments, &simulated_parameter, &execute_set->as, (void *) &result);
- }
}
else {
status = fll_execute_program(program, arguments, &execute_set->parameter, &execute_set->as, (void *) &result);
f_thread_unlock(&instance->lock);
- status_lock = controller_lock_write_instance(instance, &instance->active);
+ status_lock = controller_lock_write_instance(instance, &instance->lock);
if (F_status_is_error(status_lock)) {
controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false);
if (F_status_set_fine(status_lock) != F_interrupt) {
- status = controller_lock_read_instance(instance, &instance->active);
+ status = controller_lock_read_instance(instance, &instance->lock);
if (status == F_okay) return status_lock;
}
f_thread_unlock(&instance->lock);
- status_lock = controller_lock_read_instance(instance, &instance->active);
+ status_lock = controller_lock_read_instance(instance, &instance->lock);
if (F_status_is_error(status_lock)) {
controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_true);
f_thread_unlock(&instance->lock);
}
- status_lock = controller_lock_write_instance(instance, &instance->active);
+ status_lock = controller_lock_write_instance(instance, &instance->lock);
if (F_status_is_error(status_lock)) {
controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_false);
if (F_status_set_fine(status_lock) != F_interrupt) {
- status = controller_lock_read_instance(instance, &instance->active);
+ status = controller_lock_read_instance(instance, &instance->lock);
if (status == F_okay) return status_lock;
}
f_thread_unlock(&instance->lock);
- status_lock = controller_lock_read_instance(instance, &instance->active);
+ status_lock = controller_lock_read_instance(instance, &instance->lock);
if (F_status_is_error(status_lock)) {
controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_true);
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(instance->type, &main->thread)) return F_status_set_error(F_interrupt);
}
if (main->program.error.verbosity > f_console_verbosity_quiet_e) {
} // for
if (status == F_child || F_status_set_fine(status) == F_interrupt) break;
-
if (F_status_is_error(status) && !(instance->options & controller_instance_option_simulate_e)) break;
} // for
}
- if (status == F_child || F_status_set_fine(status) == F_interrupt) {
- return status;
- }
-
- if (!controller_thread_is_enabled_instance(instance)) {
- return F_status_set_error(F_interrupt);
- }
+ if (status == F_child || F_status_set_fine(status) == F_interrupt) return status;
+ if (!controller_thread_is_enabled_instance(instance)) return F_status_set_error(F_interrupt);
if ((instance->options & controller_instance_option_wait_e) && F_status_is_error_not(status) && (instance->options & controller_instance_option_validate_e)) {
status_lock = controller_rule_wait_all_instance_type(main, instance->type, F_false);
-
- if (F_status_set_fine(status_lock) == F_interrupt) {
- return status_lock;
- }
+ if (F_status_set_fine(status_lock) == F_interrupt) return status_lock;
}
if (!(instance->options & controller_instance_option_validate_e) && F_status_is_error_not(status)) {
if (F_status_is_error_not(status)) {
status = controller_rule_execute(main, instance->action, instance->options, instance);
+
if (status == F_child || F_status_set_fine(status) == F_interrupt || F_status_set_fine(status) == F_lock) return status;
if (F_status_is_error(status)) {
if (!argument) return 0;
- f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); // TODO: need to setup thread states as deferred before starting the thread to avoid needing to do this call.
+ f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0);
controller_t * const main = (controller_t *) argument;
if (F_status_is_error_not(*status) && *status != F_child) {
if (!(main->setting.flag & controller_main_flag_validate_e) || (main->setting.flag & controller_main_flag_simulate_e)) {
-
if (main->process.entry.pid == controller_entry_pid_require_e && 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_fail_e;
time->tv_nsec = (now.tv_usec * 1000);
}
- // If result would be greater than 1 second, then increment seconds without overflowing.
- if (time->tv_nsec > 500000000 && nanoseconds > 500000000) {
+ // Do not allow for nanoseconds to be too large.
+ if (nanoseconds > 999999999) {
+ long ns = nanoseconds;
+
+ do {
+ ns -= 1000000000;
+ ++(time->tv_sec);
+
+ } while (ns > 999999999);
+
+ time->tv_nsec += ns;
+ }
+ else {
+ time->tv_nsec += nanoseconds;
+ }
+
+ // If tv_nsec is 1 second or greater, then increment seconds.
+ if (time->tv_nsec > 999999999) {
++(time->tv_sec);
- time->tv_nsec = (time->tv_nsec - 500000000) + (nanoseconds - 500000000);
+ time->tv_nsec -= 1000000000;
}
}
#endif // _di_controller_time_now_