[gnome-session] GsmProcessHelper: Port to GSubprocess
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-session] GsmProcessHelper: Port to GSubprocess
- Date: Tue, 5 Nov 2013 15:20:03 +0000 (UTC)
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]