[glib: 1/3] Merging tests/child-test.c into glib/tests/spawn-multithreaded.c




commit 241b9f41b412bd2fed20fde48a1035b0affbf467
Author: Emmanuel Fleury <emmanuel fleury gmail com>
Date:   Fri Dec 3 16:59:35 2021 +0100

    Merging tests/child-test.c into glib/tests/spawn-multithreaded.c
    
    Helps issue #1434

 glib/tests/spawn-multithreaded.c | 160 ++++++++++++++++++++++++++++++-
 tests/child-test.c               | 198 ---------------------------------------
 tests/meson.build                |   1 -
 3 files changed, 159 insertions(+), 200 deletions(-)
---
diff --git a/glib/tests/spawn-multithreaded.c b/glib/tests/spawn-multithreaded.c
index bf2c8a501..b0d7a2f39 100644
--- a/glib/tests/spawn-multithreaded.c
+++ b/glib/tests/spawn-multithreaded.c
@@ -23,11 +23,168 @@
 
 #include "config.h"
 
+#include <stdlib.h>
+
 #include <glib.h>
 #include <string.h>
 
+#include <sys/types.h>
+
 static char *echo_prog_path;
 
+#ifdef G_OS_UNIX
+#include <unistd.h>
+#endif
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#endif
+
+#ifdef G_OS_WIN32
+#define GPID_FORMAT "%p"
+#else
+#define GPID_FORMAT "%d"
+#endif
+
+GMainLoop *main_loop;
+gint alive;
+
+#ifdef G_OS_WIN32
+char *argv0;
+#endif
+
+static GPid
+get_a_child (gint ttl)
+{
+  GPid pid;
+
+#ifdef G_OS_WIN32
+  STARTUPINFO si;
+  PROCESS_INFORMATION pi;
+  gchar *cmdline;
+
+  memset (&si, 0, sizeof (si));
+  si.cb = sizeof (&si);
+  memset (&pi, 0, sizeof (pi));
+
+  cmdline = g_strdup_printf ("child-test -c%d", ttl);
+
+  if (!CreateProcess (argv0, cmdline, NULL, NULL,
+                      FALSE, 0, NULL, NULL, &si, &pi))
+    g_error ("CreateProcess failed: %s",
+             g_win32_error_message (GetLastError ()));
+
+  g_free (cmdline);
+
+  CloseHandle (pi.hThread);
+  pid = pi.hProcess;
+
+  return pid;
+#else
+  pid = fork ();
+  if (pid < 0)
+    exit (1);
+
+  if (pid > 0)
+    return pid;
+
+  sleep (ttl);
+  _exit (0);
+#endif /* G_OS_WIN32 */
+}
+
+static gboolean
+child_watch_callback (GPid pid, gint status, gpointer data)
+{
+#ifdef VERBOSE
+  gint ttl = GPOINTER_TO_INT (data);
+
+  g_print ("child " GPID_FORMAT " (ttl %d) exited, status %d\n",
+           pid, ttl, status);
+#endif
+
+  g_spawn_close_pid (pid);
+
+  if (--alive == 0)
+    g_main_loop_quit (main_loop);
+
+  return TRUE;
+}
+
+#ifdef TEST_THREAD
+static gpointer
+start_thread (gpointer data)
+{
+  GMainLoop *new_main_loop;
+  GSource *source;
+  GPid pid;
+  gint ttl = GPOINTER_TO_INT (data);
+
+  new_main_loop = g_main_loop_new (NULL, FALSE);
+
+  pid = get_a_child (ttl);
+  source = g_child_watch_source_new (pid);
+  g_source_set_callback (source,
+                         (GSourceFunc) child_watch_callback, data, NULL);
+  g_source_attach (source, g_main_loop_get_context (new_main_loop));
+  g_source_unref (source);
+
+#ifdef VERBOSE
+  g_print ("whee! created pid: " GPID_FORMAT " (ttl %d)\n", pid, ttl);
+#endif
+
+  g_main_loop_run (new_main_loop);
+
+  return NULL;
+}
+#endif
+
+static gboolean
+quit_loop (gpointer data)
+{
+  GMainLoop *main_loop = data;
+
+  g_main_loop_quit (main_loop);
+
+  return TRUE;
+}
+
+static void
+test_spawn_childs (void)
+{
+#ifndef TEST_THREAD
+  GPid pid;
+#endif
+
+  main_loop = g_main_loop_new (NULL, FALSE);
+
+#ifdef G_OS_WIN32
+  system ("ipconfig /all");
+#else
+  system ("true");
+#endif
+
+  alive = 2;
+  g_timeout_add_seconds (30, quit_loop, main_loop);
+
+#ifdef TEST_THREAD
+  g_thread_create (start_thread, GINT_TO_POINTER (10), FALSE, NULL);
+  g_thread_create (start_thread, GINT_TO_POINTER (20), FALSE, NULL);
+#else
+  pid = get_a_child (10);
+  g_child_watch_add (pid, (GChildWatchFunc) child_watch_callback,
+                     GINT_TO_POINTER (10));
+  pid = get_a_child (20);
+  g_child_watch_add (pid, (GChildWatchFunc) child_watch_callback,
+                     GINT_TO_POINTER (20));
+#endif
+
+  g_main_loop_run (main_loop);
+  g_main_loop_unref (main_loop);
+
+  g_assert_true (alive == 0);
+}
+
 static void
 multithreaded_test_run (GThreadFunc function)
 {
@@ -105,7 +262,7 @@ on_child_exited (GPid     pid,
   data->child_exited = TRUE;
   if (data->child_exited && data->stdout_done)
     g_main_loop_quit (data->loop);
-  
+
   return G_SOURCE_REMOVE;
 }
 
@@ -232,6 +389,7 @@ main (int   argc,
 
   g_assert (g_file_test (echo_prog_path, G_FILE_TEST_EXISTS));
 
+  g_test_add_func ("/gthread/spawn-childs", test_spawn_childs);
   g_test_add_func ("/gthread/spawn-sync", test_spawn_sync_multithreaded);
   g_test_add_func ("/gthread/spawn-async", test_spawn_async_multithreaded);
 
diff --git a/tests/meson.build b/tests/meson.build
index 8accea423..0f120edee 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -18,7 +18,6 @@ subdir('refcount')
 tests = {
   'testglib' : {'tap' : true},
   'testgdate' : {},
-  'child-test' : {},
   'dirname-test' : {},
   'file-test' : {},
   'env-test' : {},


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]