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.
This commit is contained in:
@@ -28,6 +28,7 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netinet/ether.h>
|
#include <netinet/ether.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
@@ -49,6 +50,9 @@
|
|||||||
#include "nm-system-config-hal-manager.h"
|
#include "nm-system-config-hal-manager.h"
|
||||||
#include "nm-system-config-interface.h"
|
#include "nm-system-config-interface.h"
|
||||||
|
|
||||||
|
static GMainLoop *loop = NULL;
|
||||||
|
static gboolean debug = FALSE;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DBusConnection *connection;
|
DBusConnection *connection;
|
||||||
DBusGConnection *g_connection;
|
DBusGConnection *g_connection;
|
||||||
@@ -57,13 +61,13 @@ typedef struct {
|
|||||||
NMSystemConfigHalManager *hal_mgr;
|
NMSystemConfigHalManager *hal_mgr;
|
||||||
|
|
||||||
NMSysconfigSettings *settings;
|
NMSysconfigSettings *settings;
|
||||||
GMainLoop *loop;
|
|
||||||
|
|
||||||
GHashTable *wired_devices;
|
GHashTable *wired_devices;
|
||||||
} Application;
|
} Application;
|
||||||
|
|
||||||
|
|
||||||
NMSystemConfigHalManager *nm_system_config_hal_manager_get (DBusGConnection *g_connection);
|
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 dbus_init (Application *app);
|
||||||
static gboolean start_dbus_service (Application *app);
|
static gboolean start_dbus_service (Application *app);
|
||||||
@@ -194,7 +198,7 @@ load_stuff (gpointer user_data)
|
|||||||
g_slist_free (devs);
|
g_slist_free (devs);
|
||||||
|
|
||||||
if (!start_dbus_service (app)) {
|
if (!start_dbus_service (app)) {
|
||||||
g_main_loop_quit (app->loop);
|
g_main_loop_quit (loop);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,11 +465,9 @@ dbus_cleanup (Application *app)
|
|||||||
static void
|
static void
|
||||||
destroy_cb (DBusGProxy *proxy, gpointer user_data)
|
destroy_cb (DBusGProxy *proxy, gpointer user_data)
|
||||||
{
|
{
|
||||||
Application *app = (Application *) user_data;
|
|
||||||
|
|
||||||
/* Clean up existing connection */
|
/* Clean up existing connection */
|
||||||
g_warning ("disconnected from the system bus, exiting.");
|
g_warning ("disconnected from the system bus, exiting.");
|
||||||
g_main_loop_quit (app->loop);
|
g_main_loop_quit (loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -608,6 +610,30 @@ logging_shutdown (void)
|
|||||||
closelog ();
|
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
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
@@ -616,7 +642,6 @@ main (int argc, char **argv)
|
|||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
char *plugins = NULL;
|
char *plugins = NULL;
|
||||||
char *config = NULL;
|
char *config = NULL;
|
||||||
gboolean debug = FALSE;
|
|
||||||
|
|
||||||
GOptionEntry entries[] = {
|
GOptionEntry entries[] = {
|
||||||
{ "config", 0, 0, G_OPTION_ARG_FILENAME, &config, "Config file location", "/path/to/config.file" },
|
{ "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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
app->loop = g_main_loop_new (NULL, FALSE);
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
if (!debug)
|
if (!debug)
|
||||||
logging_setup ();
|
logging_setup ();
|
||||||
@@ -682,15 +707,18 @@ main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
g_free (plugins);
|
g_free (plugins);
|
||||||
|
|
||||||
|
setup_signals ();
|
||||||
|
|
||||||
g_idle_add (load_stuff, app);
|
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_object_unref (app->hal_mgr);
|
||||||
|
|
||||||
g_hash_table_destroy (app->wired_devices);
|
g_hash_table_destroy (app->wired_devices);
|
||||||
|
|
||||||
|
g_object_unref (app->settings);
|
||||||
dbus_cleanup (app);
|
dbus_cleanup (app);
|
||||||
|
|
||||||
if (!debug)
|
if (!debug)
|
||||||
|
@@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
NMSystemConfigHalManager *nm_system_config_hal_manager_get (DBusGConnection *g_connection);
|
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
|
#define NUM_DEVICE_TYPES NM_DEVICE_TYPE_CDMA
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -221,30 +223,6 @@ init_dbus (NMSystemConfigHalManager *manager, DBusGConnection *g_connection)
|
|||||||
return TRUE;
|
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 *
|
static NMSystemConfigHalManager *
|
||||||
nm_system_config_hal_manager_new (DBusGConnection *g_connection)
|
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);
|
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
|
static void
|
||||||
dispose (GObject *object)
|
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);
|
G_OBJECT_CLASS (nm_system_config_hal_manager_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user