]> Kevux Git Server - fll/commitdiff
Update: redesign forced exit to utilize timed waits.
authorKevin Day <thekevinday@gmail.com>
Sat, 10 Apr 2021 01:42:46 +0000 (20:42 -0500)
committerKevin Day <thekevinday@gmail.com>
Sat, 10 Apr 2021 01:42:46 +0000 (20:42 -0500)
level_3/controller/c/private-common.h
level_3/controller/c/private-thread.c

index 162e65e6cea404d509901f61ddc06162504fbd8b..9f1037a5a8948c2228783e809da3d0994d6d3eb4 100644 (file)
@@ -1076,7 +1076,8 @@ extern "C" {
   #define controller_thread_cleanup_interval_long  3600 // 1 hour in seconds.
   #define controller_thread_cleanup_interval_short 180  // 3 minutes in seconds.
   //#define controller_thread_exit_force_timeout 60  // 1 minute in seconds.
-  #define controller_thread_exit_process_force_timeout 2000000 // 2 seconds in microseconds.
+  #define controller_thread_exit_process_force_wait 30000000 // 0.03 seconds in nanoseconds.
+  #define controller_thread_exit_process_force_total 200 // 6 seconds in multiples of wait.
   #define controller_thread_exit_main_force_timeout 100000 // 0.1 seconds in microseconds.
   #define controller_thread_simulation_timeout 200000 // 0.2 seconds in microseconds.
   #define controller_thread_wait_timeout_seconds 10
index 4d41bd511474502049812550add7db6ef764eb74..a4bb24a560e68f12380aede520643dad42d72850 100644 (file)
@@ -111,28 +111,85 @@ extern "C" {
 
     f_thread_lock_read(&main->thread->lock.process);
 
-    // @todo redesign this to use timed waits, that include a counter and a max wait such that when max wait is reached, send kill signals.
-    //       this would, in theory, allow faster exits without as much waiting when there is nothing to wait for.
-
     if (main->thread->processs.size) {
       f_thread_unlock(&main->thread->lock.process);
 
-      usleep(controller_thread_exit_process_force_timeout);
-
       f_thread_lock_read(&main->thread->lock.process);
 
-      for (f_array_length_t i = 0; i < main->thread->processs.size; ++i) {
+      pid_t *process_pids[main->thread->processs.used];
+      f_thread_id_t *process_threads[main->thread->processs.used];
 
-        if (!main->thread->processs.array[i]) continue;
+      memset(process_pids, 0, sizeof(pid_t *) * main->thread->processs.used);
+      memset(process_threads, 0, sizeof(f_thread_id_t *) * main->thread->processs.used);
 
+      f_array_length_t i = 0;
+      f_array_length_t used = 0;
+
+      for (; i < main->thread->processs.size; ++i) {
         if (main->thread->processs.array[i]->child > 0) {
-          f_signal_send(F_signal_kill, main->thread->processs.array[i]->child);
+
+          process_pids[used] = &main->thread->processs.array[i]->child;
+
+          if (main->thread->processs.array[i]->id_thread) {
+            process_threads[used] = &main->thread->processs.array[i]->id_thread;
+          }
+
+          ++used;
         }
+        else if (main->thread->processs.array[i]->id_thread) {
+          process_threads[used] = &main->thread->processs.array[i]->id_thread;
 
-        if (main->thread->processs.array[i]->id_thread) {
-          f_thread_signal(main->thread->processs.array[i]->id_thread, F_signal_kill);
+          ++used;
         }
       } // for
+
+      if (used) {
+        f_status_t status = F_none;
+        f_array_length_t spent = 0;
+
+        struct timespec wait;
+        wait.tv_sec = 0;
+        wait.tv_nsec = controller_thread_exit_process_force_wait;
+
+        for (i = 0; i < used && spent < controller_thread_exit_process_force_total; ++i) {
+
+          do {
+
+            status = f_thread_join_timed(*process_threads[i], wait, 0);
+
+            if (status == F_none) {
+              if (process_pids[i]) *process_pids[i] = 0;
+              if (process_threads[i]) *process_threads[i] = 0;
+
+              process_pids[i] = 0;
+              process_threads[i] = 0;
+            }
+
+            spent++;
+
+          } while (status == F_time && spent < controller_thread_exit_process_force_total);
+
+        } // for
+
+        for (i = 0; i < used; ++i) {
+
+          if (process_pids[i] && *process_pids[i]) {
+            f_signal_send(F_signal_kill, *process_pids[i]);
+
+            *process_pids[i] = 0;
+            process_pids[i] = 0;
+          }
+
+          if (process_pids[i] && *process_pids[i]) {
+            f_thread_signal(*process_pids[i], F_signal_kill);
+
+            f_thread_join(*process_pids[i], 0);
+
+            *process_threads[i] = 0;
+            process_threads[i] = 0;
+          }
+        } // for
+      }
     }
 
     f_thread_unlock(&main->thread->lock.process);