if ((process->options & controller_rule_option_simulate) && main.data->parameters[controller_parameter_validate].result == f_console_result_found) {
controller_rule_validate(process->rule, controller_rule_action_type_start, process->options, main, &process->cache);
+
+ return F_none;
}
f_array_length_t i = 0;
controller_rule_error_print(main.data->error, process->cache.action, F_status_set_fine(status), "controller_rule_find", F_true, F_true, main.thread);
}
else {
- main.setting->rules.array[id_rule].status = process->rule.status;
+ controller_rule_t *rule = &main.setting->rules.array[id_rule];
+
+ rule->status = process->rule.status;
+
+ f_array_length_t j = 0;
+
+ controller_rule_item_t *rule_item = 0;
+ controller_rule_action_t *rule_action = 0;
- // @fixme the rule item action status needs to be copied over from the local rule to the old one but there is no way to map the two (the structure could have changeed).
+ // @todo implement a "version" counter and detect if the rule version is different before attempting update.
+ // copy all rule item action statuses from the rule process to the rule.
+ for (i = 0; i < rule->items.used; ++i) {
+
+ rule_item = &rule->items.array[i];
+
+ for (j = 0; j < rule_item->actions.used; ++j) {
+ rule_item->actions.array[j].status = process->rule.items.array[i].actions.array[j].status;
+ } // for
+ } // for
}
f_thread_unlock(&main.thread->lock.rule);
controller_cache_delete_simple(&process->cache);
f_type_array_lengths_resize(0, &process->stack);
+ // deallocate any rules in the space that is declared to be unused.
+ if (i >= main->thread->processs.used) {
+ controller_rule_delete_simple(&process->rule);
+ }
+
f_thread_unlock(&process->active);
} // for
thread.id_rule = 0;
status = thread.status;
- }
- if (status == F_child) {
- controller_thread_delete_simple(&thread);
+ if (status == F_child) {
+ controller_thread_delete_simple(&thread);
- return F_child;
+ return F_child;
+ }
}
}
}
+ // @todo consider redesigning to spawn forked processes from main thread to allow proper deallocation via a timed mutex condition (only need to do this for scripts).
+
// only make the rule and control threads available once any/all pre-processing and are completed.
if (F_status_is_error_not(status) && status != F_signal && status != F_child && thread.enabled) {
- if (data->parameters[controller_parameter_validate].result == f_console_result_none && thread.id_rule) {
+ if (data->parameters[controller_parameter_validate].result == f_console_result_none) {
- // wait for the entry thread to complete before starting the rule thread.
- f_thread_join(thread.id_rule, 0);
+ if (thread.id_rule) {
- if (thread.status == F_child) {
- controller_thread_delete_simple(&thread);
+ // wait for the entry thread to complete before starting the rule thread.
+ f_thread_join(thread.id_rule, 0);
- return F_child;
- }
+ if (thread.status == F_child) {
+ controller_thread_delete_simple(&thread);
- thread.id_rule = 0;
+ return F_child;
+ }
+
+ thread.id_rule = 0;
+ }
if (thread.enabled) {
status = f_thread_create(0, &thread.id_rule, &controller_thread_rule, (void *) &main);
- }
- status = f_thread_create(0, &thread.id_control, &controller_thread_control, (void *) &main);
+ if (F_status_is_error(status)) {
+ thread.id_rule = 0;
+ }
+ else {
+ status = f_thread_create(0, &thread.id_control, &controller_thread_control, (void *) &main);
+ }
- if (F_status_is_error(status)) {
- thread.id_control = 0;
- }
- else {
- status = f_thread_create(0, &thread.id_cleanup, &controller_thread_cleanup, (void *) &main);
- }
+ if (F_status_is_error(status)) {
+ thread.id_control = 0;
+ }
+ else {
+ status = f_thread_create(0, &thread.id_cleanup, &controller_thread_cleanup, (void *) &main);
+ }
- if (F_status_is_error(status)) {
- thread.id_cleanup = 0;
+ if (F_status_is_error(status)) {
+ thread.id_cleanup = 0;
- if (data->error.verbosity != f_console_verbosity_quiet) {
- controller_error_print(data->error, F_status_set_fine(status), "f_thread_create", F_true, &thread);
+ if (data->error.verbosity != f_console_verbosity_quiet) {
+ controller_error_print(data->error, F_status_set_fine(status), "f_thread_create", F_true, &thread);
+ }
}
}
}
thread.id_signal = 0;
}
- }
- controller_thread_process_cancel(&main);
+ controller_thread_process_cancel(&main);
+ }
if (thread.id_signal) f_thread_cancel(thread.id_signal);
if (thread.id_cleanup) f_thread_cancel(thread.id_cleanup);