]> Kevux Git Server - fll/commitdiff
Bugfix: Controller program print locking issues and fix delimits cache issue.
authorKevin Day <thekevinday@gmail.com>
Sun, 26 Sep 2021 22:30:18 +0000 (17:30 -0500)
committerKevin Day <thekevinday@gmail.com>
Sun, 26 Sep 2021 22:30:18 +0000 (17:30 -0500)
The locking as it is implemented is incomplete.
In many places, it unlocks twice.
There are some places where locking is not correctly being locked or unlocked, resulting in deadlocks.

Rewrite controller_print_unlock_flush(), and also add controller_print_lock().

I belive the problem is simply a result of many design changes in the locking and I just missed a number of places.

There are some printing where the parameters should have been printed but are not correctly printed.
Make sure controller_entry_action_parameters_print() is called in these places.

Make sure the cache delimits is cleared before calling fll_fss_extended_read().

level_3/controller/c/private-common.c
level_3/controller/c/private-common.h
level_3/controller/c/private-controller.c
level_3/controller/c/private-entry.c
level_3/controller/c/private-rule.c
level_3/controller/c/private-rule.h
level_3/controller/c/private-thread.c

index f8d829e9f36ee8ba7ab8cede1ab31a41138582f5..b31c5cfdcf386d471100e2547e29ce727d4fc817 100644 (file)
@@ -187,11 +187,17 @@ extern "C" {
   void controller_error_file_print(const fll_error_print_t print, const f_status_t status, const f_string_t function, const bool fallback, const f_string_t name, const f_string_t operation, const uint8_t type, controller_thread_t *thread) {
 
     if (print.verbosity != f_console_verbosity_quiet) {
-      f_thread_mutex_lock(&thread->lock.print);
+
+      // fll_error_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_print_lock().
+      if (thread) {
+        f_thread_mutex_lock(&thread->lock.print);
+      }
 
       fll_error_file_print(print, status, function, fallback, name, operation, type);
 
-      controller_print_unlock_flush(print.to.stream, &thread->lock.print);
+      if (thread) {
+        f_thread_mutex_unlock(&thread->lock.print);
+      }
     }
   }
 #endif // _di_controller_error_file_print_
@@ -199,18 +205,16 @@ extern "C" {
 #ifndef _di_controller_error_pid_bad_match_print_
   void controller_error_pid_bad_match_print(const fll_error_print_t print, const f_string_t path, controller_thread_t *thread) {
 
-    if (thread) f_thread_mutex_lock(&thread->lock.print);
-
-    flockfile(print.to.stream);
-
-    fl_print_format("%c%[%SThe pid file '%]", print.to.stream, f_string_eol_s[0], print.context, print.prefix ? print.prefix : f_string_empty_s, print.context);
-    fl_print_format("%[' must not be specified with the parameter '%]", print.to.stream, print.context, print.context);
-    fl_print_format("%[%S%]", print.to.stream, print.notable, path, print.notable);
-    fl_print_format("%[' doesn't contain the expected number, not deleting file.%]%c", print.to.stream, print.context, print.context, f_string_eol_s[0]);
+    if (print.verbosity != f_console_verbosity_quiet) {
+      controller_print_lock(print.to, thread);
 
-    funlockfile(print.to.stream);
+      fl_print_format("%c%[%SThe pid file '%]", print.to.stream, f_string_eol_s[0], print.context, print.prefix ? print.prefix : f_string_empty_s, print.context);
+      fl_print_format("%[' must not be specified with the parameter '%]", print.to.stream, print.context, print.context);
+      fl_print_format("%[%S%]", print.to.stream, print.notable, path, print.notable);
+      fl_print_format("%[' doesn't contain the expected number, not deleting file.%]%c", print.to.stream, print.context, print.context, f_string_eol_s[0]);
 
-    if (thread) controller_print_unlock_flush(print.to.stream, &thread->lock.print);
+      controller_print_unlock_flush(print.to, thread);
+    }
   }
 #endif // _di_controller_error_pid_bad_match_print_
 
@@ -218,11 +222,17 @@ extern "C" {
   void controller_error_print(const fll_error_print_t print, const f_status_t status, const f_string_t function, const bool fallback, controller_thread_t *thread) {
 
     if (print.verbosity != f_console_verbosity_quiet) {
-      f_thread_mutex_lock(&thread->lock.print);
+
+      // fll_error_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_print_lock().
+      if (thread) {
+        f_thread_mutex_lock(&thread->lock.print);
+      }
 
       fll_error_print(print, status, function, fallback);
 
-      controller_print_unlock_flush(print.to.stream, &thread->lock.print);
+      if (thread) {
+        f_thread_mutex_unlock(&thread->lock.print);
+      }
     }
   }
 #endif // _di_controller_error_print_
@@ -307,9 +317,7 @@ extern "C" {
     }
 
     if (print.verbosity != f_console_verbosity_quiet) {
-      f_thread_mutex_lock(&thread->lock.print);
-
-      flockfile(print.to.stream);
+      controller_print_lock(print.to, thread);
 
       fl_print_format("%c%[%SThe pid file '%]", print.to.stream, f_string_eol_s[0], print.context, print.prefix ? print.prefix : f_string_empty_s, print.context);
       fl_print_format("%['Critical failure while attempting to establish '%]", print.to.stream, print.context, print.context);
@@ -334,9 +342,7 @@ extern "C" {
 
       fl_print_format("%['.%]%c", print.to.stream, print.context, print.context, f_string_eol_s[0]);
 
-      funlockfile(print.to.stream);
-
-      controller_print_unlock_flush(print.to.stream, &thread->lock.print);
+      controller_print_unlock_flush(print.to, thread);
     }
   }
 #endif // _di_controller_lock_error_critical_print_
@@ -463,15 +469,26 @@ extern "C" {
   }
 #endif // _di_controller_pids_resize_
 
-#ifndef _di_controller_print_unlock_flush_
-  void controller_print_unlock_flush(FILE * const stream, f_thread_mutex_t *mutex) {
+#ifndef _di_controller_print_lock_
+  void controller_print_lock(const f_file_t to, controller_thread_t * const thread) {
 
-    if (stream == 0 || mutex == 0) {
-      return;
+    if (thread) {
+      f_thread_mutex_lock(&thread->lock.print);
     }
 
-    fflush(stream);
-    f_thread_mutex_unlock(mutex);
+    flockfile(to.stream);
+  }
+#endif // _di_controller_print_lock_
+
+#ifndef _di_controller_print_unlock_flush_
+  void controller_print_unlock_flush(const f_file_t to, controller_thread_t * const thread) {
+
+    fflush(to.stream);
+    funlockfile(to.stream);
+
+    if (thread) {
+      f_thread_mutex_unlock(&thread->lock.print);
+    }
   }
 #endif // _di_controller_print_unlock_flush_
 
index 4413b7033f4b5b2d0a95c8cad44ae0899da11e09..662fc73938c3f243655b1a9749ddecf7756c1fa2 100644 (file)
@@ -1594,7 +1594,8 @@ extern "C" {
  * @param type
  *   A valid file type code from the fll_error_file_type enum.
  * @param thread
- *   The thread data.
+ *   (optional) The thread data.
+ *   Set to NULL to disable locking on the thread (this should be done only if the lock is already in place).
  *
  * @see fll_error_file_print()
  */
@@ -1635,7 +1636,8 @@ extern "C" {
  * @param fallback
  *   Set to F_true to print the fallback error message for unknown errors.
  * @param thread
- *   The thread data.
+ *   (optional) The thread data.
+ *   Set to NULL to disable locking on the thread (this should be done only if the lock is already in place).
  *
  * @see fll_error_print()
  */
@@ -1916,20 +1918,44 @@ extern "C" {
 #endif // _di_controller_pids_resize_
 
 /**
+ * Lock the mutex and the stream.
+ *
+ * This is implemented as a compliment to controller_print_unlock_flush() for consistency reasons.
+ *
+ * @param to
+ *   The file stream to lock.
+ * @param thread
+ *   The thread containing the print mutex to lock.
+ *
+ * @see flockfile()
+ *
+ * @see f_thread_mutex_unlock()
+ */
+#ifndef _di_controller_print_lock_
+  extern void controller_print_lock(const f_file_t to, controller_thread_t * const thread) f_attribute_visibility_internal;
+#endif // _di_controller_print_lock_
+
+/**
  * Flush the stream buffer and then unlock the mutex.
  *
+ * This unlocks both the stream and the mutex locks.
+ *
  * Weird behavior was observed when piping data from this program.
  * The behavior appears related to how this handles locks in addition to the file streams own locking mechanisms.
  *
  * As a work-around, this performs a flush immediately before unlocking the print mutex.
  *
- * @param stream
- *   The output stream to flush.
- * @param mutex
- *   The print mutex to unlock.
+ * @param to
+ *   The file stream to unlock and flush.
+ * @param thread
+ *   The thread containing the print mutex to unlock.
+ *
+ * @see funlockfile()
+ *
+ * @see f_thread_mutex_unlock()
  */
 #ifndef _di_controller_print_unlock_flush_
-  void controller_print_unlock_flush(FILE * const stream, f_thread_mutex_t *mutex) f_attribute_visibility_internal;
+  void controller_print_unlock_flush(const f_file_t to, controller_thread_t * const thread) f_attribute_visibility_internal;
 #endif // _di_controller_print_unlock_flush_
 
 /**
index b09425e2bdad541fcbb2830f5893ffb9767a3277..004f19ad0aa9f946864e87e2641cea9a7938e80a 100644 (file)
@@ -109,11 +109,7 @@ extern "C" {
       }
 
       if (global.main->error.verbosity != f_console_verbosity_quiet) {
-        f_thread_mutex_lock(&global.thread->lock.print);
-
-        fll_error_file_print(global.main->error, F_status_set_fine(status), "f_file_stream_open", F_true, path, "open", fll_error_file_type_file);
-
-        controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+        controller_error_file_print(global.main->error, F_status_set_fine(status), "f_file_stream_open", F_true, path, "open", fll_error_file_type_file, global.thread);
       }
     }
     else {
@@ -121,11 +117,7 @@ extern "C" {
 
       if (F_status_is_error(status)) {
         if (global.main->error.verbosity != f_console_verbosity_quiet) {
-          f_thread_mutex_lock(&global.thread->lock.print);
-
-          fll_error_file_print(global.main->error, F_status_set_fine(status), "f_file_stream_read", F_true, path, "read", fll_error_file_type_file);
-
-          controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+          controller_error_file_print(global.main->error, F_status_set_fine(status), "f_file_stream_read", F_true, path, "read", fll_error_file_type_file, global.thread);
         }
       }
     }
@@ -139,11 +131,7 @@ extern "C" {
 
       if (F_status_is_error(status)) {
         if (global.main->error.verbosity != f_console_verbosity_quiet) {
-          f_thread_mutex_lock(&global.thread->lock.print);
-
-          fll_error_file_print(global.main->error, F_status_set_fine(status), "f_file_stat", F_true, path, "stat", fll_error_file_type_file);
-
-          controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+          controller_error_file_print(global.main->error, F_status_set_fine(status), "f_file_stat", F_true, path, "stat", fll_error_file_type_file, global.thread);
         }
       }
       else {
@@ -423,26 +411,30 @@ extern "C" {
         // always return immediately on memory errors.
         if (F_status_set_fine(status) == F_memory_not) {
           if (global.main->error.verbosity != f_console_verbosity_quiet) {
-            f_thread_mutex_lock(&global.thread->lock.print);
+            controller_print_lock(global.main->error.to, global.thread);
+
+            controller_error_file_print(global.main->error, F_status_set_fine(status), "controller_file_pid_create", F_true, global.setting->path_pid.string, "create", fll_error_file_type_file, 0);
 
-            fll_error_file_print(global.main->error, F_status_set_fine(status), "controller_file_pid_create", F_true, global.setting->path_pid.string, "create", fll_error_file_type_file);
+            flockfile(global.main->error.to.stream);
 
             controller_entry_error_print_cache(is_entry, global.main->error, cache->action);
 
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
           }
 
           return status;
         }
 
         if (global.main->warning.verbosity == f_console_verbosity_debug) {
-          f_thread_mutex_lock(&global.thread->lock.print);
+          controller_print_lock(global.main->warning.to, global.thread);
 
-          fll_error_file_print(global.main->warning, F_status_set_fine(status), "controller_file_pid_create", F_true, global.setting->path_pid.string, "create", fll_error_file_type_file);
+          controller_error_file_print(global.main->warning, F_status_set_fine(status), "controller_file_pid_create", F_true, global.setting->path_pid.string, "create", fll_error_file_type_file, 0);
+
+          flockfile(global.main->warning.to.stream);
 
           controller_entry_error_print_cache(is_entry, global.main->warning, cache->action);
 
-          controller_print_unlock_flush(global.main->warning.to.stream, &global.thread->lock.print);
+          controller_print_unlock_flush(global.main->warning.to, global.thread);
         }
 
         status = F_none;
@@ -530,9 +522,7 @@ extern "C" {
 
           if (global.setting->ready == controller_setting_ready_wait) {
             if (global.main->warning.verbosity == f_console_verbosity_debug) {
-              f_thread_mutex_lock(&global.thread->lock.print);
-
-              flockfile(global.main->warning.to.stream);
+              controller_print_lock(global.main->warning.to, global.thread);
 
               fl_print_format("%c%[%SMultiple '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, global.main->warning.context);
               fl_print_format("%[%s%]", global.main->warning.to.stream, global.main->warning.notable, controller_string_ready_s, global.main->warning.notable);
@@ -540,9 +530,7 @@ extern "C" {
 
               controller_entry_error_print_cache(is_entry, global.main->warning, cache->action);
 
-              funlockfile(global.main->warning.to.stream);
-
-              controller_print_unlock_flush(global.main->warning.to.stream, &global.thread->lock.print);
+              controller_print_unlock_flush(global.main->warning.to, global.thread);
             }
           }
 
@@ -569,9 +557,7 @@ extern "C" {
 
                 if (cache->ats.array[j] == i) {
                   if (global.main->error.verbosity != f_console_verbosity_quiet) {
-                    f_thread_mutex_lock(&global.thread->lock.print);
-
-                    flockfile(global.main->error.to.stream);
+                    controller_print_lock(global.main->error.to, global.thread);
 
                     fl_print_format("%c%[%SThe %s item named '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, is_entry ? controller_string_entry_s : controller_string_exit_s, global.main->error.prefix, global.main->error.context);
                     fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, entry->items.array[i].name, global.main->error.notable);
@@ -579,9 +565,7 @@ extern "C" {
 
                     controller_entry_error_print_cache(is_entry, global.main->error, cache->action);
 
-                    funlockfile(global.main->error.to.stream);
-
-                    controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                    controller_print_unlock_flush(global.main->error.to, global.thread);
                   }
 
                   if (F_status_is_error_not(status)) {
@@ -635,9 +619,7 @@ extern "C" {
           if (error_has || i >= entry->items.used) {
             if (i >= entry->items.used) {
               if (global.main->error.verbosity != f_console_verbosity_quiet) {
-                f_thread_mutex_lock(&global.thread->lock.print);
-
-                flockfile(global.main->error.to.stream);
+                controller_print_lock(global.main->error.to, global.thread);
 
                 fl_print_format("%c%[%SThe %s item named '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, is_entry ? controller_string_entry_s : controller_string_exit_s, global.main->error.prefix, global.main->error.context);
                 fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, actions->array[cache->ats.array[at_j]].parameters.array[0], global.main->error.notable);
@@ -645,9 +627,7 @@ extern "C" {
 
                 controller_entry_error_print_cache(is_entry, global.main->error, cache->action);
 
-                funlockfile(global.main->error.to.stream);
-
-                controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                controller_print_unlock_flush(global.main->error.to, global.thread);
               }
 
               if (F_status_is_error_not(status)) {
@@ -764,16 +744,12 @@ extern "C" {
 
     if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose) {
       if (global->main->error.verbosity != f_console_verbosity_quiet) {
-        f_thread_mutex_lock(&global->thread->lock.print);
-
-        flockfile(global->main->output.stream);
+        controller_print_lock(global->main->output, global->thread);
 
         fl_print_format("%cProcessing %s%s item '", global->main->output.stream, f_string_eol_s[0], failsafe ? "failsafe " : "", is_entry ? controller_string_entry_s : controller_string_exit_s);
         fl_print_format("%[%Q%]'.%c", global->main->output.stream, global->main->context.set.notable, cache->action.name_item, global->main->context.set.notable, f_string_eol_s[0]);
 
-        funlockfile(global->main->output.stream);
-
-        controller_print_unlock_flush(global->main->output.stream, &global->thread->lock.print);
+        controller_print_unlock_flush(global->main->output, global->thread);
       }
     }
 
@@ -800,9 +776,7 @@ extern "C" {
           if (controller_entry_action_type_is_rule(entry_action->type)) {
             if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found) {
               if (global->main->error.verbosity != f_console_verbosity_quiet) {
-                f_thread_mutex_lock(&global->thread->lock.print);
-
-                flockfile(global->main->output.stream);
+                controller_print_lock(global->main->output, global->thread);
 
                 fl_print_format("%cThe %s item action '", global->main->output.stream, f_string_eol_s[0], is_entry ? controller_string_entry_s : controller_string_exit_s);
                 fl_print_format("%[%Q%]", global->main->output.stream, global->main->context.set.title, cache->action.name_action, global->main->context.set.title);
@@ -810,16 +784,14 @@ extern "C" {
                 if (entry_action->parameters.used) {
                   fl_print_format(" %[", global->main->output.stream, global->main->context.set.notable);
 
-                  controller_entry_action_parameters_print(global->main->output.stream, entry_actions->array[cache->ats.array[at_j]]);
+                  controller_entry_action_parameters_print(global->main->output.stream, *entry_action);
 
                   fl_print_format("%]", global->main->output.stream, global->main->context.set.notable);
                 }
 
                 fl_print_format("' is %s and is in a %[failed%] state, skipping execution.%c", global->main->output.stream, entry_action->code & controller_entry_rule_code_require ? "required" : "optional", f_string_eol_s[0]);
 
-                funlockfile(global->main->output.stream);
-
-                controller_print_unlock_flush(global->main->output.stream, &global->thread->lock.print);
+                controller_print_unlock_flush(global->main->output, global->thread);
               }
             }
             else if ((entry_action->code & controller_entry_rule_code_require) && global->main->error.verbosity != f_console_verbosity_quiet || global->main->warning.verbosity == f_console_verbosity_verbose || global->main->warning.verbosity == f_console_verbosity_debug) {
@@ -832,15 +804,17 @@ extern "C" {
                 output = &global->main->warning;
               }
 
-              f_thread_mutex_lock(&global->thread->lock.print);
-
-              flockfile(output->to.stream);
+              controller_print_lock(output->to, global->thread);
 
               fl_print_format("%c%[%SThe %s item action '%]", output->to.stream, f_string_eol_s[0], output->context, output->prefix ? output->prefix : f_string_empty_s, is_entry ? controller_string_entry_s : controller_string_exit_s, output->context);
               fl_print_format("%[%Q%]", output->to.stream, output->notable, cache->action.name_action, output->notable);
 
               if (entry_action->parameters.used) {
-                fl_print_format(" %[%S%]", output->to.stream, output->notable, entry_actions->array[cache->ats.array[at_j]], output->notable);
+                fl_print_format(" %[", output->to.stream, global->main->context.set.notable);
+
+                controller_entry_action_parameters_print(output->to.stream, *entry_action);
+
+                fl_print_format("%]", output->to.stream, global->main->context.set.notable);
               }
 
               fl_print_format("%[' is%] %[required%]", output->to.stream, output->context, output->context, output->notable, output->notable);
@@ -849,9 +823,7 @@ extern "C" {
 
               controller_entry_error_print_cache(is_entry, *output, cache->action);
 
-              funlockfile(output->to.stream);
-
-              controller_print_unlock_flush(output->to.stream, &global->thread->lock.print);
+              controller_print_unlock_flush(output->to, global->thread);
 
               if (entry_action->code & controller_entry_rule_code_require) {
                 return F_status_is_error(F_require);
@@ -869,15 +841,17 @@ extern "C" {
                 output = &global->main->warning;
               }
 
-              f_thread_mutex_lock(&global->thread->lock.print);
-
-              flockfile(output->to.stream);
+              controller_print_lock(output->to, global->thread);
 
               fl_print_format("%c%[%SThe %s item action '%]", output->to.stream, f_string_eol_s[0], output->context, output->prefix ? output->prefix : f_string_empty_s, is_entry ? controller_string_entry_s : controller_string_exit_s, output->context);
               fl_print_format("%[%Q%]", output->to.stream, output->notable, cache->action.name_action, output->notable);
 
               if (entry_action->parameters.used) {
-                fl_print_format(" %[%S%]", output->to.stream, output->notable, entry_actions->array[cache->ats.array[at_j]], output->notable);
+                fl_print_format(" %[", output->to.stream, global->main->context.set.notable);
+
+                controller_entry_action_parameters_print(output->to.stream, *entry_action);
+
+                fl_print_format("%]", output->to.stream, global->main->context.set.notable);
               }
 
               fl_print_format(" %[is in a%] %[failed%]", output->to.stream, output->context, output->context, output->notable, output->notable);
@@ -885,9 +859,7 @@ extern "C" {
 
               controller_entry_error_print_cache(is_entry, *output, cache->action);
 
-              funlockfile(output->to.stream);
-
-              controller_print_unlock_flush(output->to.stream, &global->thread->lock.print);
+              controller_print_unlock_flush(output->to, global->thread);
             }
           }
 
@@ -898,17 +870,13 @@ extern "C" {
           if (entry_action->code & controller_entry_rule_code_wait) {
             if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose) {
               if (global->main->error.verbosity != f_console_verbosity_quiet) {
-                f_thread_mutex_lock(&global->thread->lock.print);
-
-                flockfile(global->main->output.stream);
+                controller_print_lock(global->main->output, global->thread);
 
                 fl_print_format("%cWaiting before processing %s item action '", global->main->output.stream, f_string_eol_s[0], is_entry ? controller_string_entry_s : controller_string_exit_s);
                 fl_print_format("%[%s%]", global->main->output.stream, global->main->context.set.title, controller_string_ready_s, global->main->context.set.title);
                 fl_print_format("'.%c", global->main->output.stream, f_string_eol_s[0]);
 
-                funlockfile(global->main->output.stream);
-
-                controller_print_unlock_flush(global->main->output.stream, &global->thread->lock.print);
+                controller_print_unlock_flush(global->main->output, global->thread);
               }
             }
 
@@ -920,17 +888,13 @@ extern "C" {
           if (global->setting->ready == controller_setting_ready_wait) {
             if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose) {
               if (global->main->error.verbosity != f_console_verbosity_quiet) {
-                f_thread_mutex_lock(&global->thread->lock.print);
-
-                flockfile(global->main->output.stream);
+                controller_print_lock(global->main->output, global->thread);
 
                 fl_print_format("%cWaiting before processing %s item action '", global->main->output.stream, f_string_eol_s[0], is_entry ? controller_string_entry_s : controller_string_exit_s);
                 fl_print_format("%[%s%]", global->main->output.stream, global->main->context.set.title, controller_string_ready_s, global->main->context.set.title);
                 fl_print_format("'.%c", global->main->output.stream, f_string_eol_s[0]);
 
-                funlockfile(global->main->output.stream);
-
-                controller_print_unlock_flush(global->main->output.stream, &global->thread->lock.print);
+                controller_print_unlock_flush(global->main->output, global->thread);
               }
             }
 
@@ -944,17 +908,13 @@ extern "C" {
           }
           else if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose) {
             if (global->main->error.verbosity != f_console_verbosity_quiet) {
-              f_thread_mutex_lock(&global->thread->lock.print);
-
-              flockfile(global->main->output.stream);
+              controller_print_lock(global->main->output, global->thread);
 
               fl_print_format("%cIgnoring %s item action '", global->main->output.stream, f_string_eol_s[0], is_entry ? controller_string_entry_s : controller_string_exit_s);
               fl_print_format("%[%s%]", global->main->output.stream, global->main->context.set.title, controller_string_ready_s, global->main->context.set.title);
               fl_print_format("', state already is ready.%c", global->main->output.stream, f_string_eol_s[0]);
 
-              funlockfile(global->main->output.stream);
-
-              controller_print_unlock_flush(global->main->output.stream, &global->thread->lock.print);
+              controller_print_unlock_flush(global->main->output, global->thread);
             }
           }
         }
@@ -963,9 +923,7 @@ extern "C" {
 
             // This should not happen if the pre-process is working as intended, but in case it doesn't, return a critical error to prevent infinite recursion and similar errors.
             if (global->main->error.verbosity != f_console_verbosity_quiet) {
-              f_thread_mutex_lock(&global->thread->lock.print);
-
-              flockfile(global->main->error.to.stream);
+              controller_print_lock(global->main->error.to, global->thread);
 
               fl_print_format("%c%[Invalid %s item index '%]", global->main->error.to.stream, f_string_eol_s[0], global->main->error.context, is_entry ? controller_string_entry_s : controller_string_exit_s, global->main->error.context);
               fl_print_format("%[%un%]", global->main->error.to.stream, global->main->error.notable, entry_action->number, global->main->error.notable);
@@ -973,9 +931,7 @@ extern "C" {
 
               controller_entry_error_print_cache(is_entry, global->main->error, cache->action);
 
-              funlockfile(global->main->error.to.stream);
-
-              controller_print_unlock_flush(global->main->error.to.stream, &global->thread->lock.print);
+              controller_print_unlock_flush(global->main->error.to, global->thread);
             }
 
             return F_status_is_error(F_critical);
@@ -1014,17 +970,13 @@ extern "C" {
 
           if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose) {
             if (global->main->error.verbosity != f_console_verbosity_quiet) {
-              f_thread_mutex_lock(&global->thread->lock.print);
-
-              flockfile(global->main->output.stream);
+              controller_print_lock(global->main->output, global->thread);
 
               fl_print_format("%cProcessing %s item '", global->main->output.stream, f_string_eol_s[0], is_entry ? controller_string_entry_s : controller_string_exit_s);
               fl_print_format("%[%Q%]", global->main->output.stream, global->main->context.set.title, cache->action.name_item, global->main->context.set.title);
               fl_print_format("'.%c", global->main->output.stream, f_string_eol_s[0]);
 
-              funlockfile(global->main->output.stream);
-
-              controller_print_unlock_flush(global->main->output.stream, &global->thread->lock.print);
+              controller_print_unlock_flush(global->main->output, global->thread);
             }
           }
 
@@ -1074,17 +1026,13 @@ extern "C" {
 
           if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose) {
             if (global->main->error.verbosity != f_console_verbosity_quiet) {
-              f_thread_mutex_lock(&global->thread->lock.print);
-
-              flockfile(global->main->output.stream);
+              controller_print_lock(global->main->output, global->thread);
 
               fl_print_format("%c%s %s item rule '", global->main->output.stream, f_string_eol_s[0], entry_action->type == controller_entry_action_type_consider ? "Considering" : "Processing", is_entry ? controller_string_entry_s : controller_string_exit_s);
               fl_print_format("%[%Q%]", global->main->output.stream, global->main->context.set.title, alias_rule, global->main->context.set.title);
               fl_print_format("'.%c", global->main->output.stream, f_string_eol_s[0]);
 
-              funlockfile(global->main->output.stream);
-
-              controller_print_unlock_flush(global->main->output.stream, &global->thread->lock.print);
+              controller_print_unlock_flush(global->main->output, global->thread);
             }
           }
 
@@ -1146,11 +1094,11 @@ extern "C" {
             if (F_status_is_error(status)) {
 
               if (global->main->error.verbosity != f_console_verbosity_quiet) {
-                f_thread_mutex_lock(&global->thread->lock.print);
+                controller_print_lock(global->main->output, global->thread);
 
                 controller_entry_error_print_cache(is_entry, global->main->error, cache->action);
 
-                controller_print_unlock_flush(global->main->output.stream, &global->thread->lock.print);
+                controller_print_unlock_flush(global->main->output, global->thread);
               }
 
               if (global->main->parameters[controller_parameter_simulate].result == f_console_result_none) {
@@ -1208,9 +1156,7 @@ extern "C" {
         else if (entry_action->type == controller_entry_action_type_execute) {
           if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose) {
             if (global->main->error.verbosity != f_console_verbosity_quiet) {
-              f_thread_mutex_lock(&global->thread->lock.print);
-
-              flockfile(global->main->output.stream);
+              controller_print_lock(global->main->output, global->thread);
 
               fl_print_format("%c%s is executing '", global->main->output.stream, f_string_eol_s[0], is_entry ? controller_string_entry_s : controller_string_exit_s);
 
@@ -1225,9 +1171,7 @@ extern "C" {
 
               fl_print_format("'.%c", global->main->output.stream, f_string_eol_s[0]);
 
-              funlockfile(global->main->output.stream);
-
-              controller_print_unlock_flush(global->main->output.stream, &global->thread->lock.print);
+              controller_print_unlock_flush(global->main->output, global->thread);
             }
           }
 
@@ -1244,9 +1188,7 @@ extern "C" {
           if (F_status_is_error(status)) {
             if (F_status_set_fine(status) == F_file_found_not) {
               if (global->main->error.verbosity != f_console_verbosity_quiet) {
-                f_thread_mutex_lock(&global->thread->lock.print);
-
-                flockfile(global->main->error.to.stream);
+                controller_print_lock(global->main->error.to, global->thread);
 
                 fl_print_format("%c%[%SExecution failed, unable to find program or script '%]", global->main->error.to.stream, f_string_eol_s[0], global->main->error.context, global->main->error.prefix ? global->main->error.prefix : f_string_empty_s, global->main->error.context);
                 fl_print_format("%[%Q%]", global->main->error.to.stream, global->main->error.notable, entry_action->parameters.array[0], global->main->error.notable);
@@ -1254,9 +1196,7 @@ extern "C" {
 
                 controller_entry_error_print_cache(is_entry, global->main->error, cache->action);
 
-                funlockfile(global->main->error.to.stream);
-
-                controller_print_unlock_flush(global->main->error.to.stream, &global->thread->lock.print);
+                controller_print_unlock_flush(global->main->error.to, global->thread);
               }
             }
             else {
@@ -1267,9 +1207,7 @@ extern "C" {
           }
           else if (result != 0) {
             if (global->main->error.verbosity != f_console_verbosity_quiet) {
-              f_thread_mutex_lock(&global->thread->lock.print);
-
-              flockfile(global->main->error.to.stream);
+              controller_print_lock(global->main->error.to, global->thread);
 
               fl_print_format("%c%[%SExecution failed with return value of '%]", global->main->error.to.stream, f_string_eol_s[0], global->main->error.context, global->main->error.prefix ? global->main->error.prefix : f_string_empty_s, global->main->error.context);
               fl_print_format("%[%i%]", global->main->error.to.stream, global->main->error.notable, result, global->main->error.notable);
@@ -1277,9 +1215,7 @@ extern "C" {
 
               controller_entry_error_print_cache(is_entry, global->main->error, cache->action);
 
-              funlockfile(global->main->error.to.stream);
-
-              controller_print_unlock_flush(global->main->error.to.stream, &global->thread->lock.print);
+              controller_print_unlock_flush(global->main->error.to, global->thread);
             }
 
             return F_status_set_error(F_execute);
@@ -1303,18 +1239,14 @@ extern "C" {
             }
 
             if (global->main->error.verbosity != f_console_verbosity_quiet) {
-              f_thread_mutex_lock(&global->thread->lock.print);
-
-              flockfile(global->main->output.stream);
+              controller_print_lock(global->main->output, global->thread);
 
               fl_print_format("%cProcessing %s item action '", global->main->output.stream, f_string_eol_s[0], is_entry ? controller_string_entry_s : controller_string_exit_s);
               fl_print_format("%[%s%]' setting '", global->main->output.stream, global->main->context.set.title, controller_string_timeout_s, global->main->context.set.title);
               fl_print_format("%[%S%]' to '", global->main->output.stream, global->main->context.set.important, code, global->main->context.set.important);
               fl_print_format("%[%un%]' MegaTime (milliseconds).%c", global->main->output.stream, global->main->context.set.important, entry_action->number, global->main->context.set.important, f_string_eol_s[0]);
 
-              funlockfile(global->main->output.stream);
-
-              controller_print_unlock_flush(global->main->output.stream, &global->thread->lock.print);
+              controller_print_unlock_flush(global->main->output, global->thread);
             }
           }
 
@@ -1332,17 +1264,13 @@ extern "C" {
 
           if (failsafe) {
             if (global->main->warning.verbosity == f_console_verbosity_debug) {
-              f_thread_mutex_lock(&global->thread->lock.print);
-
-              flockfile(global->main->error.to.stream);
+              controller_print_lock(global->main->warning.to, global->thread);
 
               fl_print_format("%c%[%SFailsafe may not be specified when running in failsafe, ignoring.%]%c", global->main->warning.to.stream, f_string_eol_s[0], global->main->warning.context, global->main->warning.prefix ? global->main->warning.prefix : f_string_empty_s, global->main->warning.context, f_string_eol_s[0]);
 
               controller_entry_error_print_cache(is_entry, global->main->warning, cache->action);
 
-              funlockfile(global->main->warning.to.stream);
-
-              controller_print_unlock_flush(global->main->warning.to.stream, &global->thread->lock.print);
+              controller_print_unlock_flush(global->main->warning.to, global->thread);
             }
           }
           else {
@@ -1350,9 +1278,7 @@ extern "C" {
 
               // This should not happen if the pre-process is working as designed, but in case it doesn't, return a critical error to prevent infinite recursion and similar errors.
               if (global->main->error.verbosity != f_console_verbosity_quiet) {
-                f_thread_mutex_lock(&global->thread->lock.print);
-
-                flockfile(global->main->error.to.stream);
+                controller_print_lock(global->main->error.to, global->thread);
 
                 fl_print_format("%c%[%SInvalid %s item index '%]", global->main->error.to.stream, f_string_eol_s[0], global->main->error.context, global->main->error.prefix ? global->main->error.prefix : f_string_empty_s, is_entry ? controller_string_entry_s : controller_string_exit_s, global->main->error.context);
                 fl_print_format("%[%un%]", global->main->error.to.stream, global->main->error.notable, entry_action->number, global->main->error.notable);
@@ -1360,9 +1286,7 @@ extern "C" {
 
                 controller_entry_error_print_cache(is_entry, global->main->error, cache->action);
 
-                funlockfile(global->main->error.to.stream);
-
-                controller_print_unlock_flush(global->main->error.to.stream, &global->thread->lock.print);
+                controller_print_unlock_flush(global->main->error.to, global->thread);
               }
 
               return F_status_is_error(F_critical);
@@ -1373,18 +1297,14 @@ extern "C" {
 
               if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose) {
                 if (global->main->error.verbosity != f_console_verbosity_quiet) {
-                  f_thread_mutex_lock(&global->thread->lock.print);
-
-                  flockfile(global->main->output.stream);
+                  controller_print_lock(global->main->output, global->thread);
 
                   fl_print_format("%cProcessing %s item action '", global->main->output.stream, f_string_eol_s[0], is_entry ? controller_string_entry_s : controller_string_exit_s);
                   fl_print_format("%[%s%]' setting value to '", global->main->output.stream, global->main->context.set.title, controller_string_failsafe_s, global->main->context.set.title);
                   fl_print_format("%[%Q%]", global->main->output.stream, global->main->context.set.important, entry->items.array[global->setting->failsafe_item_id].name, global->main->context.set.important);
                   fl_print_format("'.%c", global->main->output.stream, f_string_eol_s[0]);
 
-                  funlockfile(global->main->output.stream);
-
-                  controller_print_unlock_flush(global->main->output.stream, &global->thread->lock.print);
+                  controller_print_unlock_flush(global->main->output, global->thread);
                 }
               }
             }
@@ -1454,9 +1374,7 @@ extern "C" {
     }
 
     if ((global->main->parameters[controller_parameter_simulate].result == f_console_result_found && global->main->error.verbosity != f_console_verbosity_quiet) || global->main->error.verbosity == f_console_verbosity_verbose) {
-      f_thread_mutex_lock(&global->thread->lock.print);
-
-      flockfile(global->main->output.stream);
+      controller_print_lock(global->main->output, global->thread);
 
       fl_print_format("%cDone processing %s item '", global->main->output.stream, f_string_eol_s[0], is_entry ? controller_string_entry_s : controller_string_exit_s);
       fl_print_format("%[%s%]", global->main->output.stream, global->main->context.set.title, controller_string_main_s, global->main->context.set.title);
@@ -1467,9 +1385,7 @@ extern "C" {
         f_print_terminated(f_string_eol_s, global->main->output.stream);
       }
 
-      funlockfile(global->main->output.stream);
-
-      controller_print_unlock_flush(global->main->output.stream, &global->thread->lock.print);
+      controller_print_unlock_flush(global->main->output, global->thread);
     }
 
     return status;
index 3395785547c2ca1c28a548b0244a9aba477f079e..c64ef657329eac390cd0f99b3dc98a059adb2b74 100644 (file)
@@ -11,9 +11,7 @@ extern "C" {
 #ifndef _di_controller_entry_action_parameters_print_
   void controller_entry_action_parameters_print(FILE * const stream, const controller_entry_action_t action) {
 
-    f_array_length_t index = 0;
-
-    for (;;) {
+    for (f_array_length_t index = 0; ;) {
 
       f_print_dynamic_safely(action.parameters.array[index], stream);
 
@@ -329,15 +327,15 @@ extern "C" {
       }
       else {
         if (global.main->warning.verbosity == f_console_verbosity_debug) {
-          flockfile(global.main->warning.to.stream);
+          controller_print_lock(global.main->warning.to, global.thread);
 
           fl_print_format("%c%[%SUnknown %s item action '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, is_entry ? controller_string_entry_s : controller_string_exit_s, global.main->warning.context);
-          fl_print_format("%[%S%]'", global.main->warning.to.stream, global.main->warning.notable, cache->action.name_action, global.main->warning.notable);
+          fl_print_format("%[%S%]", global.main->warning.to.stream, global.main->warning.notable, cache->action.name_action, global.main->warning.notable);
           fl_print_format("%['.%]%c", global.main->warning.to.stream, global.main->warning.context, global.main->warning.context, f_string_eol_s[0]);
 
           controller_entry_error_print_cache(is_entry, global.main->warning, cache->action);
 
-          funlockfile(global.main->warning.to.stream);
+          controller_print_unlock_flush(global.main->warning.to, global.thread);
         }
 
         continue;
@@ -373,6 +371,8 @@ extern "C" {
         action->status = F_status_set_error(F_parameter);
 
         if (global.main->error.verbosity != f_console_verbosity_quiet) {
+          f_thread_mutex_lock(&global.thread->lock.print);
+
           flockfile(global.main->error.to.stream);
 
           fl_print_format("%c%[%SThe %s item action '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_string_entry_s : controller_string_exit_s, global.main->error.context);
@@ -400,6 +400,8 @@ extern "C" {
           }
 
           funlockfile(global.main->error.to.stream);
+
+          f_thread_mutex_unlock(&global.thread->lock.print);
         }
       }
       else {
@@ -718,12 +720,17 @@ extern "C" {
   void controller_entry_error_print(const bool is_entry, const fll_error_print_t print, const controller_cache_action_t cache, const f_status_t status, const f_string_t function, const bool fallback, controller_thread_t *thread) {
 
     if (print.verbosity != f_console_verbosity_quiet) {
+
+      // fll_error_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_print_lock().
       f_thread_mutex_lock(&thread->lock.print);
 
       fll_error_print(print, status, function, fallback);
+
+      flockfile(print.to.stream);
+
       controller_entry_error_print_cache(is_entry, print, cache);
 
-      controller_print_unlock_flush(print.to.stream, &thread->lock.print);
+      controller_print_unlock_flush(print.to, thread);
     }
   }
 #endif // _di_controller_entry_error_print_
@@ -856,11 +863,11 @@ extern "C" {
       }
       else {
         if (global.main->error.verbosity != f_console_verbosity_quiet) {
-          f_thread_mutex_lock(&global.thread->lock.print);
+          controller_print_lock(global.main->error.to, global.thread);
 
           fll_print_format("%c%[%SThe %s file is empty.%]%c", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_string_entry_s : is_entry ? controller_string_entry_s : controller_string_exit_s, global.main->error.context, f_string_eol_s[0]);
 
-          controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+          controller_print_unlock_flush(global.main->error.to, global.thread);
         }
 
         status = F_status_set_error(F_data_not);
@@ -936,9 +943,7 @@ extern "C" {
 
             if (fl_string_dynamic_compare(entry->items.array[j].name, cache->action.name_item) == F_equal_to) {
               if (global.main->warning.verbosity == f_console_verbosity_debug) {
-                f_thread_mutex_lock(&global.thread->lock.print);
-
-                flockfile(global.main->warning.to.stream);
+                controller_print_lock(global.main->warning.to, global.thread);
 
                 fl_print_format("%c%[%SIgnoring duplicate %s item '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, is_entry ? controller_string_entry_s : controller_string_exit_s, global.main->warning.context);
                 fl_print_format("%[%Q%]", global.main->warning.to.stream, global.main->warning.notable, cache->action.name_file, global.main->warning.notable);
@@ -946,9 +951,7 @@ extern "C" {
 
                 controller_entry_error_print_cache(is_entry, global.main->warning, cache->action);
 
-                funlockfile(global.main->warning.to.stream);
-
-                controller_print_unlock_flush(global.main->warning.to.stream, &global.thread->lock.print);
+                controller_print_unlock_flush(global.main->warning.to, global.thread);
               }
 
               code |= 0x2;
@@ -999,11 +1002,11 @@ extern "C" {
           status = controller_entry_actions_read(is_entry, *range, global, cache, &entry->items.array[at].actions);
 
           if (F_status_is_error(status)) {
-            f_thread_mutex_lock(&global.thread->lock.print);
+            controller_print_lock(global.main->error.to, global.thread);
 
             controller_entry_error_print_cache(is_entry, global.main->error, cache->action);
 
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
 
             if (F_status_set_fine(status) == F_memory_not) {
               break;
@@ -1021,17 +1024,13 @@ extern "C" {
 
           if (!(code & 0x1)) {
             if (global.main->error.verbosity != f_console_verbosity_quiet) {
-              f_thread_mutex_lock(&global.thread->lock.print);
-
-              flockfile(global.main->error.to.stream);
+              controller_print_lock(global.main->error.to, global.thread);
 
               fl_print_format("%c%[%SThe required %s item '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_string_entry_s : controller_string_exit_s, global.main->error.context);
               fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_string_main_s, global.main->error.notable);
               fl_print_format("%[' was not found.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]);
 
-              funlockfile(global.main->error.to.stream);
-
-              controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+              controller_print_unlock_flush(global.main->error.to, global.thread);
             }
 
             status = F_status_set_error(F_found_not);
@@ -1086,9 +1085,7 @@ extern "C" {
                     }
 
                     if (global.main->error.verbosity != f_console_verbosity_quiet) {
-                      f_thread_mutex_lock(&global.thread->lock.print);
-
-                      flockfile(global.main->error.to.stream);
+                      controller_print_lock(global.main->error.to, global.thread);
 
                       fl_print_format("%c%[%SThe required %s item '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_string_entry_s : controller_string_exit_s, global.main->error.context);
                       fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, action->parameters.array[0], global.main->error.notable);
@@ -1096,9 +1093,7 @@ extern "C" {
 
                       controller_entry_error_print_cache(is_entry, global.main->error, cache->action);
 
-                      funlockfile(global.main->error.to.stream);
-
-                      controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                      controller_print_unlock_flush(global.main->error.to, global.thread);
                     }
 
                     action->number = 0;
@@ -1184,7 +1179,7 @@ extern "C" {
       if (is_entry && fl_string_dynamic_compare_string(controller_string_mode_s, cache->action.name_action, controller_string_mode_length) == F_equal_to) {
         if (cache->content_actions.array[i].used < 0 || cache->content_actions.array[i].used > 1) {
           if (global.main->error.verbosity != f_console_verbosity_quiet) {
-            flockfile(global.main->error.to.stream);
+            controller_print_lock(global.main->error.to, global.thread);
 
             fl_print_format("%c%[%SThe %s item setting '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_string_entry_s : controller_string_exit_s, global.main->error.context);
             fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, cache->action.name_action, global.main->error.notable);
@@ -1192,7 +1187,7 @@ extern "C" {
             fl_print_format("%[1%]", global.main->error.to.stream, global.main->error.notable, global.main->error.notable);
             fl_print_format("%[' parameter.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]);
 
-            funlockfile(global.main->error.to.stream);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
           }
 
           continue;
@@ -1206,15 +1201,15 @@ extern "C" {
         }
         else {
           if (global.main->warning.verbosity == f_console_verbosity_debug) {
-            flockfile(global.main->warning.to.stream);
+            controller_print_lock(global.main->warning.to, global.thread);
 
             fl_print_format("%c%[%Sfor %s item setting '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, is_entry ? controller_string_entry_s : controller_string_exit_s, global.main->warning.context);
             fl_print_format("%[%Q%]", global.main->warning.to.stream, global.main->warning.notable, cache->action.name_action, global.main->warning.notable);
             fl_print_format("%['.%]%c", global.main->warning.to.stream, global.main->warning.context, global.main->warning.context, f_string_eol_s[0]);
 
-            funlockfile(global.main->warning.to.stream);
-
             controller_entry_error_print_cache(is_entry, global.main->warning, cache->action);
+
+            controller_print_unlock_flush(global.main->warning.to, global.thread);
           }
 
           continue;
@@ -1222,15 +1217,15 @@ extern "C" {
       }
       else {
         if (global.main->warning.verbosity == f_console_verbosity_debug) {
-          flockfile(global.main->warning.to.stream);
+          controller_print_lock(global.main->warning.to, global.thread);
 
           fl_print_format("%c%[%SUnknown %s item setting '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, is_entry ? controller_string_entry_s : controller_string_exit_s, global.main->warning.context);
           fl_print_format("%[%Q%]", global.main->warning.to.stream, global.main->warning.notable, cache->action.name_action, global.main->warning.notable);
           fl_print_format("%['.%]%c", global.main->warning.to.stream, global.main->warning.context, global.main->warning.context, f_string_eol_s[0]);
 
-          funlockfile(global.main->warning.to.stream);
-
           controller_entry_error_print_cache(is_entry, global.main->warning, cache->action);
+
+          controller_print_unlock_flush(global.main->warning.to, global.thread);
         }
 
         continue;
index 5a0d533c866daf5e84fc56a9aa24c2f2a57a96e0..e9090bc7c62983fec25eec000068863082a54812 100644 (file)
@@ -272,7 +272,6 @@ extern "C" {
               controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, global.thread);
             }
             else {
-
               actions->array[actions->used].type = type;
               actions->array[actions->used].line = cache->action.line_action;
               actions->array[actions->used].parameters.used = 0;
@@ -290,8 +289,7 @@ extern "C" {
                 controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
               }
               else {
-                actions->array[actions->used].parameters.used = 1;
-                ++actions->used;
+                actions->array[actions->used++].parameters.used = 1;
               }
             }
 
@@ -302,6 +300,8 @@ extern "C" {
             controller_state_interrupt_t custom = macro_controller_state_interrupt_t_initialize(is_normal, global.thread);
             f_state_t state = macro_f_state_t_initialize(controller_common_allocation_large, controller_common_allocation_small, 0, &controller_thread_signal_state_fss, 0, (void *) &custom, 0);
 
+            cache->delimits.used = 0;
+
             // the object_actions and content_actions caches are being used for the purposes of getting the parameters a given the action.
             status = fll_fss_extended_read(cache->buffer_item, state, &cache->content_action.array[0], &cache->object_actions, &cache->content_actions, 0, 0, &cache->delimits, 0);
           }
@@ -310,14 +310,12 @@ extern "C" {
             controller_error_print(global.main->error, F_status_set_fine(status), "fll_fss_extended_read", F_true, global.thread);
           }
           else {
-
             status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_item);
 
             if (F_status_is_error(status)) {
               controller_error_print(global.main->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread);
             }
             else {
-
               f_array_length_t i = 0;
               f_array_length_t j = 0;
 
@@ -435,13 +433,11 @@ extern "C" {
             if (F_status_is_error(status)) {
               controller_error_print(global.main->error, F_status_set_fine(status), "controller_rule_parameters_read", F_true, global.thread);
 
-              actions->array[actions->used].status = controller_status_simplify_error(F_status_set_fine(status));
+              actions->array[actions->used++].status = controller_status_simplify_error(F_status_set_fine(status));
             }
             else {
-              actions->array[actions->used].status = status;
+              actions->array[actions->used++].status = status;
             }
-
-            ++actions->used;
           }
         }
       }
@@ -452,17 +448,13 @@ extern "C" {
 
     if (F_status_is_error_not(status) && status == F_data_not) {
       if (global.main->warning.verbosity == f_console_verbosity_debug) {
-        f_thread_mutex_lock(&global.thread->lock.print);
-
-        flockfile(global.main->warning.to.stream);
+        controller_print_lock(global.main->warning.to, global.thread);
 
         fl_print_format("%c%[%SAction is empty, nothing to do.%]%c", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, global.main->warning.context, f_string_eol_s[0]);
 
         controller_rule_error_print_cache(global.main->warning, cache->action, F_true);
 
-        funlockfile(global.main->warning.to.stream);
-
-        controller_print_unlock_flush(global.main->warning.to.stream, &global.thread->lock.print);
+        controller_print_unlock_flush(global.main->warning.to, global.thread);
       }
     }
 
@@ -671,6 +663,8 @@ extern "C" {
   void controller_rule_error_print(const fll_error_print_t print, const controller_cache_action_t cache, const f_status_t status, const f_string_t function, const bool fallback, const bool item, controller_thread_t *thread) {
 
     if (print.verbosity != f_console_verbosity_quiet) {
+
+      // fll_error_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_print_lock().
       f_thread_mutex_lock(&thread->lock.print);
 
       fll_error_print(print, status, function, fallback);
@@ -679,9 +673,7 @@ extern "C" {
 
       controller_rule_error_print_cache(print, cache, item);
 
-      funlockfile(print.to.stream);
-
-      controller_print_unlock_flush(print.to.stream, &thread->lock.print);
+      controller_print_unlock_flush(print.to, thread);
     }
   }
 #endif // _di_controller_rule_error_print_
@@ -718,23 +710,27 @@ extern "C" {
 #endif // _di_controller_rule_error_print_cache_
 
 #ifndef _di_controller_rule_item_error_print_
-  void controller_rule_item_error_print(const fll_error_print_t output, const controller_cache_action_t cache, const bool item, controller_thread_t *thread) {
+  void controller_rule_item_error_print(const fll_error_print_t print, const controller_cache_action_t cache, const bool item, controller_thread_t *thread) {
 
-    if (output.verbosity != f_console_verbosity_quiet) {
+    if (print.verbosity != f_console_verbosity_quiet) {
+
+      // fll_error_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_print_lock().
       f_thread_mutex_lock(&thread->lock.print);
 
-      controller_rule_error_print_cache(output, cache, item);
+      controller_rule_error_print_cache(print, cache, item);
+
+      flockfile(print.to.stream);
 
-      controller_print_unlock_flush(output.to.stream, &thread->lock.print);
+      controller_print_unlock_flush(print.to, thread);
     }
   }
 #endif // _di_controller_rule_item_error_print_
 
 #ifndef _di_controller_rule_item_error_print_execute_
-  void controller_rule_item_error_print_execute(const fll_error_print_t output, const bool script_is, const f_string_t name, const int code, const f_status_t status) {
+  void controller_rule_item_error_print_execute(const fll_error_print_t output, const bool script_is, const f_string_t name, const int code, const f_status_t status, controller_thread_t * const thread) {
 
     if (output.verbosity != f_console_verbosity_quiet) {
-      flockfile(output.to.stream);
+      controller_print_lock(output.to, thread);
 
       fl_print_format("%c%[%SThe %s '%]", output.to.stream, f_string_eol_s[0], output.context, output.prefix, script_is ? controller_string_script_s : controller_string_program_s, output.context);
       fl_print_format("%[%S%]", output.to.stream, output.notable, name, output.notable);
@@ -768,7 +764,7 @@ extern "C" {
         fl_print_format("%[' failed.%]%c", output.to.stream, output.context, output.context, f_string_eol_s[0]);
       }
 
-      funlockfile(output.to.stream);
+      controller_print_unlock_flush(output.to, thread);
     }
   }
 #endif // _di_controller_rule_item_error_print_execute_
@@ -777,13 +773,9 @@ extern "C" {
   void controller_rule_item_error_print_execute_not_found(const fll_error_print_t output, const bool script_is, const f_string_t name) {
 
     if (output.verbosity != f_console_verbosity_quiet) {
-      flockfile(output.to.stream);
-
       fl_print_format("%c%[%SThe %s '%]", output.to.stream, f_string_eol_s[0], output.context, output.prefix, script_is ? controller_string_script_s : controller_string_program_s, output.context);
       fl_print_format("%[%S%]", output.to.stream, output.notable, name, output.notable);
       fl_print_format("%[' could not be executed because it was not found.%]%c", output.to.stream, output.context, output.context, f_string_eol_s[0]);
-
-      funlockfile(output.to.stream);
     }
   }
 #endif // _di_controller_rule_item_error_print_execute_not_found_
@@ -792,13 +784,9 @@ extern "C" {
   void controller_rule_item_error_print_need_want_wish(const fll_error_print_t output, const f_string_t need_want_wish, const f_string_t value, const f_string_t why) {
 
     if (output.verbosity != f_console_verbosity_quiet) {
-      flockfile(output.to.stream);
-
       fl_print_format("%c%[%SThe %s rule '%]", output.to.stream, f_string_eol_s[0], output.context, output.prefix, need_want_wish, output.context);
       fl_print_format("%[%S%]", output.to.stream, output.notable, value, output.notable);
       fl_print_format("%[' %S.%]%c", output.to.stream, output.context, why, output.context, f_string_eol_s[0]);
-
-      funlockfile(output.to.stream);
     }
   }
 #endif // _di_controller_rule_item_error_print_need_want_wish_
@@ -807,13 +795,9 @@ extern "C" {
   void controller_rule_item_error_print_rule_not_loaded(const fll_error_print_t output, const f_string_t alias) {
 
     if (output.verbosity != f_console_verbosity_quiet) {
-      flockfile(output.to.stream);
-
       fl_print_format("%c%[%SThe rule '%]", output.to.stream, f_string_eol_s[0], output.context, output.prefix, output.context);
       fl_print_format("%[%S%]", output.to.stream, output.notable, alias, output.notable);
       fl_print_format("%[' is no longer loaded.%]%c", output.to.stream, output.context, output.context, f_string_eol_s[0]);
-
-      funlockfile(output.to.stream);
     }
   }
 #endif // _di_controller_rule_item_error_print_rule_not_loaded_
@@ -822,13 +806,9 @@ extern "C" {
   void controller_rule_action_error_missing_pid(const fll_error_print_t output, const f_string_t alias) {
 
     if (output.verbosity != f_console_verbosity_quiet) {
-      flockfile(output.to.stream);
-
       fl_print_format("%c%[%SThe rule '%]", output.to.stream, f_string_eol_s[0], output.context, output.prefix, output.context);
       fl_print_format("%[%S%]", output.to.stream, output.notable, alias, output.notable);
       fl_print_format("%[' is not designating a pid file.%]%c", output.to.stream, output.context, output.context, f_string_eol_s[0]);
-
-      funlockfile(output.to.stream);
     }
   }
 #endif // _di_controller_rule_action_error_missing_pid_
@@ -1064,17 +1044,13 @@ extern "C" {
         }
         else {
           if (global.main->warning.verbosity == f_console_verbosity_debug) {
-            f_thread_mutex_lock(&global.thread->lock.print);
-
-            flockfile(global.main->warning.to.stream);
+            controller_print_lock(global.main->warning.to, global.thread);
 
             fl_print_format("%c%[%SAction type is unknown, ignoring.%]%c", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, global.main->warning.context, f_string_eol_s[0]);
 
             controller_rule_error_print_cache(global.main->warning, process->cache.action, F_true);
 
-            funlockfile(global.main->warning.to.stream);
-
-            controller_print_unlock_flush(global.main->warning.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->warning.to, global.thread);
           }
 
           if (success == F_false) {
@@ -1135,7 +1111,7 @@ extern "C" {
     status = controller_pids_increase(&process->childs);
 
     if (F_status_is_error(status)) {
-      fll_error_print(global.main->error, F_status_set_fine(status), "controller_pids_increase", F_true);
+      controller_error_print(global.main->error, F_status_set_fine(status), "controller_pids_increase", F_true, global.thread);
 
       return status;
     }
@@ -1159,9 +1135,7 @@ extern "C" {
 
     if (options & controller_process_option_simulate) {
       if (global.main->error.verbosity != f_console_verbosity_quiet) {
-        f_thread_mutex_lock(&global.thread->lock.print);
-
-        flockfile(global.main->output.stream);
+        controller_print_lock(global.main->output, global.thread);
 
         fl_print_format("%cSimulating execution of '%[", global.main->output.stream, f_string_eol_s[0], global.main->context.set.title);
 
@@ -1186,9 +1160,7 @@ extern "C" {
         fl_print_format("%]' from '", global.main->output.stream, global.main->context.set.important);
         fl_print_format("%[%Q%]'.%c", global.main->output.stream, global.main->context.set.notable, process->rule.name, global.main->context.set.notable, f_string_eol_s[0]);
 
-        funlockfile(global.main->output.stream);
-
-        controller_print_unlock_flush(global.main->output.stream, &global.thread->lock.print);
+        controller_print_unlock_flush(global.main->output, global.thread);
       }
 
       // sleep for less than a second to better show simulation of synchronous vs asynchronous.
@@ -1319,20 +1291,20 @@ extern "C" {
     if (F_status_is_error(status)) {
       status = F_status_set_fine(status);
 
-      f_thread_mutex_lock(&global.thread->lock.print);
-
       if (status == F_control_group || status == F_failure || status == F_limit || status == F_processor || status == F_schedule) {
-        controller_rule_item_error_print_execute(global.main->error, type == controller_rule_item_type_script, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, result, status);
+        controller_rule_item_error_print_execute(global.main->error, type == controller_rule_item_type_script, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, result, status, global.thread);
       }
       else if (status == F_file_found_not) {
+        controller_print_lock(global.main->error.to, global.thread);
+
         controller_rule_item_error_print_execute_not_found(global.main->error, F_false, program);
+
+        controller_print_unlock_flush(global.main->error.to, global.thread);
       }
       else {
         controller_error_print(global.main->error, F_status_set_fine(status), "fll_execute_program", F_true, global.thread);
       }
 
-      controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
-
       status = F_status_set_error(status);
     }
 
@@ -1352,7 +1324,7 @@ extern "C" {
     status = controller_pids_increase(&process->childs);
 
     if (F_status_is_error(status)) {
-      fll_error_print(global.main->error, F_status_set_fine(status), "controller_pids_increase", F_true);
+      controller_error_print(global.main->error, F_status_set_fine(status), "controller_pids_increase", F_true, global.thread);
 
       return status;
     }
@@ -1360,7 +1332,7 @@ extern "C" {
     status = f_string_dynamics_increase(controller_common_allocation_small, &process->path_pids);
 
     if (F_status_is_error(status)) {
-      fll_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true);
+      controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, global.thread);
 
       return status;
     }
@@ -1395,13 +1367,13 @@ extern "C" {
     status = f_file_exists(pid_file.string);
 
     if (F_status_is_error(status)) {
-      fll_error_file_print(global.main->error, F_status_set_fine(status), "f_file_exists", F_true, pid_file.string, "find", fll_error_file_type_file);
+      controller_error_file_print(global.main->error, F_status_set_fine(status), "f_file_exists", F_true, pid_file.string, "find", fll_error_file_type_file, global.thread);
 
       return status;
     }
 
     if (status == F_true) {
-      fll_error_file_print(global.main->error, F_file_found, "f_file_exists", F_true, pid_file.string, "find", fll_error_file_type_file);
+      controller_error_file_print(global.main->error, F_file_found, "f_file_exists", F_true, pid_file.string, "find", fll_error_file_type_file, global.thread);
 
       return F_status_set_error(F_file_found);
     }
@@ -1409,16 +1381,14 @@ extern "C" {
     status = controller_string_dynamic_append_terminated(pid_file, child_pid_file);
 
     if (F_status_is_error(status)) {
-      fll_error_print(global.main->error, F_status_set_fine(status), "controller_string_dynamic_append_terminated", F_true);
+      controller_error_print(global.main->error, F_status_set_fine(status), "controller_string_dynamic_append_terminated", F_true, global.thread);
 
       return status;
     }
 
     if (options & controller_process_option_simulate) {
       if (global.main->error.verbosity != f_console_verbosity_quiet) {
-        f_thread_mutex_lock(&global.thread->lock.print);
-
-        flockfile(global.main->error.to.stream);
+        controller_print_lock(global.main->error.to, global.thread);
 
         fl_print_format("%cSimulating execution of '%[", global.main->error.to.stream, f_string_eol_s[0], global.main->context.set.title);
 
@@ -1443,9 +1413,7 @@ extern "C" {
         fl_print_format("%]' from '", global.main->error.to.stream, global.main->context.set.important);
         fl_print_format("%[%Q%]'.%c", global.main->error.to.stream, global.main->context.set.notable, process->rule.name, global.main->context.set.notable, f_string_eol_s[0]);
 
-        funlockfile(global.main->error.to.stream);
-
-        controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+        controller_print_unlock_flush(global.main->error.to, global.thread);
       }
 
       // sleep for less than a second to better show simulation of synchronous vs asynchronous.
@@ -1577,20 +1545,20 @@ extern "C" {
     if (F_status_is_error(status)) {
       status = F_status_set_fine(status);
 
-      f_thread_mutex_lock(&global.thread->lock.print);
-
       if (status == F_control_group || status == F_failure || status == F_limit || status == F_processor || status == F_schedule) {
-        controller_rule_item_error_print_execute(global.main->error, type == controller_rule_item_type_utility, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, result, status);
+        controller_rule_item_error_print_execute(global.main->error, type == controller_rule_item_type_utility, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, result, status, global.thread);
       }
       else if (status == F_file_found_not) {
+        controller_print_lock(global.main->error.to, global.thread);
+
         controller_rule_item_error_print_execute_not_found(global.main->error, F_false, program);
+
+        controller_print_unlock_flush(global.main->error.to, global.thread);
       }
       else {
         controller_error_print(global.main->error, F_status_set_fine(status), "fll_execute_program", F_true, global.thread);
       }
 
-      controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
-
       return F_status_set_error(status);
     }
 
@@ -1757,9 +1725,7 @@ extern "C" {
       }
       else {
         if (global.main->warning.verbosity == f_console_verbosity_debug) {
-          f_thread_mutex_lock(&global.thread->lock.print);
-
-          flockfile(global.main->warning.to.stream);
+          controller_print_lock(global.main->warning.to, global.thread);
 
           fl_print_format("%c%[%SUnknown rule item action '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, global.main->warning.context);
           fl_print_format("%[%Q%]", global.main->warning.to.stream, global.main->warning.notable, cache->action.name_action, global.main->warning.notable);
@@ -1767,9 +1733,7 @@ extern "C" {
 
           controller_rule_error_print_cache(global.main->warning, cache->action, F_true);
 
-          funlockfile(global.main->warning.to.stream);
-
-          controller_print_unlock_flush(global.main->warning.to.stream, &global.thread->lock.print);
+          controller_print_unlock_flush(global.main->warning.to, global.thread);
         }
 
         continue;
@@ -1779,17 +1743,13 @@ extern "C" {
         if (type == controller_rule_action_type_group || type == controller_rule_action_type_pid_file || type == controller_rule_action_type_user) {
 
           if (global.main->error.verbosity != f_console_verbosity_quiet) {
-            f_thread_mutex_lock(&global.thread->lock.print);
-
-            flockfile(global.main->error.to.stream);
+            controller_print_lock(global.main->error.to, global.thread);
 
             fl_print_format("%c%[%SFSS Extended List is not allowed for the rule item action '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
             fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, cache->action.name_action, global.main->error.notable);
             fl_print_format("%['.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]);
 
-            funlockfile(global.main->error.to.stream);
-
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
           }
 
           status = F_status_set_error(F_supported_not);
@@ -1986,9 +1946,7 @@ extern "C" {
 
       default:
         if (global.main->error.verbosity != f_console_verbosity_quiet) {
-          f_thread_mutex_lock(&global.thread->lock.print);
-
-          flockfile(global.main->error.to.stream);
+          controller_print_lock(global.main->error.to, global.thread);
 
           fl_print_format("%c%[%SUnsupported action type '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
           fl_print_format("%[%q%]", global.main->error.to.stream, global.main->error.notable, controller_rule_action_type_name(process->action), global.main->error.notable);
@@ -1996,9 +1954,7 @@ extern "C" {
 
           controller_rule_error_print_cache(global.main->error, process->cache.action, F_true);
 
-          funlockfile(global.main->error.to.stream);
-
-          controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+          controller_print_unlock_flush(global.main->error.to, global.thread);
         }
 
         return F_status_set_error(F_parameter);
@@ -2121,12 +2077,12 @@ extern "C" {
               }
 
               if (global.main->error.verbosity != f_console_verbosity_quiet) {
-                f_thread_mutex_lock(&global.thread->lock.print);
+                controller_print_lock(global.main->error.to, global.thread);
 
                 controller_rule_item_error_print_rule_not_loaded(global.main->error, dynamics[i]->array[j].string);
                 controller_rule_error_print_cache(global.main->error, process->cache.action, F_false);
 
-                controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                controller_print_unlock_flush(global.main->error.to, global.thread);
               }
 
               return status;
@@ -2176,12 +2132,12 @@ extern "C" {
             id_rule = 0;
 
             if (i == 0) {
-              f_thread_mutex_lock(&global.thread->lock.print);
+              controller_print_lock(global.main->error.to, global.thread);
 
               controller_rule_item_error_print_need_want_wish(global.main->error, strings[i], dynamics[i]->array[j].string, "was not found");
               controller_rule_error_print_cache(global.main->error, process->cache.action, F_true);
 
-              controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+              controller_print_unlock_flush(global.main->error.to, global.thread);
 
               status = F_status_set_error(F_found_not);
 
@@ -2195,12 +2151,12 @@ extern "C" {
             }
             else {
               if (global.main->warning.verbosity == f_console_verbosity_debug) {
-                f_thread_mutex_lock(&global.thread->lock.print);
+                controller_print_lock(global.main->warning.to, global.thread);
 
                 controller_rule_item_error_print_need_want_wish(global.main->warning, strings[i], dynamics[i]->array[j].string, "was not found");
                 controller_rule_error_print_cache(global.main->warning, process->cache.action, F_true);
 
-                controller_print_unlock_flush(global.main->warning.to.stream, &global.thread->lock.print);
+                controller_print_unlock_flush(global.main->warning.to, global.thread);
               }
             }
           }
@@ -2278,12 +2234,12 @@ extern "C" {
 
                 if (F_status_is_error(status)) {
                   if (i == 0 || i == 1 || F_status_set_fine(status) == F_memory_not) {
-                    f_thread_mutex_lock(&global.thread->lock.print);
+                    controller_print_lock(global.main->error.to, global.thread);
 
                     controller_rule_item_error_print_need_want_wish(global.main->error, strings[i], alias_other_buffer, "failed during execution");
                     controller_rule_error_print_cache(global.main->error, process->cache.action, F_true);
 
-                    controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                    controller_print_unlock_flush(global.main->error.to, global.thread);
 
                     if (!(dependency->options & controller_process_option_simulate) || F_status_set_fine(status) == F_memory_not) {
                       f_thread_unlock(&dependency->active);
@@ -2293,12 +2249,12 @@ extern "C" {
                   }
                   else {
                     if (global.main->warning.verbosity == f_console_verbosity_debug) {
-                      f_thread_mutex_lock(&global.thread->lock.print);
+                      controller_print_lock(global.main->warning.to, global.thread);
 
                       controller_rule_item_error_print_need_want_wish(global.main->warning, strings[i], alias_other_buffer, "failed during execution");
                       controller_rule_error_print_cache(global.main->warning, process->cache.action, F_true);
 
-                      controller_print_unlock_flush(global.main->warning.to.stream, &global.thread->lock.print);
+                      controller_print_unlock_flush(global.main->warning.to, global.thread);
                     }
                   }
                 }
@@ -2336,14 +2292,15 @@ extern "C" {
               f_thread_unlock(&global.thread->lock.rule);
 
               if (i == 0 || i == 1) {
-                f_thread_mutex_lock(&global.thread->lock.print);
+                controller_print_lock(global.main->error.to, global.thread);
 
                 controller_rule_item_error_print_need_want_wish(global.main->error, strings[i], alias_other_buffer, "is in a failed state");
 
-                status = F_status_set_error(F_found_not);
                 controller_rule_error_print_cache(global.main->error, process->cache.action, F_true);
 
-                controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                controller_print_unlock_flush(global.main->error.to, global.thread);
+
+                status = F_status_set_error(F_found_not);
 
                 if (!(dependency->options & controller_process_option_simulate)) {
                   f_thread_unlock(&dependency->active);
@@ -2353,12 +2310,13 @@ extern "C" {
               }
               else {
                 if (global.main->warning.verbosity == f_console_verbosity_debug) {
-                  f_thread_mutex_lock(&global.thread->lock.print);
+                  controller_print_lock(global.main->warning.to, global.thread);
 
                   controller_rule_item_error_print_need_want_wish(global.main->warning, strings[i], alias_other_buffer, "is in a failed state");
+
                   controller_rule_error_print_cache(global.main->warning, process->cache.action, F_true);
 
-                  controller_print_unlock_flush(global.main->warning.to.stream, &global.thread->lock.print);
+                  controller_print_unlock_flush(global.main->warning.to, global.thread);
                 }
               }
             }
@@ -2416,9 +2374,7 @@ extern "C" {
 
         if (missing) {
           if (global.main->error.verbosity != f_console_verbosity_quiet) {
-            f_thread_mutex_lock(&global.thread->lock.print);
-
-            flockfile(global.main->error.to.stream);
+            controller_print_lock(global.main->error.to, global.thread);
 
             fl_print_format("%c%[%SThe rule '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
             fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, process->rule.name, global.main->error.notable);
@@ -2428,9 +2384,7 @@ extern "C" {
 
             controller_rule_error_print_cache(global.main->error, process->cache.action, F_true);
 
-            funlockfile(global.main->error.to.stream);
-
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
           }
 
           status = F_status_set_error(F_parameter);
@@ -2558,12 +2512,12 @@ extern "C" {
         f_thread_unlock(&global.thread->lock.process);
 
         if (global.main->error.verbosity != f_console_verbosity_quiet) {
-          f_thread_mutex_lock(&global.thread->lock.print);
+          controller_print_lock(global.main->error.to, global.thread);
 
           controller_rule_item_error_print_rule_not_loaded(global.main->error, alias_rule.string);
           controller_rule_error_print_cache(global.main->error, cache.action, F_false);
 
-          controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+          controller_print_unlock_flush(global.main->error.to, global.thread);
         }
 
         return status;
@@ -2863,9 +2817,7 @@ extern "C" {
 
           if (process->stack.array[i] == id_rule) {
             if (global.main->error.verbosity != f_console_verbosity_quiet) {
-              f_thread_mutex_lock(&global.thread->lock.print);
-
-              flockfile(global.main->error.to.stream);
+              controller_print_lock(global.main->error.to, global.thread);
 
               fl_print_format("%c%[%SThe rule '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
               fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, process->rule.alias, global.main->error.notable);
@@ -2873,9 +2825,7 @@ extern "C" {
 
               controller_rule_error_print_cache(global.main->error, process->cache.action, F_true);
 
-              funlockfile(global.main->error.to.stream);
-
-              controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+              controller_print_unlock_flush(global.main->error.to, global.thread);
             }
 
             // never continue on circular recursion errors even in simulate mode.
@@ -2945,12 +2895,12 @@ extern "C" {
       status = F_status_set_error(F_found_not);
 
       if (global.main->error.verbosity != f_console_verbosity_quiet) {
-        f_thread_mutex_lock(&global.thread->lock.print);
+        controller_print_lock(global.main->error.to, global.thread);
 
         controller_rule_item_error_print_rule_not_loaded(global.main->error, process->rule.alias.string);
         controller_rule_error_print_cache(global.main->error, process->cache.action, F_false);
 
-        controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+        controller_print_unlock_flush(global.main->error.to, global.thread);
       }
     }
 
@@ -3241,9 +3191,7 @@ extern "C" {
           }
           else {
             if (global.main->warning.verbosity == f_console_verbosity_debug) {
-              f_thread_mutex_lock(&global.thread->lock.print);
-
-              flockfile(global.main->warning.to.stream);
+              controller_print_lock(global.main->warning.to, global.thread);
 
               fl_print_format("%c%[%SUnknown rule item '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, global.main->warning.context);
               fl_print_format("%[%Q%]", global.main->warning.to.stream, global.main->warning.notable, cache->action.name_item, global.main->warning.notable);
@@ -3251,9 +3199,7 @@ extern "C" {
 
               controller_rule_error_print_cache(global.main->warning, cache->action, F_true);
 
-              funlockfile(global.main->warning.to.stream);
-
-              f_thread_mutex_lock(&global.thread->lock.print);
+              controller_print_unlock_flush(global.main->warning.to, global.thread);
             }
 
             continue;
@@ -3443,9 +3389,7 @@ extern "C" {
 
           cache->action.line_action = ++cache->action.line_item;
 
-          f_thread_mutex_lock(&global.thread->lock.print);
-
-          flockfile(global.main->warning.to.stream);
+          controller_print_lock(global.main->warning.to, global.thread);
 
           fl_print_format("%c%[%SUnknown rule setting '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, global.main->warning.context);
           fl_print_format("%[%Q%]", global.main->warning.to.stream, global.main->warning.notable, cache->action.name_item, global.main->warning.notable);
@@ -3453,9 +3397,7 @@ extern "C" {
 
           controller_rule_error_print_cache(global.main->warning, cache->action, F_false);
 
-          funlockfile(global.main->warning.to.stream);
-
-          controller_print_unlock_flush(global.main->warning.to.stream, &global.thread->lock.print);
+          controller_print_unlock_flush(global.main->warning.to, global.thread);
         }
 
         continue;
@@ -3470,17 +3412,13 @@ extern "C" {
 
           cache->action.line_action = ++cache->action.line_item;
 
-          f_thread_mutex_lock(&global.thread->lock.print);
-
-          flockfile(global.main->warning.to.stream);
+          controller_print_lock(global.main->warning.to, global.thread);
 
           fl_print_format("%c%[%SEmpty rule setting.%]%c", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, global.main->warning.context, f_string_eol_s[0]);
 
           controller_rule_error_print_cache(global.main->warning, cache->action, F_false);
 
-          funlockfile(global.main->warning.to.stream);
-
-          controller_print_unlock_flush(global.main->warning.to.stream, &global.thread->lock.print);
+          controller_print_unlock_flush(global.main->warning.to, global.thread);
         }
 
         continue;
@@ -3536,17 +3474,13 @@ extern "C" {
 
             cache->action.line_action = ++cache->action.line_item;
 
-            f_thread_mutex_lock(&global.thread->lock.print);
-
-            flockfile(global.main->error.to.stream);
+            controller_print_lock(global.main->error.to, global.thread);
 
             fl_print_format("%c%[%SRule setting requires one or more Content.%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context, f_string_eol_s[0]);
 
             controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-            funlockfile(global.main->error.to.stream);
-
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
           }
 
           if (F_status_is_error_not(status_return)) {
@@ -3599,9 +3533,7 @@ extern "C" {
 
                 cache->action.line_action = ++cache->action.line_item;
 
-                f_thread_mutex_lock(&global.thread->lock.print);
-
-                flockfile(global.main->error.to.stream);
+                controller_print_lock(global.main->error.to, global.thread);
 
                 if (status == F_number_overflow || status == F_number_underflow) {
                   fl_print_format("%c%[%SRule setting has an unsupported number '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
@@ -3616,9 +3548,7 @@ extern "C" {
 
                 controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-                funlockfile(global.main->error.to.stream);
-
-                controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                controller_print_unlock_flush(global.main->error.to, global.thread);
               }
 
               status = F_status_set_error(F_valid_not);
@@ -3657,17 +3587,13 @@ extern "C" {
 
             cache->action.line_action = ++cache->action.line_item;
 
-            f_thread_mutex_lock(&global.thread->lock.print);
-
-            flockfile(global.main->error.to.stream);
+            controller_print_lock(global.main->error.to, global.thread);
 
             fl_print_format("%c%[%SRule setting requires exactly two Content.%]%c", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context, f_string_eol_s[0]);
 
             controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-            funlockfile(global.main->error.to.stream);
-
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
           }
 
           if (F_status_is_error_not(status_return)) {
@@ -3780,9 +3706,7 @@ extern "C" {
 
         if (cache->content_actions.array[i].used < 2 || rule->has & controller_rule_has_control_group) {
           if (global.main->error.verbosity != f_console_verbosity_quiet) {
-            f_thread_mutex_lock(&global.thread->lock.print);
-
-            flockfile(global.main->error.to.stream);
+            controller_print_lock(global.main->error.to, global.thread);
 
             fl_print_format("%c%[%SRule setting requires two or more Content.%]%c", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context, f_string_eol_s[0]);
 
@@ -3794,9 +3718,7 @@ extern "C" {
 
             controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-            funlockfile(global.main->error.to.stream);
-
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
           }
 
           if (F_status_is_error_not(status_return)) {
@@ -3821,9 +3743,7 @@ extern "C" {
 
             cache->action.line_action = ++cache->action.line_item;
 
-            f_thread_mutex_lock(&global.thread->lock.print);
-
-            flockfile(global.main->error.to.stream);
+            controller_print_lock(global.main->error.to, global.thread);
 
             fl_print_format("%c%[%SRule setting has an unknown option '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
             fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[0], global.main->error.notable);
@@ -3831,9 +3751,7 @@ extern "C" {
 
             controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-            funlockfile(global.main->error.to.stream);
-
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
           }
 
           if (F_status_is_error_not(status_return)) {
@@ -3914,17 +3832,13 @@ extern "C" {
 
             cache->action.line_action = ++cache->action.line_item;
 
-            f_thread_mutex_lock(&global.thread->lock.print);
-
-            flockfile(global.main->error.to.stream);
+            controller_print_lock(global.main->error.to, global.thread);
 
             fl_print_format("%c%[%SRule setting requires three Content.%]%c", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context, f_string_eol_s[0]);
 
             controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-            funlockfile(global.main->error.to.stream);
-
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
           }
 
           if (F_status_is_error_not(status_return)) {
@@ -3991,9 +3905,7 @@ extern "C" {
 
             cache->action.line_action = ++cache->action.line_item;
 
-            f_thread_mutex_lock(&global.thread->lock.print);
-
-            flockfile(global.main->error.to.stream);
+            controller_print_lock(global.main->error.to, global.thread);
 
             fl_print_format("%c%[%SUnknown resource limit type '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
             fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, cache->action.name_action, global.main->error.notable);
@@ -4001,9 +3913,7 @@ extern "C" {
 
             controller_rule_error_print_cache(global.main->error, cache->action, F_true);
 
-            funlockfile(global.main->error.to.stream);
-
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
           }
 
           if (F_status_is_error_not(status_return)) {
@@ -4024,17 +3934,13 @@ extern "C" {
 
               cache->action.line_action = ++cache->action.line_item;
 
-              f_thread_mutex_lock(&global.thread->lock.print);
-
-              flockfile(global.main->error.to.stream);
+              controller_print_lock(global.main->error.to, global.thread);
 
               fl_print_format("%c%[%SThe resource limit type is already specified%]%c", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.context, f_string_eol_s[0]);
 
               controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-              funlockfile(global.main->error.to.stream);
-
-              controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+              controller_print_unlock_flush(global.main->error.to, global.thread);
             }
 
             status = F_status_set_error(F_valid_not);
@@ -4091,9 +3997,7 @@ extern "C" {
 
                 cache->action.line_action = ++cache->action.line_item;
 
-                f_thread_mutex_lock(&global.thread->lock.print);
-
-                flockfile(global.main->error.to.stream);
+                controller_print_lock(global.main->error.to, global.thread);
 
                 if (status == F_number_overflow || status == F_number_underflow) {
                   fl_print_format("%c%[%SRule setting has an unsupported number'%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
@@ -4108,9 +4012,7 @@ extern "C" {
 
                 controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-                funlockfile(global.main->error.to.stream);
-
-                controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                controller_print_unlock_flush(global.main->error.to, global.thread);
               }
 
               status = F_status_set_error(F_valid_not);
@@ -4168,17 +4070,13 @@ extern "C" {
 
             cache->action.line_action = ++cache->action.line_item;
 
-            f_thread_mutex_lock(&global.thread->lock.print);
-
-            flockfile(global.main->error.to.stream);
+            controller_print_lock(global.main->error.to, global.thread);
 
             fl_print_format("%c%[%SRule setting requires exactly one Content.%]%c", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context, f_string_eol_s[0]);
 
             controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-            funlockfile(global.main->error.to.stream);
-
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
           }
 
           if (F_status_is_error_not(status_return)) {
@@ -4229,9 +4127,7 @@ extern "C" {
 
               if (status == F_false) {
                 if (global.main->error.verbosity != f_console_verbosity_quiet) {
-                  f_thread_mutex_lock(&global.thread->lock.print);
-
-                  flockfile(global.main->error.to.stream);
+                  controller_print_lock(global.main->error.to, global.thread);
 
                   fl_print_format("%c%[%SRule setting has an invalid name '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
                   fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, *setting_value, global.main->error.notable);
@@ -4239,9 +4135,7 @@ extern "C" {
 
                   controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-                  funlockfile(global.main->error.to.stream);
-
-                  controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                  controller_print_unlock_flush(global.main->error.to, global.thread);
                 }
 
                 if (F_status_is_error_not(status_return)) {
@@ -4318,17 +4212,13 @@ extern "C" {
 
             cache->action.line_action = ++cache->action.line_item;
 
-            f_thread_mutex_lock(&global.thread->lock.print);
-
-            flockfile(global.main->error.to.stream);
+            controller_print_lock(global.main->error.to, global.thread);
 
             fl_print_format("%c%[%SRule setting requires either one or two Content.'%]%c", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context, f_string_eol_s[0]);
 
             controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-            funlockfile(global.main->error.to.stream);
-
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
           }
 
           if (F_status_is_error_not(status_return)) {
@@ -4371,9 +4261,7 @@ extern "C" {
 
             cache->action.line_action = ++cache->action.line_item;
 
-            f_thread_mutex_lock(&global.thread->lock.print);
-
-            flockfile(global.main->error.to.stream);
+            controller_print_lock(global.main->error.to, global.thread);
 
             fl_print_format("%c%[%SRule setting has an unknown scheduler '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
             fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[0], global.main->error.notable);
@@ -4381,9 +4269,7 @@ extern "C" {
 
             controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-            funlockfile(global.main->error.to.stream);
-
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
           }
 
           if (F_status_is_error_not(status_return)) {
@@ -4413,9 +4299,7 @@ extern "C" {
 
                 cache->action.line_action = ++cache->action.line_item;
 
-                f_thread_mutex_lock(&global.thread->lock.print);
-
-                flockfile(global.main->error.to.stream);
+                controller_print_lock(global.main->error.to, global.thread);
 
                 fl_print_format("%c%[%SRule setting has an invalid number '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
                 fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[1], global.main->error.notable);
@@ -4434,9 +4318,7 @@ extern "C" {
 
                 controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-                funlockfile(global.main->error.to.stream);
-
-                controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                controller_print_unlock_flush(global.main->error.to, global.thread);
               }
 
               if (F_status_is_error_not(status_return)) {
@@ -4475,17 +4357,13 @@ extern "C" {
 
             cache->action.line_action = ++cache->action.line_item;
 
-            f_thread_mutex_lock(&global.thread->lock.print);
-
-            flockfile(global.main->error.to.stream);
+            controller_print_lock(global.main->error.to, global.thread);
 
             fl_print_format("%c%[%SRule setting requires exactly one Content.%]%c", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context, f_string_eol_s[0]);
 
             controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-            funlockfile(global.main->error.to.stream);
-
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
           }
 
           if (F_status_is_error_not(status_return)) {
@@ -4508,13 +4386,13 @@ extern "C" {
 
             cache->action.line_action = ++cache->action.line_item;
 
-            f_thread_mutex_lock(&global.thread->lock.print);
+            controller_print_lock(global.main->error.to, global.thread);
 
             controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
 
             controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
 
             if (F_status_set_fine(status) == F_memory_not) {
               status_return = status;
@@ -4536,13 +4414,13 @@ extern "C" {
 
             cache->action.line_action = ++cache->action.line_item;
 
-            f_thread_mutex_lock(&global.thread->lock.print);
+            controller_print_lock(global.main->error.to, global.thread);
 
             controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false, global.thread);
 
             controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
 
             if (F_status_set_fine(status) == F_memory_not) {
               status_return = status;
@@ -4565,13 +4443,13 @@ extern "C" {
 
               cache->action.line_action = ++cache->action.line_item;
 
-              f_thread_mutex_lock(&global.thread->lock.print);
+              controller_print_lock(global.main->error.to, global.thread);
 
               controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_capability_from_text", F_true, F_false, global.thread);
 
               controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-              controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+              controller_print_unlock_flush(global.main->error.to, global.thread);
 
               status_return = status;
               break;
@@ -4585,17 +4463,13 @@ extern "C" {
 
               cache->action.line_action = ++cache->action.line_item;
 
-              f_thread_mutex_lock(&global.thread->lock.print);
-
-              flockfile(global.main->error.to.stream);
+              controller_print_lock(global.main->error.to, global.thread);
 
               fl_print_format("%c%[%SRule setting failed to process the capabilities.%]%c", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context, f_string_eol_s[0]);
 
               controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-              funlockfile(global.main->error.to.stream);
-
-              controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+              controller_print_unlock_flush(global.main->error.to, global.thread);
             }
 
             if (F_status_is_error_not(status_return)) {
@@ -4623,9 +4497,7 @@ extern "C" {
 
                 cache->action.line_action = ++cache->action.line_item;
 
-                f_thread_mutex_lock(&global.thread->lock.print);
-
-                flockfile(global.main->error.to.stream);
+                controller_print_lock(global.main->error.to, global.thread);
 
                 fl_print_format("%c%[%SRule setting has an invalid number '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
                 fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[0], global.main->error.notable);
@@ -4637,9 +4509,7 @@ extern "C" {
 
                 controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-                funlockfile(global.main->error.to.stream);
-
-                controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                controller_print_unlock_flush(global.main->error.to, global.thread);
               }
 
               if (F_status_is_error_not(status_return)) {
@@ -4676,47 +4546,35 @@ extern "C" {
 
             if (status == F_exist_not) {
               if (global.main->error.verbosity != f_console_verbosity_quiet) {
-                f_thread_mutex_lock(&global.thread->lock.print);
-
-                flockfile(global.main->error.to.stream);
+                controller_print_lock(global.main->error.to, global.thread);
 
                 fl_print_format("%c%[%SRule setting has an invalid user '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
                 fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[0], global.main->error.notable);
                 fl_print_format("%[' because no user was found by that name.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]);
 
-                funlockfile(global.main->error.to.stream);
-
-                controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                controller_print_unlock_flush(global.main->error.to, global.thread);
               }
             }
             else if (status == F_number_too_large) {
               if (global.main->error.verbosity != f_console_verbosity_quiet) {
-                f_thread_mutex_lock(&global.thread->lock.print);
-
-                flockfile(global.main->error.to.stream);
+                controller_print_lock(global.main->error.to, global.thread);
 
                 fl_print_format("%c%[%SRule setting has an invalid user '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
                 fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[0], global.main->error.notable);
                 fl_print_format("%[' because the given ID is too large.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]);
 
-                funlockfile(global.main->error.to.stream);
-
-                controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                controller_print_unlock_flush(global.main->error.to, global.thread);
               }
             }
             else if (status == F_number) {
               if (global.main->error.verbosity != f_console_verbosity_quiet) {
-                f_thread_mutex_lock(&global.thread->lock.print);
-
-                flockfile(global.main->error.to.stream);
+                controller_print_lock(global.main->error.to, global.thread);
 
                 fl_print_format("%c%[%SRule setting has an invalid user '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
                 fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[0], global.main->error.notable);
                 fl_print_format("%[' because the given ID is not a valid supported number.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]);
 
-                funlockfile(global.main->error.to.stream);
-
-                controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                controller_print_unlock_flush(global.main->error.to, global.thread);
               }
             }
             else {
@@ -4748,17 +4606,13 @@ extern "C" {
 
             cache->action.line_action = ++cache->action.line_item;
 
-            f_thread_mutex_lock(&global.thread->lock.print);
-
-            flockfile(global.main->error.to.stream);
+            controller_print_lock(global.main->error.to, global.thread);
 
             fl_print_format("%c%[%SRule setting requires one or more Content.%]%c", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context, f_string_eol_s[0]);
 
             controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-            funlockfile(global.main->error.to.stream);
-
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
           }
 
           if (F_status_is_error_not(status_return)) {
@@ -4806,47 +4660,35 @@ extern "C" {
 
             if (status == F_exist_not) {
               if (global.main->error.verbosity != f_console_verbosity_quiet) {
-                f_thread_mutex_lock(&global.thread->lock.print);
-
-                flockfile(global.main->error.to.stream);
+                controller_print_lock(global.main->error.to, global.thread);
 
                 fl_print_format("%c%[%SRule setting has an invalid group '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
                 fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[j], global.main->error.notable);
                 fl_print_format("%[' because no group was found by that name.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]);
 
-                funlockfile(global.main->error.to.stream);
-
-                controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                controller_print_unlock_flush(global.main->error.to, global.thread);
               }
             }
             else if (status == F_number_too_large) {
               if (global.main->error.verbosity != f_console_verbosity_quiet) {
-                f_thread_mutex_lock(&global.thread->lock.print);
-
-                flockfile(global.main->error.to.stream);
+                controller_print_lock(global.main->error.to, global.thread);
 
                 fl_print_format("%c%[%SRule setting has an invalid group '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
                 fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[j], global.main->error.notable);
                 fl_print_format("%[' because the given ID is too large.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]);
 
-                funlockfile(global.main->error.to.stream);
-
-                controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                controller_print_unlock_flush(global.main->error.to, global.thread);
               }
             }
             else if (status == F_number) {
               if (global.main->error.verbosity != f_console_verbosity_quiet) {
-                f_thread_mutex_lock(&global.thread->lock.print);
-
-                flockfile(global.main->error.to.stream);
+                controller_print_lock(global.main->error.to, global.thread);
 
                 fl_print_format("%c%[%SRule setting has an invalid group '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
                 fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[j], global.main->error.notable);
                 fl_print_format("%[' because the given ID is not a valid supported number.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]);
 
-                funlockfile(global.main->error.to.stream);
-
-                controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                controller_print_unlock_flush(global.main->error.to, global.thread);
               }
             }
             else {
@@ -4960,9 +4802,7 @@ extern "C" {
             if (status == F_false) {
 
               if (global.main->error.verbosity != f_console_verbosity_quiet) {
-                f_thread_mutex_lock(&global.thread->lock.print);
-
-                flockfile(global.main->error.to.stream);
+                controller_print_lock(global.main->error.to, global.thread);
 
                 fl_print_format("%c%[%SRule setting has an invalid environment variable name '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
                 fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, setting_values->array[setting_values->used], global.main->error.notable);
@@ -4970,9 +4810,7 @@ extern "C" {
 
                 controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-                funlockfile(global.main->error.to.stream);
-
-                controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+                controller_print_unlock_flush(global.main->error.to, global.thread);
               }
 
               if (F_status_is_error_not(status_return)) {
@@ -5013,17 +4851,13 @@ extern "C" {
 
           cache->action.line_action = ++cache->action.line_item;
 
-          f_thread_mutex_lock(&global.thread->lock.print);
-
-          flockfile(global.main->error.to.stream);
+          controller_print_lock(global.main->error.to, global.thread);
 
           fl_print_format("%c%[%SRule setting requires exactly four Content.%]%c", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context, f_string_eol_s[0]);
 
           controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-          funlockfile(global.main->error.to.stream);
-
-          controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+          controller_print_unlock_flush(global.main->error.to, global.thread);
         }
 
         if (F_status_is_error_not(status_return)) {
@@ -5072,7 +4906,7 @@ extern "C" {
 
           f_thread_mutex_lock(&global.thread->lock.print);
 
-          flockfile(global.main->error.to.stream);
+          controller_print_lock(global.main->error.to, global.thread);
 
           fl_print_format("%c%[%SRule setting's first value has '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
           fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[1], global.main->error.notable);
@@ -5081,9 +4915,7 @@ extern "C" {
 
           controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-          funlockfile(global.main->error.to.stream);
-
-          controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+          controller_print_unlock_flush(global.main->error.to, global.thread);
         }
 
         if (F_status_is_error_not(status_return)) {
@@ -5123,9 +4955,7 @@ extern "C" {
 
             cache->action.line_action = ++cache->action.line_item;
 
-            f_thread_mutex_lock(&global.thread->lock.print);
-
-            flockfile(global.main->error.to.stream);
+            controller_print_lock(global.main->error.to, global.thread);
 
             fl_print_format("%c%[%SRule setting's second value has '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
             fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[1], global.main->error.notable);
@@ -5133,9 +4963,7 @@ extern "C" {
 
             controller_rule_error_print_cache(global.main->error, cache->action, F_false);
 
-            funlockfile(global.main->error.to.stream);
-
-            controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+            controller_print_unlock_flush(global.main->error.to, global.thread);
           }
 
           if (F_status_is_error_not(status_return)) {
@@ -5222,9 +5050,7 @@ extern "C" {
       if (fl_string_dynamic_partial_compare_string(cache->buffer_item.string, cache->buffer_path, cache->buffer_item.used, cache->content_actions.array[i].array[1]) == F_equal_to_not) {
 
         if (global.main->error.verbosity != f_console_verbosity_quiet) {
-          f_thread_mutex_lock(&global.thread->lock.print);
-
-          flockfile(global.main->error.to.stream);
+          controller_print_lock(global.main->error.to, global.thread);
 
           fl_print_format("%c%[%SThe rule item action third parameter '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context);
           fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[2], global.main->error.notable);
@@ -5232,9 +5058,7 @@ extern "C" {
           fl_print_format("%[%Q%]", global.main->error.to.stream, cache->buffer_path, global.main->error.notable);
           fl_print_format("%['.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]);
 
-          funlockfile(global.main->error.to.stream);
-
-          controller_print_unlock_flush(global.main->error.to.stream, &global.thread->lock.print);
+          controller_print_unlock_flush(global.main->error.to, global.thread);
         }
 
         setting_values->array[setting_values->used].used = 0;
@@ -5268,8 +5092,6 @@ extern "C" {
 
     const controller_main_t *main = global.main;
 
-    f_thread_mutex_lock(&global.thread->lock.print);
-
     switch (action) {
       case controller_rule_action_type_freeze:
       case controller_rule_action_type_kill:
@@ -5285,7 +5107,7 @@ extern "C" {
       default:
 
         if (main->error.verbosity != f_console_verbosity_quiet) {
-          flockfile(main->error.to.stream);
+          controller_print_lock(main->error.to, global.thread);
 
           fl_print_format("%c%[%SUnsupported action type '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context);
           fl_print_format("%[%q%]", main->error.to.stream, main->error.notable, controller_rule_action_type_name(action), main->error.notable);
@@ -5293,11 +5115,9 @@ extern "C" {
 
           controller_rule_error_print_cache(main->error, cache->action, F_true);
 
-          funlockfile(main->error.to.stream);
+          controller_print_unlock_flush(main->error.to, global.thread);
         }
 
-        controller_print_unlock_flush(main->error.to.stream, &global.thread->lock.print);
-
         return;
     }
 
@@ -5320,7 +5140,7 @@ extern "C" {
       } // for
 
       if (missing) {
-        flockfile(main->output.stream);
+        controller_print_lock(main->output, global.thread);
 
         fl_print_format("%cRule '", main->output.stream, f_string_eol_s[0]);
         fl_print_format("%[%Q%]' has no '", main->output.stream, main->context.set.title, rule.name, main->context.set.title);
@@ -5328,11 +5148,11 @@ extern "C" {
         fl_print_format("%[%s%]' because it is '", main->output.stream, main->context.set.important, options & controller_process_option_require ? controller_string_fail_s : controller_string_succeed_s, main->context.set.important);
         fl_print_format("%[%s%]'.%c", main->output.stream, main->context.set.important, options & controller_process_option_require ? controller_string_required_s : controller_string_optional_s, main->context.set.important, f_string_eol_s[0]);
 
-        funlockfile(main->output.stream);
+        controller_print_unlock_flush(main->output, global.thread);
       }
     }
 
-    flockfile(main->output.stream);
+    controller_print_lock(main->output, global.thread);
 
     fl_print_format("%cRule %[%Q%] {%c", main->output.stream, f_string_eol_s[0], main->context.set.title, rule.alias, main->context.set.title, f_string_eol_s[0]);
     fl_print_format("  %[%s%] %Q%c", main->output.stream, main->context.set.important, controller_string_name_s, main->context.set.important, rule.name, f_string_eol_s[0]);
@@ -5592,9 +5412,7 @@ extern "C" {
 
     fl_print_format("}%c", main->output.stream, f_string_eol_s[0]);
 
-    funlockfile(main->output.stream);
-
-    controller_print_unlock_flush(main->output.stream, &global.thread->lock.print);
+    controller_print_unlock_flush(main->output, global.thread);
   }
 #endif // _di_controller_rule_validate_
 
index bf3971d5ef17822eb180d1fd8c5ec4dca33f1f65..06aaa4015e98b1879fab8bbd62ef7e4938166937 100644 (file)
@@ -245,8 +245,8 @@ extern "C" {
  *
  * This is explicitly intended to be used in addition to the error message.
  *
- * @param output
- *   The error or warning output structure.
+ * @param print
+ *   The error or warning print structure.
  * @param cache
  *   A structure for containing and caching relevant data.
  * @param item
@@ -258,7 +258,7 @@ extern "C" {
  * @see controller_rule_error_print_cache()
  */
 #ifndef _di_controller_rule_item_error_print_
-  extern void controller_rule_item_error_print(const fll_error_print_t output, const controller_cache_action_t cache, const bool item, controller_thread_t *thread) f_attribute_visibility_internal;
+  extern void controller_rule_item_error_print(const fll_error_print_t print, const controller_cache_action_t cache, const bool item, controller_thread_t *thread) f_attribute_visibility_internal;
 #endif // _di_controller_rule_item_error_print_
 
 /**
@@ -275,9 +275,11 @@ extern "C" {
  *   The code returned by the executed program or script.
  * @param status
  *   The status code representing the failure (without the error bit set).
+ * @param thread
+ *   The thread data.
  */
 #ifndef _di_controller_rule_item_error_print_execute_
-  extern void controller_rule_item_error_print_execute(const fll_error_print_t output, const bool script_is, const f_string_t name, const int code, const f_status_t status) f_attribute_visibility_internal;
+  extern void controller_rule_item_error_print_execute(const fll_error_print_t output, const bool script_is, const f_string_t name, const int code, const f_status_t status, controller_thread_t * const thread) f_attribute_visibility_internal;
 #endif // _di_controller_rule_item_error_print_execute_
 
 /**
index fb58d3b59e0be72b1bdfecc15d6569c36fedcc39..fb47c10dc9befabd1a58a6bc62c461cd4af75a64 100644 (file)
@@ -227,17 +227,13 @@ extern "C" {
 
         if (f_file_exists(setting->path_pid.string) == F_true) {
           if (main->error.verbosity != f_console_verbosity_quiet) {
-            f_thread_mutex_lock(&thread.lock.print);
-
-            flockfile(main->error.to.stream);
+            controller_print_lock(main->error.to, &thread);
 
             fl_print_format("%c%[%SThe pid file '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context);
             fl_print_format("%[%S%]", main->error.to.stream, main->error.notable, setting->path_pid.string, main->error.notable);
             fl_print_format("%[' must not already exist.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]);
 
-            funlockfile(main->error.to.stream);
-
-            controller_print_unlock_flush(main->error.to.stream, &thread.lock.print);
+            controller_print_unlock_flush(main->error.to, &thread);
           }
 
           setting->ready = controller_setting_ready_abort;
@@ -723,17 +719,13 @@ extern "C" {
 
         if (f_file_exists(entry->setting->path_pid.string) == F_true) {
           if (main->error.verbosity != f_console_verbosity_quiet) {
-            f_thread_mutex_lock(&entry->global->thread->lock.print);
-
-            flockfile(main->error.to.stream);
+            controller_print_lock(main->error.to, entry->global->thread);
 
             fl_print_format("%c%[%SThe pid file '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context);
             fl_print_format("%[%Q%]", main->error.to.stream, main->error.notable, entry->setting->path_pid, main->error.notable);
             fl_print_format("%[' must not already exist.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]);
 
-            funlockfile(main->error.to.stream);
-
-            controller_print_unlock_flush(main->error.to.stream, &entry->global->thread->lock.print);
+            controller_print_unlock_flush(main->error.to, entry->global->thread);
           }
 
           entry->setting->ready = controller_setting_ready_fail;
@@ -767,17 +759,13 @@ extern "C" {
 
               if (F_status_is_error(status_failsafe)) {
                 if (main->error.verbosity != f_console_verbosity_quiet) {
-                  f_thread_mutex_lock(&entry->global->thread->lock.print);
-
-                  flockfile(main->error.to.stream);
+                  controller_print_lock(main->error.to, entry->global->thread);
 
                   fl_print_format("%c%[%SFailed while processing requested failsafe item '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context);
                   fl_print_format("%[%Q%]", main->error.to.stream, main->error.notable, entry->global->setting->entry.items.array[entry->global->setting->failsafe_enabled].name, main->error.notable);
                   fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]);
 
-                  funlockfile(main->error.to.stream);
-
-                  controller_print_unlock_flush(main->error.to.stream, &entry->global->thread->lock.print);
+                  controller_print_unlock_flush(main->error.to, entry->global->thread);
                 }
 
                 *status = F_status_set_error(F_failure);
@@ -880,17 +868,13 @@ extern "C" {
 
             if (F_status_is_error(status_failsafe)) {
               if (main->error.verbosity != f_console_verbosity_quiet) {
-                f_thread_mutex_lock(&entry->global->thread->lock.print);
-
-                flockfile(main->error.to.stream);
+                controller_print_lock(main->error.to, entry->global->thread);
 
                 fl_print_format("%c%[%SFailed while processing requested failsafe item '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context);
                 fl_print_format("%[%Q%]", main->error.to.stream, main->error.notable, entry->global->setting->entry.items.array[entry->global->setting->failsafe_enabled].name, main->error.notable);
                 fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]);
 
-                funlockfile(main->error.to.stream);
-
-                controller_print_unlock_flush(main->error.to.stream, &entry->global->thread->lock.print);
+                controller_print_unlock_flush(main->error.to, entry->global->thread);
               }
 
               *status = F_status_set_error(F_failure);