[epiphany] main: Exit cleanly on SIGINT or SIGTERM



commit 8094d949c2c85405fbafb7ce8caeaab5469ef032
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Mon Oct 31 17:28:02 2016 -0500

    main: Exit cleanly on SIGINT or SIGTERM

 src/ephy-main.c       |   35 ++++++++++++++++++++++++++++++++++-
 src/ephy-shell.c      |    8 +++++++-
 src/ephy-shell.h      |    2 ++
 src/window-commands.c |    3 +--
 4 files changed, 44 insertions(+), 4 deletions(-)
---
diff --git a/src/ephy-main.c b/src/ephy-main.c
index 65d97ed..c6413c1 100644
--- a/src/ephy-main.c
+++ b/src/ephy-main.c
@@ -34,10 +34,12 @@
 
 #include <errno.h>
 #include <glib/gi18n.h>
+#include <glib-unix.h>
 #include <gtk/gtk.h>
 #include <libnotify/notify.h>
 #include <libxml/xmlreader.h>
 #include <libxml/xmlversion.h>
+#include <signal.h>
 #include <string.h>
 #include <stdlib.h>
 
@@ -56,6 +58,31 @@ static gboolean application_mode = FALSE;
 static char *desktop_file_basename = NULL;
 static char *profile_directory = NULL;
 
+static EphyShell *ephy_shell = NULL;
+static int shutdown_signum = 0;
+
+static gboolean
+handle_shutdown_signal (gpointer user_data)
+{
+  shutdown_signum = GPOINTER_TO_INT (user_data);
+
+  /* Note that this function executes on the main loop AFTER the signal handler
+   * has returned, so we don't have to worry about async signal safety.
+   */
+  g_assert (ephy_shell != NULL);
+  ephy_shell_try_quit (ephy_shell);
+
+  /* Goals:
+   *
+   * (1) Shutdown safely and cleanly if signal is received once.
+   * (2) Shutdown unsafely but immediately if signal is received twice.
+   * (3) Always re-raise the signal so the parent process knows what happened.
+   *
+   * Removing this source is required by goals (2) and (3).
+   */
+  return G_SOURCE_REMOVE;
+}
+
 static gboolean
 application_mode_cb (const gchar *option_name,
                      const gchar *value,
@@ -166,7 +193,6 @@ main (int   argc,
   EphyShellStartupContext *ctx;
   EphyStartupFlags startup_flags;
   EphyEmbedShellMode mode;
-  EphyShell *ephy_shell;
   int status;
   EphyFileHelpersFlags flags;
   GDesktopAppInfo *desktop_info = NULL;
@@ -400,6 +426,10 @@ main (int   argc,
   g_strfreev (arguments);
   ephy_shell = ephy_shell_get_default ();
   ephy_shell_set_startup_context (ephy_shell, ctx);
+
+  g_unix_signal_add (SIGINT, (GSourceFunc)handle_shutdown_signal, GINT_TO_POINTER (SIGINT));
+  g_unix_signal_add (SIGTERM, (GSourceFunc)handle_shutdown_signal, GINT_TO_POINTER (SIGTERM));
+
   status = g_application_run (G_APPLICATION (ephy_shell), argc, argv);
 
   /* Shutdown */
@@ -415,5 +445,8 @@ main (int   argc,
   ephy_file_helpers_shutdown ();
   xmlCleanupParser ();
 
+  if (shutdown_signum != 0)
+    raise (shutdown_signum);
+
   return status;
 }
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index ffee46f..80d8ac0 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -905,6 +905,13 @@ ephy_shell_close_all_windows (EphyShell *shell)
   return retval;
 }
 
+void
+ephy_shell_try_quit (EphyShell *shell)
+{
+  if (ephy_shell_close_all_windows (shell))
+    g_application_quit (G_APPLICATION (shell));
+}
+
 typedef struct {
   EphyShell *shell;
   EphySession *session;
@@ -1054,4 +1061,3 @@ ephy_shell_open_uris (EphyShell       *shell,
 
   shell->open_uris_idle_ids = g_slist_prepend (shell->open_uris_idle_ids, GUINT_TO_POINTER (id));
 }
-
diff --git a/src/ephy-shell.h b/src/ephy-shell.h
index 74fd039..31d763f 100644
--- a/src/ephy-shell.h
+++ b/src/ephy-shell.h
@@ -112,6 +112,8 @@ guint           ephy_shell_get_n_windows                (EphyShell *shell);
 
 gboolean        ephy_shell_close_all_windows            (EphyShell *shell);
 
+void            ephy_shell_try_quit                     (EphyShell *shell);
+
 void            ephy_shell_open_uris                    (EphyShell *shell,
                                                          const char **uris,
                                                          EphyStartupFlags startup_flags,
diff --git a/src/window-commands.c b/src/window-commands.c
index 4011382..f48597c 100644
--- a/src/window-commands.c
+++ b/src/window-commands.c
@@ -283,8 +283,7 @@ window_cmd_quit (GSimpleAction *action,
                  GVariant      *parameter,
                  gpointer       user_data)
 {
-  if (ephy_shell_close_all_windows (ephy_shell_get_default ()))
-    g_application_quit (g_application_get_default ());
+  ephy_shell_try_quit (ephy_shell_get_default ());
 }
 
 void


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