I did some testing and found some problems and some things to clean up.
Further reduce the small allocation to 4 which shows a decent reduction in memory waste.
#define controller_allocation_iki_small_d 8
#define controller_allocation_large_d 256
#define controller_allocation_pipe_d 16384
- #define controller_allocation_small_d 8
+ #define controller_allocation_small_d 4
#endif // _di_controller_allocation_d_
/**
#endif // _di_controller_cache_delete_
#ifndef _di_controller_cache_action_delete_
- void controller_cache_action_delete(controller_cache_action_t * const cache) {
+ void controller_cache_action_delete(controller_cache_action_t * const action) {
- if (!cache) return;
+ if (!action) return;
- f_memory_array_resize(0, sizeof(f_char_t), (void **) &cache->name_action.string, &cache->name_action.used, &cache->name_action.size);
- f_memory_array_resize(0, sizeof(f_char_t), (void **) &cache->name_file.string, &cache->name_file.used, &cache->name_file.size);
- f_memory_array_resize(0, sizeof(f_char_t), (void **) &cache->name_item.string, &cache->name_item.used, &cache->name_item.size);
- f_memory_array_resize(0, sizeof(f_char_t), (void **) &cache->generic.string, &cache->generic.used, &cache->generic.size);
+ f_memory_array_resize(0, sizeof(f_char_t), (void **) &action->name_action.string, &action->name_action.used, &action->name_action.size);
+ f_memory_array_resize(0, sizeof(f_char_t), (void **) &action->name_file.string, &action->name_file.used, &action->name_file.size);
+ f_memory_array_resize(0, sizeof(f_char_t), (void **) &action->name_item.string, &action->name_item.used, &action->name_item.size);
+ f_memory_array_resize(0, sizeof(f_char_t), (void **) &action->generic.string, &action->generic.used, &action->generic.size);
}
#endif // _di_controller_cache_action_delete_
/**
* De-allocate the Controller action cache.
*
- * @param cache
+ * @param action
* The action cache.
*
* Must not be NULL.
* @see f_memory_array_resize()
*/
#ifndef _di_controller_cache_action_delete_
- extern void controller_cache_action_delete(controller_cache_action_t * const cache);
+ extern void controller_cache_action_delete(controller_cache_action_t * const action);
#endif // _di_controller_cache_action_delete_
#ifdef __cplusplus
#endif // _di_controller_print_error_entry_
#ifndef _di_controller_print_error_entry_cache_
- f_status_t controller_print_error_entry_cache(fl_print_t * const print, controller_cache_action_t * const cache, const uint8_t is_entry) {
+ f_status_t controller_print_error_entry_cache(fl_print_t * const print, controller_cache_action_t * const action, const uint8_t is_entry) {
- if (!print || !cache) return F_status_set_error(F_output_not);
+ if (!print || !action) return F_status_set_error(F_output_not);
if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
fl_print_format("%r%[%QWhile processing ", print->to, f_string_eol_s, print->context, print->prefix);
- if (cache->name_action.used) {
+ if (action->name_action.used) {
fl_print_format("action '%]", print->to, print->context);
- fl_print_format(f_string_format_Q_single_s.string, print->to, print->notable, cache->name_action, print->notable);
+ fl_print_format(f_string_format_Q_single_s.string, print->to, print->notable, action->name_action, print->notable);
fl_print_format("%[' on line%] ", print->to, print->context, print->context);
- fl_print_format(f_string_format_un_single_s.string, print->to, print->notable, cache->line_action, print->notable);
+ fl_print_format(f_string_format_un_single_s.string, print->to, print->notable, action->line_action, print->notable);
fl_print_format("%[ for ", print->to, print->context);
}
- if (cache->name_item.used) {
+ if (action->name_item.used) {
fl_print_format("%r item '%]", print->to, is_entry ? controller_entry_s : controller_exit_s, print->context);
- fl_print_format(f_string_format_Q_single_s.string, print->to, print->notable, cache->name_item, print->notable);
+ fl_print_format(f_string_format_Q_single_s.string, print->to, print->notable, action->name_item, print->notable);
fl_print_format("%[' on line%] ", print->to, print->context, print->context);
- fl_print_format(f_string_format_un_single_s.string, print->to, print->notable, cache->line_item, print->notable);
+ fl_print_format(f_string_format_un_single_s.string, print->to, print->notable, action->line_item, print->notable);
fl_print_format("%[ for ", print->to, print->context);
}
- if (cache->name_file.used) {
- fl_print_format("%r file '%]", print->to, is_entry ? controller_entry_s : controller_exit_s, print->context);
- fl_print_format("%[%Q%]%['", print->to, print->notable, cache->name_file, print->notable, print->context);
+ if (action->name_file.used) {
+ fl_print_format("%r file '%]%[%Q%]%['", print->to, is_entry ? controller_entry_s : controller_exit_s, print->context, print->notable, action->name_file, print->notable, print->context);
}
fl_print_format(".%]%r", print->to, print->context, f_string_eol_s);
* This does not alter print.custom.setting.state.status.
*
* Must not be NULL.
- * @param cache
+ * @param action
* The action cache.
*
* Must not be NULL.
* F_output_not (with error bit) if setting is NULL.
*/
#ifndef _di_controller_print_error_entry_cache_
- extern f_status_t controller_print_error_entry_cache(fl_print_t * const print, controller_cache_action_t * const cache, const uint8_t is_entry);
+ extern f_status_t controller_print_error_entry_cache(fl_print_t * const print, controller_cache_action_t * const action, const uint8_t is_entry);
#endif // _di_controller_print_error_entry_cache_
/**
controller_lock_print(print->to, &main->thread);
- controller_print_error_rule_cache(print, action, F_true);
-
fl_print_format("%r%[%QFSS Extended List (FSS-0003) is not allowed for the Rule Item Action '%]", print->to, f_string_eol_s, print->context, print->prefix, print->context);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->notable, name, print->notable);
fl_print_format(f_string_format_sentence_end_quote_s.string, print->to, print->context, print->context, f_string_eol_s);
+ controller_print_error_rule_cache(print, action, F_true);
+
controller_unlock_print_flush(print->to, &main->thread);
return F_okay;
#endif // _di_controller_print_error_rule_action_fss_0003_unsupported_
#ifndef _di_controller_print_error_rule_action_missing_pid_
- f_status_t controller_print_error_rule_action_missing_pid(fl_print_t * const print, const f_string_static_t alias) {
+ f_status_t controller_print_error_rule_action_missing_pid(fl_print_t * const print, controller_cache_action_t * const action, const f_string_static_t alias) {
if (!print || !print->custom) return F_status_set_error(F_output_not);
if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
fl_print_format(f_string_format_Q_single_s.string, print->to, print->notable, alias, print->notable);
fl_print_format("%[' is not designating a pid file.%]%r", print->to, print->context, print->context, f_string_eol_s);
+ controller_print_error_rule_cache(print, action, F_true);
+
controller_unlock_print_flush(print->to, &main->thread);
return F_okay;
* This does not alter print.custom.setting.state.status.
*
* Must not be NULL.
+ * @param action
+ * The Action cache.
+ *
+ * Must not be NULL.
* @param alias
* The Rule alias of the Rule that is missing the pid file designation.
*
* F_output_not (with error bit) if setting is NULL.
*/
#ifndef _di_controller_print_error_rule_action_missing_pid_
- extern f_status_t controller_print_error_rule_action_missing_pid(fl_print_t * const print, const f_string_static_t alias);
+ extern f_status_t controller_print_error_rule_action_missing_pid(fl_print_t * const print, controller_cache_action_t * const action, const f_string_static_t alias);
#endif // _di_controller_print_error_rule_action_missing_pid_
/**
#ifndef _di_controller_print_error_rule_item_
f_status_t controller_print_error_rule_item(fl_print_t * const print, controller_cache_action_t * const action, const uint8_t item, const f_status_t status) {
- if (!print || !print->custom || !action || status == F_interrupt) return F_status_set_error(F_output_not);
- if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
+ if (!print || !print->custom || !action) return F_status_set_error(F_output_not);
+ if (print->verbosity < f_console_verbosity_error_e || status == F_interrupt) return F_output_not;
controller_t * const main = (controller_t *) print->custom;
- // fll_error_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_lock_print().
- f_thread_mutex_lock(&main->thread.lock.print);
+ controller_lock_print(print->to, &main->thread);
controller_print_error_rule_cache(print, action, item);
- f_file_stream_lock(print->to);
-
controller_unlock_print_flush(print->to, &main->thread);
return F_okay;
#endif // _di_controller_print_error_rule_item_
#ifndef _di_controller_print_error_rule_item_execute_
- f_status_t controller_print_error_rule_item_execute(fl_print_t * const print, controller_instance_t * const instance, const uint8_t script_is, const f_string_static_t name, const f_status_t status) {
+ f_status_t controller_print_error_rule_item_execute(fl_print_t * const print, const uint8_t script_is, const f_string_static_t name, const f_status_t status, const int result) {
- if (!print || !instance || !instance->main) return F_status_set_error(F_output_not);
+ if (!print || !print->custom) return F_status_set_error(F_output_not);
if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
- controller_lock_print(print->to, &instance->main->thread);
+ controller_t * const main = (controller_t *) print->custom;
+
+ controller_lock_print(print->to, &main->thread);
fl_print_format("%r%[%QThe %r '%]", print->to, f_string_eol_s, print->context, print->prefix, script_is ? controller_engine_s : controller_program_s, print->context);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->notable, name, print->notable);
fl_print_format("%]%['.%]%r", print->to, print->notable, print->context, print->context, f_string_eol_s);
}
- else if (WIFEXITED(instance->result) ? WEXITSTATUS(instance->result) : 0) {
- const uint8_t code = WIFEXITED(instance->result) ? WEXITSTATUS(instance->result) : 0;
+ else if (WIFEXITED(result) ? WEXITSTATUS(result) : 0) {
+ const uint8_t code = WIFEXITED(result) ? WEXITSTATUS(result) : 0;
if (code == F_execute_access) {
fl_print_format("%[' failed, access is denied.%]%r", print->to, print->context, print->context, f_string_eol_s);
fl_print_format("%[' failed.%]%r", print->to, print->context, print->context, f_string_eol_s);
}
- controller_unlock_print_flush(print->to, &instance->main->thread);
+ controller_unlock_print_flush(print->to, &main->thread);
return F_okay;
}
#endif // _di_controller_print_error_rule_item_need_want_wish_
#ifndef _di_controller_print_error_rule_item_rule_not_loaded_
- f_status_t controller_print_error_rule_item_rule_not_loaded(fl_print_t * const print, const f_string_static_t alias) {
+ f_status_t controller_print_error_rule_item_rule_not_loaded(fl_print_t * const print, controller_cache_action_t * const action, const f_string_static_t alias) {
if (!print || !print->custom) return F_status_set_error(F_output_not);
if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
controller_t * const main = (controller_t *) print->custom;
- if (print->verbosity == f_console_verbosity_quiet_e) return F_output_not;
+ controller_lock_print(print->to, &main->thread);
fl_print_format("%r%[%QThe rule '%]", print->to, f_string_eol_s, print->context, print->prefix, print->context);
fl_print_format(f_string_format_Q_single_s.string, print->to, print->notable, alias, print->notable);
fl_print_format("%[' is no longer loaded.%]%r", print->to, print->context, print->context, f_string_eol_s);
+ controller_print_error_rule_cache(print, action, F_false);
+
+ controller_unlock_print_flush(print->to, &main->thread);
+
return F_okay;
}
#endif // _di_controller_print_error_rule_item_rule_not_loaded_
* This does not alter print.custom.setting.state.status.
*
* Must not be NULL.
- * @param cache
+ * @param action
* The Action cache.
*
* Must not be NULL.
* F_output_not (with error bit) if setting is NULL.
*/
#ifndef _di_controller_print_error_rule_item_
- extern f_status_t controller_print_error_rule_item(fl_print_t * const print, controller_cache_action_t * const cache, const uint8_t item, const f_status_t status);
+ extern f_status_t controller_print_error_rule_item(fl_print_t * const print, controller_cache_action_t * const action, const uint8_t item, const f_status_t status);
#endif // _di_controller_print_error_rule_item_
/**
* This does not alter print.custom.setting.state.status.
*
* Must not be NULL.
- * @param instance
- * The process instance.
- *
- * Must not be NULL.
* @param script_is
* If TRUE, then this represents a script.
* If FALSE, then this represents a program.
* The code returned by the executed program or script.
* @param status
* The status code representing the failure (without the error bit set).
+ * @param result
+ * The status code result.
*
* @return
* F_okay on success.
* F_output_not (with error bit) if setting is NULL.
*/
#ifndef _di_controller_print_error_rule_item_execute_
- extern f_status_t controller_print_error_rule_item_execute(fl_print_t * const print, controller_instance_t * const instance, const uint8_t script_is, const f_string_static_t name, const f_status_t status);
+ extern f_status_t controller_print_error_rule_item_execute(fl_print_t * const print, const uint8_t script_is, const f_string_static_t name, const f_status_t status, const int result);
#endif // _di_controller_print_error_rule_item_execute_
/**
* Print an error or warning message related to need/want/wish settings of some rule.
*
* @param print
- * The error or warning output structure.
+ * The output structure to print to.
+ *
+ * This requires print.custom to be controller_t.
+ *
+ * This does not alter print.custom.setting.state.status.
+ *
+ * Must not be NULL.
* @param need_want_wish
* The appropriate string, such as "needs", "wants", or "wishes for" to output when describing this error/warning.
* This string is expected to already be "safe" (no control characters, etc..).
* Print an error or warning message about some rule not being loaded.
*
* @param print
- * The error or warning output structure.
+ * The output structure to print to.
+ *
+ * This requires print.custom to be controller_t.
+ *
+ * This does not alter print.custom.setting.state.status.
+ *
+ * Must not be NULL.
+ * @param action
+ * The Action cache.
+ *
+ * Must not be NULL.
* @param alias
* The Rule alias of the Rule that is not loaded.
*
* F_output_not (with error bit) if setting is NULL.
*/
#ifndef _di_controller_print_error_rule_item_rule_not_loaded_
- extern f_status_t controller_print_error_rule_item_rule_not_loaded(fl_print_t * const print, const f_string_static_t alias);
+ extern f_status_t controller_print_error_rule_item_rule_not_loaded(fl_print_t * const print, controller_cache_action_t * const action, const f_string_static_t alias);
#endif // _di_controller_print_error_rule_item_rule_not_loaded_
#ifdef __cplusplus
else {
success = F_status_set_error(F_failure);
- controller_print_error_rule_action_missing_pid(&main->program.error, instance->rule.alias);
+ controller_print_error_rule_action_missing_pid(&main->program.error, &instance->cache.action, instance->rule.alias);
}
}
else if (instance->rule.items.array[i].type == controller_rule_item_type_utility_e) {
else {
success = F_status_set_error(F_failure);
- controller_print_error_rule_action_missing_pid(&main->program.error, instance->rule.alias);
+ controller_print_error_rule_action_missing_pid(&main->program.error, &instance->cache.action, instance->rule.alias);
}
}
else {
status = F_status_set_fine(status);
if ((WIFEXITED(instance->result) && WEXITSTATUS(instance->result)) || status == F_control_group || status == F_failure || status == F_limit || status == F_processor || status == F_schedule) {
- controller_print_error_rule_item_execute(&instance->main->program.error, instance, type == controller_rule_item_type_script_e, program.used ? program : arguments.array[0], status);
+ controller_print_error_rule_item_execute(&instance->main->program.error, type == controller_rule_item_type_script_e, program.used ? program : arguments.array[0], status, instance->result);
}
else {
controller_print_error_status(&instance->main->program.error, macro_controller_f(fll_execute_program), F_status_set_fine(status));
controller_print_error_lock_critical(&main->program.error, F_status_set_fine(status_lock), F_true);
}
+ // The child instance should perform the change into background, therefore it is safe to wait for the child to exit (another instance is spawned).
if (F_status_set_fine(status_lock) != F_interrupt) {
-
- // The child instance should perform the change into background, therefore it is safe to wait for the child to exit (another instance is spawned).
waitpid(id_child, &result.status, 0);
}
- if (!controller_thread_is_enabled_instance(instance)) {
- return status_lock == F_okay ? F_status_set_error(F_interrupt) : F_status_set_error(F_lock);
- }
+ if (!controller_thread_is_enabled_instance(instance)) return status_lock == F_okay ? F_status_set_error(F_interrupt) : F_status_set_error(F_lock);
if (status_lock == F_okay) {
f_thread_unlock(&instance->lock);
status = F_status_set_fine(status);
if ((WIFEXITED(instance->result) && WEXITSTATUS(instance->result)) || status == F_control_group || status == F_failure || status == F_limit || status == F_processor || status == F_schedule) {
- controller_print_error_rule_item_execute(&instance->main->program.error, instance, type == controller_rule_item_type_utility_e, program.used ? program : arguments.array[0], status);
+ controller_print_error_rule_item_execute(&instance->main->program.error, type == controller_rule_item_type_utility_e, program.used ? program : arguments.array[0], status, instance->result);
}
else {
controller_print_error_status(&instance->main->program.error, macro_controller_f(fll_execute_program), F_status_set_fine(status));
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) {
- controller_lock_print(main->program.error.to, &main->thread);
-
- controller_print_error_rule_item_rule_not_loaded(&main->program.error, dynamics[i]->array[j]);
- controller_print_error_rule_cache(&main->program.error, &instance->cache.action, F_false);
-
- controller_unlock_print_flush(main->program.error.to, &main->thread);
- }
+ controller_print_error_rule_item_rule_not_loaded(&main->program.error, &instance->cache.action, dynamics[i]->array[j]);
return status;
}
if (F_status_is_error(status)) {
f_thread_unlock(&main->thread.lock.instance);
- if (main->program.error.verbosity > f_console_verbosity_quiet_e) {
- controller_lock_print(main->program.error.to, &main->thread);
-
- controller_print_error_rule_item_rule_not_loaded(&main->program.error, alias_rule);
- controller_print_error_rule_cache(&main->program.error, &cache->action, F_false);
-
- controller_unlock_print_flush(main->program.error.to, &main->thread);
- }
+ controller_print_error_rule_item_rule_not_loaded(&main->program.error, &cache->action, alias_rule);
return status;
}
status = F_status_set_error(F_found_not);
- if (instance->main->program.error.verbosity > f_console_verbosity_quiet_e) {
- controller_lock_print(instance->main->program.error.to, &instance->main->thread);
-
- controller_print_error_rule_item_rule_not_loaded(&instance->main->program.error, instance->rule.alias);
- controller_print_error_rule_cache(&instance->main->program.error, &instance->cache.action, F_false);
-
- controller_unlock_print_flush(instance->main->program.error.to, &instance->main->thread);
- }
+ controller_print_error_rule_item_rule_not_loaded(&instance->main->program.error, &instance->cache.action, instance->rule.alias);
}
if (status == F_child) {