[metacity] Don't call meta_finalize from SIGTERM handler



commit ec7a3c516d36921d49fc757d6afae5e88731f47f
Author: Ray Strode <rstrode redhat com>
Date:   Thu Nov 5 14:47:47 2009 -0500

    Don't call meta_finalize from SIGTERM handler
    
    It's not a legal function to call from a signal handler.
    Instead defer until going back to the main loop.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=600864

 src/core/main.c |   28 ++++++++++++++++++++++++++--
 1 files changed, 26 insertions(+), 2 deletions(-)
---
diff --git a/src/core/main.c b/src/core/main.c
index a36a396..509c650 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -67,6 +67,7 @@
 #include <fcntl.h>
 #include <locale.h>
 #include <time.h>
+#include <unistd.h>
 
 /**
  * The exit code we'll return to our parent process when we eventually die.
@@ -369,12 +370,24 @@ meta_finalize (void)
                         CurrentTime); /* I doubt correct timestamps matter here */
 }
 
+static int sigterm_pipe_fds[2] = { -1, -1 };
+
 static void
 sigterm_handler (int signum)
 {
-  meta_finalize ();
+  if (sigterm_pipe_fds[1] >= 0)
+    {
+      write (sigterm_pipe_fds[1], "", 1);
+      close (sigterm_pipe_fds[1]);
+      sigterm_pipe_fds[1] = -1;
+    }
+}
 
-  exit (meta_exit_code);
+static gboolean
+on_sigterm (void)
+{
+  meta_quit (META_EXIT_SUCCESS);
+  return FALSE;
 }
 
 static guint sigchld_signal_id = 0;
@@ -422,6 +435,7 @@ main (int argc, char **argv)
     "Pango", "GLib-GObject", "GThread"
   };
   guint i;
+  GIOChannel *channel;
 
   if (!g_thread_supported ())
     g_thread_init (NULL);
@@ -444,6 +458,16 @@ main (int argc, char **argv)
                 g_strerror (errno));
 #endif
 
+  if (pipe (sigterm_pipe_fds) != 0)
+    g_printerr ("Failed to create SIGTERM pipe: %s\n",
+                g_strerror (errno));
+
+  channel = g_io_channel_unix_new (sigterm_pipe_fds[0]);
+  g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL);
+  g_io_add_watch (channel, G_IO_IN, (GIOFunc) on_sigterm, NULL);
+  g_io_channel_set_close_on_unref (channel, TRUE);
+  g_io_channel_unref (channel);
+
   act.sa_handler = &sigterm_handler;
   if (sigaction (SIGTERM, &act, NULL) < 0)
     g_printerr ("Failed to register SIGTERM handler: %s\n",



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