gnome-session r4957 - in trunk: . gnome-session
- From: mccann svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-session r4957 - in trunk: . gnome-session
- Date: Fri, 15 Aug 2008 16:37:43 +0000 (UTC)
Author: mccann
Date: Fri Aug 15 16:37:43 2008
New Revision: 4957
URL: http://svn.gnome.org/viewvc/gnome-session?rev=4957&view=rev
Log:
2008-08-15 William Jon McCann <jmccann redhat com>
* gnome-session/Makefile.am:
* gnome-session/gdm-signal-handler.c (block_signals_push),
(block_signals_pop), (signal_io_watch), (fallback_get_backtrace),
(crashlogger_get_backtrace), (gdm_signal_handler_backtrace),
(signal_handler), (catch_signal), (uncatch_signal),
(gdm_signal_handler_add), (gdm_signal_handler_add_fatal),
(callback_data_free), (gdm_signal_handler_remove_and_free_data),
(gdm_signal_handler_remove), (find_callback_data_by_func),
(gdm_signal_handler_remove_func), (gdm_signal_handler_class_init),
(signal_list_free), (gdm_signal_handler_set_main_loop),
(gdm_signal_handler_init), (gdm_signal_handler_finalize),
(gdm_signal_handler_new):
* gnome-session/gdm-signal-handler.h:
* gnome-session/gsm-manager.c (gsm_manager_dispose),
(gsm_manager_class_init), (gsm_manager_finalize):
* gnome-session/main.c (signal_cb), (main):
Add signal handling framework.
Added:
trunk/gnome-session/gdm-signal-handler.c
trunk/gnome-session/gdm-signal-handler.h
Modified:
trunk/ChangeLog
trunk/gnome-session/Makefile.am
trunk/gnome-session/gsm-manager.c
trunk/gnome-session/main.c
Modified: trunk/gnome-session/Makefile.am
==============================================================================
--- trunk/gnome-session/Makefile.am (original)
+++ trunk/gnome-session/Makefile.am Fri Aug 15 16:37:43 2008
@@ -20,6 +20,7 @@
-DLOCALE_DIR=\""$(datadir)/locale"\" \
-DDATA_DIR=\""$(datadir)/gnome-session"\" \
-DDBUS_LAUNCH=\"dbus-launch\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
-DGLADEDIR=\""$(pkgdatadir)"\" \
-DGCONF_SANITY_CHECK=\""$(GCONF_SANITY_CHECK)"\" \
-DGCONFTOOL_CMD=\"$(GCONFTOOL)\"
@@ -78,6 +79,8 @@
gsm-gconf.h \
gdm.h \
gdm.c \
+ gdm-signal-handler.h \
+ gdm-signal-handler.c \
main.c \
gsm-store.h \
gsm-store.c \
Added: trunk/gnome-session/gdm-signal-handler.c
==============================================================================
--- (empty file)
+++ trunk/gnome-session/gdm-signal-handler.c Fri Aug 15 16:37:43 2008
@@ -0,0 +1,540 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006 Red Hat, Inc.
+ * Copyright (C) 2007 William Jon McCann <mccann jhu edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <execinfo.h>
+#include <syslog.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <glib-object.h>
+
+#include "gdm-signal-handler.h"
+
+#define GDM_SIGNAL_HANDLER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SIGNAL_HANDLER, GdmSignalHandlerPrivate))
+
+typedef struct {
+ int signal_number;
+ GdmSignalHandlerFunc func;
+ gpointer data;
+ guint id;
+} CallbackData;
+
+struct GdmSignalHandlerPrivate
+{
+ GMainLoop *main_loop;
+ GHashTable *lookup;
+ GHashTable *id_lookup;
+ GHashTable *action_lookup;
+ guint next_id;
+};
+
+static void gdm_signal_handler_class_init (GdmSignalHandlerClass *klass);
+static void gdm_signal_handler_init (GdmSignalHandler *signal_handler);
+static void gdm_signal_handler_finalize (GObject *object);
+
+static gpointer signal_handler_object = NULL;
+static int signal_pipes[2];
+static int signals_blocked = 0;
+static sigset_t signals_block_mask;
+static sigset_t signals_oldmask;
+
+G_DEFINE_TYPE (GdmSignalHandler, gdm_signal_handler, G_TYPE_OBJECT)
+
+static void
+block_signals_push (void)
+{
+ signals_blocked++;
+
+ if (signals_blocked == 1) {
+ /* Set signal mask */
+ sigemptyset (&signals_block_mask);
+ sigfillset (&signals_block_mask);
+ sigprocmask (SIG_BLOCK, &signals_block_mask, &signals_oldmask);
+ }
+}
+
+static void
+block_signals_pop (void)
+{
+ signals_blocked--;
+
+ if (signals_blocked == 0) {
+ /* Set signal mask */
+ sigprocmask (SIG_SETMASK, &signals_oldmask, NULL);
+ }
+}
+
+static gboolean
+signal_io_watch (GIOChannel *ioc,
+ GIOCondition condition,
+ GdmSignalHandler *handler)
+{
+ char buf[256];
+ gboolean is_fatal;
+ gsize bytes_read;
+ int i;
+
+ block_signals_push ();
+
+ g_io_channel_read_chars (ioc, buf, sizeof (buf), &bytes_read, NULL);
+
+ is_fatal = FALSE;
+
+ for (i = 0; i < bytes_read; i++) {
+ int signum;
+ GSList *handlers;
+ GSList *l;
+
+ signum = (gint32)buf[i];
+
+ g_debug ("GdmSignalHandler: handling signal %d", signum);
+ handlers = g_hash_table_lookup (handler->priv->lookup, GINT_TO_POINTER (signum));
+
+ g_debug ("GdmSignalHandler: Found %u callbacks", g_slist_length (handlers));
+ for (l = handlers; l != NULL; l = l->next) {
+ gboolean res;
+ CallbackData *data;
+
+ data = g_hash_table_lookup (handler->priv->id_lookup, l->data);
+ if (data != NULL) {
+ if (data->func != NULL) {
+ g_debug ("GdmSignalHandler: running %d handler: %p", signum, data->func);
+ res = data->func (signum, data->data);
+ if (! res) {
+ is_fatal = TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ block_signals_pop ();
+
+ if (is_fatal) {
+ g_debug ("GdmSignalHandler: Caught termination signal - exiting main loop");
+ if (handler->priv->main_loop != NULL) {
+ g_main_loop_quit (handler->priv->main_loop);
+ } else {
+ exit (1);
+ }
+
+ return FALSE;
+ }
+
+ g_debug ("GdmSignalHandler: Done handling signals");
+
+ return TRUE;
+}
+
+static void
+fallback_get_backtrace (void)
+{
+ void * frames[64];
+ size_t size;
+ char ** strings;
+ size_t i;
+
+ size = backtrace (frames, G_N_ELEMENTS (frames));
+ if ((strings = backtrace_symbols (frames, size))) {
+ syslog (LOG_CRIT, "******************* START ********************************");
+ for (i = 0; i < size; i++) {
+ syslog (LOG_CRIT, "Frame %zd: %s", i, strings[i]);
+ }
+ free (strings);
+ syslog (LOG_CRIT, "******************* END **********************************");
+ } else {
+ g_warning ("GDM crashed, but symbols couldn't be retrieved.");
+ }
+}
+
+
+static gboolean
+crashlogger_get_backtrace (void)
+{
+ gboolean success = FALSE;
+ int pid;
+
+ pid = fork ();
+ if (pid > 0) {
+ /* Wait for the child to finish */
+ int estatus;
+ if (waitpid (pid, &estatus, 0) != -1) {
+ /* Only succeed if the crashlogger succeeded */
+ if (WIFEXITED (estatus) && (WEXITSTATUS (estatus) == 0)) {
+ success = TRUE;
+ }
+ }
+ } else if (pid == 0) {
+ /* Child process */
+ execl (LIBEXECDIR "/gdm-crash-logger",
+ LIBEXECDIR "/gdm-crash-logger", NULL);
+ }
+
+ return success;
+}
+
+
+static void
+gdm_signal_handler_backtrace (void)
+{
+ struct stat s;
+ gboolean fallback = TRUE;
+
+ /* Try to use gdb via gdm-crash-logger if it exists, since
+ * we get much better information out of it. Otherwise
+ * fall back to execinfo.
+ */
+ if (g_stat (LIBEXECDIR "/gdm-crash-logger", &s) == 0) {
+ fallback = crashlogger_get_backtrace () ? FALSE : TRUE;
+ }
+
+ if (fallback) {
+ fallback_get_backtrace ();
+ }
+}
+
+static void
+signal_handler (int signo)
+{
+ static int in_fatal = 0;
+ int ignore;
+ guchar signo_byte = signo;
+
+ /* avoid loops */
+ if (in_fatal > 0) {
+ return;
+ }
+
+ ++in_fatal;
+
+ switch (signo) {
+ case SIGSEGV:
+ case SIGBUS:
+ case SIGILL:
+ case SIGABRT:
+ case SIGTRAP:
+ gdm_signal_handler_backtrace ();
+ exit (1);
+ break;
+ case SIGFPE:
+ case SIGPIPE:
+ /* let the fatal signals interrupt us */
+ --in_fatal;
+ gdm_signal_handler_backtrace ();
+ ignore = write (signal_pipes [1], &signo_byte, 1);
+ break;
+ default:
+ --in_fatal;
+ ignore = write (signal_pipes [1], &signo_byte, 1);
+ break;
+ }
+}
+
+static void
+catch_signal (GdmSignalHandler *handler,
+ int signal_number)
+{
+ struct sigaction action;
+ struct sigaction *old_action;
+
+ g_debug ("GdmSignalHandler: Registering for %d signals", signal_number);
+
+ action.sa_handler = signal_handler;
+ sigemptyset (&action.sa_mask);
+ action.sa_flags = 0;
+
+ old_action = g_new0 (struct sigaction, 1);
+
+ sigaction (signal_number, &action, old_action);
+
+ g_hash_table_insert (handler->priv->action_lookup,
+ GINT_TO_POINTER (signal_number),
+ old_action);
+}
+
+static void
+uncatch_signal (GdmSignalHandler *handler,
+ int signal_number)
+{
+ struct sigaction *old_action;
+
+ g_debug ("GdmSignalHandler: Unregistering for %d signals", signal_number);
+
+ old_action = g_hash_table_lookup (handler->priv->action_lookup,
+ GINT_TO_POINTER (signal_number));
+ g_hash_table_remove (handler->priv->action_lookup,
+ GINT_TO_POINTER (signal_number));
+
+ sigaction (signal_number, old_action, NULL);
+
+ g_free (old_action);
+}
+
+guint
+gdm_signal_handler_add (GdmSignalHandler *handler,
+ int signal_number,
+ GdmSignalHandlerFunc callback,
+ gpointer data)
+{
+ CallbackData *cdata;
+ GSList *list;
+
+ g_return_val_if_fail (GDM_IS_SIGNAL_HANDLER (handler), 0);
+
+ cdata = g_new0 (CallbackData, 1);
+ cdata->signal_number = signal_number;
+ cdata->func = callback;
+ cdata->data = data;
+ cdata->id = handler->priv->next_id++;
+
+ g_debug ("GdmSignalHandler: Adding handler %u: signum=%d %p", cdata->id, cdata->signal_number, cdata->func);
+
+ if (g_hash_table_lookup (handler->priv->action_lookup, GINT_TO_POINTER (signal_number)) == NULL) {
+ catch_signal (handler, signal_number);
+ }
+
+ /* ID lookup owns the CallbackData */
+ g_hash_table_insert (handler->priv->id_lookup, GUINT_TO_POINTER (cdata->id), cdata);
+
+ list = g_hash_table_lookup (handler->priv->lookup, GINT_TO_POINTER (signal_number));
+ list = g_slist_prepend (list, GUINT_TO_POINTER (cdata->id));
+
+ g_hash_table_insert (handler->priv->lookup, GINT_TO_POINTER (signal_number), list);
+
+ return cdata->id;
+}
+
+void
+gdm_signal_handler_add_fatal (GdmSignalHandler *handler)
+{
+ g_return_if_fail (GDM_IS_SIGNAL_HANDLER (handler));
+
+ gdm_signal_handler_add (handler, SIGILL, NULL, NULL);
+ gdm_signal_handler_add (handler, SIGBUS, NULL, NULL);
+ gdm_signal_handler_add (handler, SIGSEGV, NULL, NULL);
+ gdm_signal_handler_add (handler, SIGABRT, NULL, NULL);
+ gdm_signal_handler_add (handler, SIGTRAP, NULL, NULL);
+}
+
+static void
+callback_data_free (CallbackData *d)
+{
+ g_free (d);
+}
+
+static void
+gdm_signal_handler_remove_and_free_data (GdmSignalHandler *handler,
+ CallbackData *cdata)
+{
+ GSList *list;
+
+ g_return_if_fail (GDM_IS_SIGNAL_HANDLER (handler));
+
+ list = g_hash_table_lookup (handler->priv->lookup, GINT_TO_POINTER (cdata->signal_number));
+ list = g_slist_remove_all (list, GUINT_TO_POINTER (cdata->id));
+ if (list == NULL) {
+ uncatch_signal (handler, cdata->signal_number);
+ }
+
+ g_debug ("GdmSignalHandler: Removing handler %u: signum=%d %p", cdata->signal_number, cdata->id, cdata->func);
+ /* put changed list back in */
+ g_hash_table_insert (handler->priv->lookup, GINT_TO_POINTER (cdata->signal_number), list);
+
+ g_hash_table_remove (handler->priv->id_lookup, GUINT_TO_POINTER (cdata->id));
+}
+
+void
+gdm_signal_handler_remove (GdmSignalHandler *handler,
+ guint id)
+{
+ CallbackData *found;
+
+ g_return_if_fail (GDM_IS_SIGNAL_HANDLER (handler));
+
+ found = g_hash_table_lookup (handler->priv->id_lookup, GUINT_TO_POINTER (id));
+ if (found != NULL) {
+ gdm_signal_handler_remove_and_free_data (handler, found);
+ found = NULL;
+ }
+}
+
+static CallbackData *
+find_callback_data_by_func (GdmSignalHandler *handler,
+ guint signal_number,
+ GdmSignalHandlerFunc callback,
+ gpointer data)
+{
+ GSList *list;
+ GSList *l;
+ CallbackData *found;
+
+ found = NULL;
+
+ list = g_hash_table_lookup (handler->priv->lookup, GINT_TO_POINTER (signal_number));
+
+ for (l = list; l != NULL; l = l->next) {
+ guint id;
+ CallbackData *d;
+
+ id = GPOINTER_TO_UINT (l->data);
+
+ d = g_hash_table_lookup (handler->priv->id_lookup, GUINT_TO_POINTER (id));
+ if (d != NULL
+ && d->func == callback
+ && d->data == data) {
+ found = d;
+ break;
+ }
+ }
+
+ return found;
+}
+
+void
+gdm_signal_handler_remove_func (GdmSignalHandler *handler,
+ guint signal_number,
+ GdmSignalHandlerFunc callback,
+ gpointer data)
+{
+ CallbackData *found;
+
+ g_return_if_fail (GDM_IS_SIGNAL_HANDLER (handler));
+
+ found = find_callback_data_by_func (handler, signal_number, callback, data);
+
+ if (found != NULL) {
+ gdm_signal_handler_remove_and_free_data (handler, found);
+ found = NULL;
+ }
+
+ /* FIXME: once all handlers are removed deregister signum handler */
+}
+
+static void
+gdm_signal_handler_class_init (GdmSignalHandlerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gdm_signal_handler_finalize;
+
+ g_type_class_add_private (klass, sizeof (GdmSignalHandlerPrivate));
+}
+
+static void
+signal_list_free (GSList *list)
+{
+ g_slist_free (list);
+}
+
+void
+gdm_signal_handler_set_main_loop (GdmSignalHandler *handler,
+ GMainLoop *main_loop)
+{
+ g_return_if_fail (GDM_IS_SIGNAL_HANDLER (handler));
+
+ /* FIXME: take a ref */
+ handler->priv->main_loop = main_loop;
+}
+
+static void
+gdm_signal_handler_init (GdmSignalHandler *handler)
+{
+ GIOChannel *ioc;
+
+ handler->priv = GDM_SIGNAL_HANDLER_GET_PRIVATE (handler);
+
+ handler->priv->next_id = 1;
+
+ handler->priv->lookup = g_hash_table_new (NULL, NULL);
+ handler->priv->id_lookup = g_hash_table_new (NULL, NULL);
+ handler->priv->action_lookup = g_hash_table_new (NULL, NULL);
+
+ if (pipe (signal_pipes) == -1) {
+ g_error ("Could not create pipe() for signal handling");
+ }
+
+ ioc = g_io_channel_unix_new (signal_pipes[0]);
+ g_io_channel_set_flags (ioc, G_IO_FLAG_NONBLOCK, NULL);
+ g_io_add_watch (ioc, G_IO_IN, (GIOFunc)signal_io_watch, handler);
+ g_io_channel_set_close_on_unref (ioc, TRUE);
+ g_io_channel_unref (ioc);
+}
+
+static void
+gdm_signal_handler_finalize (GObject *object)
+{
+ GdmSignalHandler *handler;
+ GList *l;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GDM_IS_SIGNAL_HANDLER (object));
+
+ handler = GDM_SIGNAL_HANDLER (object);
+
+ g_debug ("GdmSignalHandler: Finalizing signal handler");
+
+ g_return_if_fail (handler->priv != NULL);
+ for (l = g_hash_table_get_values (handler->priv->lookup);
+ l != NULL; l = l->next) {
+ signal_list_free ((GSList *) l->data);
+ }
+ g_hash_table_destroy (handler->priv->lookup);
+ for (l = g_hash_table_get_values (handler->priv->id_lookup);
+ l != NULL; l = l->next) {
+ callback_data_free ((CallbackData *) l->data);
+ }
+ g_hash_table_destroy (handler->priv->id_lookup);
+ for (l = g_hash_table_get_values (handler->priv->action_lookup);
+ l != NULL; l = l->next) {
+ g_free (l->data);
+ }
+ g_hash_table_destroy (handler->priv->action_lookup);
+
+ close (signal_pipes [0]);
+ close (signal_pipes [1]);
+
+ G_OBJECT_CLASS (gdm_signal_handler_parent_class)->finalize (object);
+}
+
+GdmSignalHandler *
+gdm_signal_handler_new (void)
+{
+ if (signal_handler_object != NULL) {
+ g_object_ref (signal_handler_object);
+ } else {
+ signal_handler_object = g_object_new (GDM_TYPE_SIGNAL_HANDLER, NULL);
+ g_object_add_weak_pointer (signal_handler_object,
+ (gpointer *) &signal_handler_object);
+ }
+
+ return GDM_SIGNAL_HANDLER (signal_handler_object);
+}
Added: trunk/gnome-session/gdm-signal-handler.h
==============================================================================
--- (empty file)
+++ trunk/gnome-session/gdm-signal-handler.h Fri Aug 15 16:37:43 2008
@@ -0,0 +1,74 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <mccann jhu edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef __GDM_SIGNAL_HANDLER_H
+#define __GDM_SIGNAL_HANDLER_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GDM_TYPE_SIGNAL_HANDLER (gdm_signal_handler_get_type ())
+#define GDM_SIGNAL_HANDLER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_SIGNAL_HANDLER, GdmSignalHandler))
+#define GDM_SIGNAL_HANDLER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_SIGNAL_HANDLER, GdmSignalHandlerClass))
+#define GDM_IS_SIGNAL_HANDLER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_SIGNAL_HANDLER))
+#define GDM_IS_SIGNAL_HANDLER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_SIGNAL_HANDLER))
+#define GDM_SIGNAL_HANDLER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_SIGNAL_HANDLER, GdmSignalHandlerClass))
+
+
+typedef gboolean (*GdmSignalHandlerFunc) (int signal,
+ gpointer data);
+
+typedef struct GdmSignalHandlerPrivate GdmSignalHandlerPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GdmSignalHandlerPrivate *priv;
+} GdmSignalHandler;
+
+typedef struct
+{
+ GObjectClass parent_class;
+} GdmSignalHandlerClass;
+
+GType gdm_signal_handler_get_type (void);
+
+GdmSignalHandler * gdm_signal_handler_new (void);
+void gdm_signal_handler_set_main_loop (GdmSignalHandler *handler,
+ GMainLoop *main_loop);
+
+void gdm_signal_handler_add_fatal (GdmSignalHandler *handler);
+guint gdm_signal_handler_add (GdmSignalHandler *handler,
+ int signal_number,
+ GdmSignalHandlerFunc callback,
+ gpointer data);
+void gdm_signal_handler_remove (GdmSignalHandler *handler,
+ guint id);
+void gdm_signal_handler_remove_func (GdmSignalHandler *handler,
+ guint signal_number,
+ GdmSignalHandlerFunc callback,
+ gpointer data);
+
+
+G_END_DECLS
+
+#endif /* __GDM_SIGNAL_HANDLER_H */
Modified: trunk/gnome-session/gsm-manager.c
==============================================================================
--- trunk/gnome-session/gsm-manager.c (original)
+++ trunk/gnome-session/gsm-manager.c Fri Aug 15 16:37:43 2008
@@ -1710,6 +1710,30 @@
}
static void
+gsm_manager_dispose (GObject *object)
+{
+ GsmManager *manager = GSM_MANAGER (object);
+
+ g_debug ("GsmManager: disposing manager");
+
+ if (manager->priv->clients != NULL) {
+ g_object_unref (manager->priv->clients);
+ manager->priv->clients = NULL;
+ }
+
+ if (manager->priv->apps != NULL) {
+ g_object_unref (manager->priv->apps);
+ manager->priv->apps = NULL;
+ }
+
+ if (manager->priv->inhibitors != NULL) {
+ g_object_unref (manager->priv->inhibitors);
+ manager->priv->inhibitors = NULL;
+ }
+
+}
+
+static void
gsm_manager_class_init (GsmManagerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -1718,6 +1742,7 @@
object_class->set_property = gsm_manager_set_property;
object_class->constructor = gsm_manager_constructor;
object_class->finalize = gsm_manager_finalize;
+ object_class->dispose = gsm_manager_dispose;
signals [PHASE_CHANGED] =
g_signal_new ("phase-changed",
@@ -1861,18 +1886,6 @@
g_return_if_fail (manager->priv != NULL);
- if (manager->priv->clients != NULL) {
- g_object_unref (manager->priv->clients);
- }
-
- if (manager->priv->apps != NULL) {
- g_object_unref (manager->priv->apps);
- }
-
- if (manager->priv->inhibitors != NULL) {
- g_object_unref (manager->priv->inhibitors);
- }
-
G_OBJECT_CLASS (gsm_manager_parent_class)->finalize (object);
}
Modified: trunk/gnome-session/main.c
==============================================================================
--- trunk/gnome-session/main.c (original)
+++ trunk/gnome-session/main.c Fri Aug 15 16:37:43 2008
@@ -35,6 +35,8 @@
#include <dbus/dbus-glib-bindings.h>
#include <dbus/dbus-glib-lowlevel.h>
+#include "gdm-signal-handler.h"
+
#include "gsm-gconf.h"
#include "gsm-util.h"
#include "gsm-manager.h"
@@ -342,15 +344,58 @@
}
}
+static gboolean
+signal_cb (int signo,
+ gpointer data)
+{
+ int ret;
+
+ g_debug ("Got callback for signal %d", signo);
+
+ ret = TRUE;
+
+ switch (signo) {
+ case SIGFPE:
+ case SIGPIPE:
+ /* let the fatal signals interrupt us */
+ g_debug ("Caught signal %d, shutting down abnormally.", signo);
+ ret = FALSE;
+ break;
+ case SIGINT:
+ case SIGTERM:
+ /* let the fatal signals interrupt us */
+ g_debug ("Caught signal %d, shutting down normally.", signo);
+ ret = FALSE;
+ break;
+ case SIGHUP:
+ g_debug ("Got HUP signal");
+ ret = TRUE;
+ break;
+ case SIGUSR1:
+ g_debug ("Got USR1 signal");
+ ret = TRUE;
+ /*gdm_log_toggle_debug (); */
+ break;
+ default:
+ g_debug ("Caught unhandled signal %d", signo);
+ ret = TRUE;
+
+ break;
+ }
+
+ return ret;
+}
+
int
main (int argc, char **argv)
{
- struct sigaction sa;
- GError *error;
- char *display_str;
- GsmManager *manager;
- GsmStore *client_store;
- GsmXsmpServer *xsmp_server;
+ struct sigaction sa;
+ GError *error;
+ char *display_str;
+ GsmManager *manager;
+ GsmStore *client_store;
+ GsmXsmpServer *xsmp_server;
+ GdmSignalHandler *signal_handler;
bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
@@ -376,6 +421,14 @@
exit (1);
}
+ signal_handler = gdm_signal_handler_new ();
+ gdm_signal_handler_add_fatal (signal_handler);
+ gdm_signal_handler_add (signal_handler, SIGTERM, signal_cb, NULL);
+ gdm_signal_handler_add (signal_handler, SIGINT, signal_cb, NULL);
+ gdm_signal_handler_add (signal_handler, SIGFPE, signal_cb, NULL);
+ gdm_signal_handler_add (signal_handler, SIGHUP, signal_cb, NULL);
+ gdm_signal_handler_add (signal_handler, SIGUSR1, signal_cb, NULL);
+
/* Set DISPLAY explicitly for all our children, in case --display
* was specified on the command line.
*/
@@ -419,5 +472,9 @@
g_object_unref (manager);
}
+ if (client_store != NULL) {
+ g_object_unref (client_store);
+ }
+
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]