From f90d079858c12c92f3d1bca433d8b2314cd2df36 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 17 Feb 2009 10:42:25 -0500 Subject: [PATCH] system-settings: fix shutdown issues Shutdown on SIGTERM, and don't segfault when quitting cleanly. Can't send signals on an object that's being disposed of, so don't do that. Fix a memory leak of the Hal manager's priv->devices on shutdown, not that it matters. --- system-settings/src/main.c | 46 ++++++++++++--- .../src/nm-system-config-hal-manager.c | 57 +++++++++++-------- 2 files changed, 69 insertions(+), 34 deletions(-) diff --git a/system-settings/src/main.c b/system-settings/src/main.c index d308c44ac..105da6e9a 100644 --- a/system-settings/src/main.c +++ b/system-settings/src/main.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -49,6 +50,9 @@ #include "nm-system-config-hal-manager.h" #include "nm-system-config-interface.h" +static GMainLoop *loop = NULL; +static gboolean debug = FALSE; + typedef struct { DBusConnection *connection; DBusGConnection *g_connection; @@ -57,13 +61,13 @@ typedef struct { NMSystemConfigHalManager *hal_mgr; NMSysconfigSettings *settings; - GMainLoop *loop; GHashTable *wired_devices; } Application; NMSystemConfigHalManager *nm_system_config_hal_manager_get (DBusGConnection *g_connection); +void nm_system_config_hal_manager_shutdown (NMSystemConfigHalManager *self); static gboolean dbus_init (Application *app); static gboolean start_dbus_service (Application *app); @@ -194,7 +198,7 @@ load_stuff (gpointer user_data) g_slist_free (devs); if (!start_dbus_service (app)) { - g_main_loop_quit (app->loop); + g_main_loop_quit (loop); return FALSE; } @@ -461,11 +465,9 @@ dbus_cleanup (Application *app) static void destroy_cb (DBusGProxy *proxy, gpointer user_data) { - Application *app = (Application *) user_data; - /* Clean up existing connection */ g_warning ("disconnected from the system bus, exiting."); - g_main_loop_quit (app->loop); + g_main_loop_quit (loop); } static gboolean @@ -608,6 +610,30 @@ logging_shutdown (void) closelog (); } +static void +signal_handler (int signo) +{ + if (signo == SIGINT || signo == SIGTERM) { + if (debug) + g_message ("Caught signal %d, shutting down...", signo); + g_main_loop_quit (loop); + } +} + +static void +setup_signals (void) +{ + struct sigaction action; + sigset_t mask; + + sigemptyset (&mask); + action.sa_handler = signal_handler; + action.sa_mask = mask; + action.sa_flags = 0; + sigaction (SIGTERM, &action, NULL); + sigaction (SIGINT, &action, NULL); +} + int main (int argc, char **argv) { @@ -616,7 +642,6 @@ main (int argc, char **argv) GError *error = NULL; char *plugins = NULL; char *config = NULL; - gboolean debug = FALSE; GOptionEntry entries[] = { { "config", 0, 0, G_OPTION_ARG_FILENAME, &config, "Config file location", "/path/to/config.file" }, @@ -656,7 +681,7 @@ main (int argc, char **argv) return 1; } - app->loop = g_main_loop_new (NULL, FALSE); + loop = g_main_loop_new (NULL, FALSE); if (!debug) logging_setup (); @@ -682,15 +707,18 @@ main (int argc, char **argv) } g_free (plugins); + setup_signals (); + g_idle_add (load_stuff, app); - g_main_loop_run (app->loop); + g_main_loop_run (loop); - g_object_unref (app->settings); + nm_system_config_hal_manager_shutdown (app->hal_mgr); g_object_unref (app->hal_mgr); g_hash_table_destroy (app->wired_devices); + g_object_unref (app->settings); dbus_cleanup (app); if (!debug) diff --git a/system-settings/src/nm-system-config-hal-manager.c b/system-settings/src/nm-system-config-hal-manager.c index 64eff00bd..fc5c23cd8 100644 --- a/system-settings/src/nm-system-config-hal-manager.c +++ b/system-settings/src/nm-system-config-hal-manager.c @@ -30,6 +30,8 @@ NMSystemConfigHalManager *nm_system_config_hal_manager_get (DBusGConnection *g_connection); +void nm_system_config_hal_manager_shutdown (NMSystemConfigHalManager *self); + #define NUM_DEVICE_TYPES NM_DEVICE_TYPE_CDMA typedef struct { @@ -221,30 +223,6 @@ init_dbus (NMSystemConfigHalManager *manager, DBusGConnection *g_connection) return TRUE; } -static void -remove_all_devices (gpointer key, gpointer data, gpointer user_data) -{ - NMSystemConfigHalManager *manager = NM_SYSTEM_CONFIG_HAL_MANAGER (user_data); - - g_signal_emit (manager, signals[DEVICE_REMOVED], 0, key, GPOINTER_TO_UINT (data)); -} - -static void -cleanup_dbus (NMSystemConfigHalManager *manager) -{ - NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager); - - g_hash_table_foreach (priv->devices, (GHFunc) remove_all_devices, manager); - g_hash_table_remove_all (priv->devices); - - if (priv->proxy) { - g_object_unref (priv->proxy); - priv->proxy = NULL; - } - - priv->g_connection = NULL; -} - static NMSystemConfigHalManager * nm_system_config_hal_manager_new (DBusGConnection *g_connection) { @@ -283,10 +261,39 @@ nm_system_config_hal_manager_init (NMSystemConfigHalManager *manager) priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); } +static void +signal_removed (gpointer key, gpointer data, gpointer user_data) +{ + NMSystemConfigHalManager *manager = NM_SYSTEM_CONFIG_HAL_MANAGER (user_data); + + g_signal_emit (manager, signals[DEVICE_REMOVED], 0, key, GPOINTER_TO_UINT (data)); +} + +void +nm_system_config_hal_manager_shutdown (NMSystemConfigHalManager *self) +{ + NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (self); + + g_hash_table_foreach (priv->devices, (GHFunc) signal_removed, self); + g_hash_table_remove_all (priv->devices); +} + static void dispose (GObject *object) { - cleanup_dbus (NM_SYSTEM_CONFIG_HAL_MANAGER (object)); + NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (object); + + if (priv->devices) { + g_hash_table_remove_all (priv->devices); + g_hash_table_destroy (priv->devices); + } + + if (priv->proxy) { + g_object_unref (priv->proxy); + priv->proxy = NULL; + } + + priv->g_connection = NULL; G_OBJECT_CLASS (nm_system_config_hal_manager_parent_class)->dispose (object); }