[gnome-session] GsmProcessHelper: Port to GSubprocess



commit bee8fa320a129499313e00d3bfa96defe5cf4a2a
Author: Colin Walters <walters verbum org>
Date:   Sat Nov 2 15:40:18 2013 -0400

    GsmProcessHelper: Port to GSubprocess
    
    Just decided to do this to help demo/test GSubprocess.  I think the
    code gets a *lot* better.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=711304

 gnome-session/Makefile.am          |    3 +-
 gnome-session/gsm-process-helper.c |  129 +++++++++++++++---------------------
 2 files changed, 55 insertions(+), 77 deletions(-)
---
diff --git a/gnome-session/Makefile.am b/gnome-session/Makefile.am
index c7ae617..0360228 100644
--- a/gnome-session/Makefile.am
+++ b/gnome-session/Makefile.am
@@ -124,7 +124,8 @@ test_client_dbus_SOURCES = test-client-dbus.c
 test_client_dbus_LDADD = $(DBUS_GLIB_LIBS)
 
 test_process_helper_SOURCES = test-process-helper.c gsm-process-helper.c gsm-process-helper.h
-test_process_helper_LDADD = $(DBUS_GLIB_LIBS)
+test_process_helper_CFLAGS = $(AM_CFLAGS) $(GIO_CFLAGS)
+test_process_helper_LDADD = $(GIO_LIBS)
 
 gsm-manager-glue.h: org.gnome.SessionManager.xml Makefile.am
        $(AM_V_GEN)dbus-binding-tool --prefix=gsm_manager --mode=glib-server --output=gsm-manager-glue.h 
$(srcdir)/org.gnome.SessionManager.xml
diff --git a/gnome-session/gsm-process-helper.c b/gnome-session/gsm-process-helper.c
index d7f3aae..6aa02d9 100644
--- a/gnome-session/gsm-process-helper.c
+++ b/gnome-session/gsm-process-helper.c
@@ -20,48 +20,54 @@
 
 #include <config.h>
 
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <signal.h>
-
-#include <glib.h>
+#include <gio/gio.h>
 #include <glib/gi18n.h>
 
 #include "gsm-process-helper.h"
 
 typedef struct {
-        const char *command_line;
-        GPid        pid;
-        gboolean    timed_out;
-        int         status;
-        GMainLoop  *loop;
-        guint       child_id;
-        guint       timeout_id;
+        gboolean        done;
+        GSubprocess    *process;
+        gboolean        caught_error;
+        GError        **error;
+        GMainContext   *maincontext;
+        GSource        *timeout_source;
 } GsmProcessHelper;
 
 static void
-on_child_exited (GPid     pid,
-                 gint     status,
-                 gpointer data)
+on_child_exited (GObject        *source,
+                 GAsyncResult   *result,
+                 gpointer        data)
 {
         GsmProcessHelper *helper = data;
 
-        helper->timed_out = FALSE;
-        helper->status = status;
+        helper->done = TRUE;
+
+        if (!g_subprocess_wait_check_finish ((GSubprocess*)source, result,
+                                             helper->caught_error ? NULL : helper->error))
+                helper->caught_error = TRUE;
 
-        g_spawn_close_pid (pid);
-        g_main_loop_quit (helper->loop);
+        g_clear_pointer (&helper->timeout_source, g_source_destroy);
+
+        g_main_context_wakeup (helper->maincontext);
 }
 
 static gboolean
 on_child_timeout (gpointer data)
 {
         GsmProcessHelper *helper = data;
-
-        kill (helper->pid, SIGTERM);
-        helper->timed_out = TRUE;
-        g_main_loop_quit (helper->loop);
-
+        
+        g_assert (!helper->done);
+        
+        g_subprocess_force_exit (helper->process);
+        
+        g_set_error_literal (helper->error,
+                             G_IO_CHANNEL_ERROR,
+                             G_IO_CHANNEL_ERROR_FAILED,
+                             "Timed out");
+
+        helper->timeout_source = NULL;
+        
         return FALSE;
 }
 
@@ -70,69 +76,40 @@ gsm_process_helper (const char   *command_line,
                     unsigned int  timeout,
                     GError      **error)
 {
-        GsmProcessHelper *helper;
+        gboolean ret = FALSE;
+        GsmProcessHelper helper = { 0, };
         gchar **argv = NULL;
-        GPid pid;
-        gboolean ret;
+        GMainContext *subcontext = NULL;
 
         if (!g_shell_parse_argv (command_line, NULL, &argv, error))
-                return FALSE;
-
-        ret = g_spawn_async (NULL,
-                             argv,
-                             NULL,
-                             G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD,
-                             NULL,
-                             NULL,
-                             &pid,
-                             error);
-
-        g_strfreev (argv);
+                goto out;
 
-        if (!ret)
-                return FALSE;
+        helper.error = error;
 
-        ret = FALSE;
+        subcontext = g_main_context_new ();
+        g_main_context_push_thread_default (subcontext);
 
-        helper = g_slice_new0 (GsmProcessHelper);
+        helper.process = g_subprocess_newv ((const char*const*)argv, 0, error);
+        if (!helper.process)
+                goto out;
 
-        helper->command_line = command_line;
-        helper->pid = pid;
-        helper->timed_out = FALSE;
-        helper->status = -1;
+        g_subprocess_wait_async (helper.process, NULL, on_child_exited, &helper);
 
-        helper->loop = g_main_loop_new (NULL, FALSE);
-        helper->child_id = g_child_watch_add (helper->pid, on_child_exited, helper);
-        helper->timeout_id = g_timeout_add (timeout, on_child_timeout, helper);
+        helper.timeout_source = g_timeout_source_new (timeout);
 
-        g_main_loop_run (helper->loop);
+        g_source_set_callback (helper.timeout_source, on_child_timeout, &helper, NULL);
+        g_source_attach (helper.timeout_source, subcontext);
 
-        if (helper->timed_out) {
-                g_set_error_literal (error,
-                                     G_IO_CHANNEL_ERROR,
-                                     G_IO_CHANNEL_ERROR_FAILED,
-                                     "Timed out");
-        } else {
-                if (g_spawn_check_exit_status (helper->status, error))
-                        ret = TRUE;
-        }
-
-        if (helper->loop) {
-                g_main_loop_unref (helper->loop);
-                helper->loop = NULL;
-        }
-
-        if (helper->child_id) {
-                g_source_remove (helper->child_id);
-                helper->child_id = 0;
-        }
+        while (!helper.done)
+                g_main_context_iteration (subcontext, TRUE);
 
-        if (helper->timeout_id) {
-                g_source_remove (helper->timeout_id);
-                helper->timeout_id = 0;
+        ret = helper.caught_error;
+ out:
+        g_strfreev (argv);
+        if (subcontext) {
+                g_main_context_pop_thread_default (subcontext);
+                g_main_context_unref (subcontext);
         }
-
-        g_slice_free (GsmProcessHelper, helper);
-
+        g_clear_object (&helper.process);
         return ret;
 }


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