From 52dbe22890f50afa93dfeed7b9dcf1e9fb382393 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 15 Feb 2009 10:17:53 -0500 Subject: [PATCH] dbus: clean up reconnection The reconnection timeout would never be canceled, and get rid of the "disconnected by the system bus" message on exit, which while technically true was useless due to the pending exit. --- src/nm-dbus-manager.c | 114 +++++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 52 deletions(-) diff --git a/src/nm-dbus-manager.c b/src/nm-dbus-manager.c index 358182ec2b..ae8aadd916 100644 --- a/src/nm-dbus-manager.c +++ b/src/nm-dbus-manager.c @@ -37,23 +37,27 @@ enum { NUMBER_OF_SIGNALS }; -static guint nm_dbus_manager_signals[NUMBER_OF_SIGNALS]; +static guint signals[NUMBER_OF_SIGNALS]; G_DEFINE_TYPE(NMDBusManager, nm_dbus_manager, G_TYPE_OBJECT) #define NM_DBUS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ - NM_TYPE_DBUS_MANAGER, \ - NMDBusManagerPrivate)) + NM_TYPE_DBUS_MANAGER, \ + NMDBusManagerPrivate)) typedef struct { - DBusConnection * connection; + DBusConnection *connection; DBusGConnection *g_connection; - DBusGProxy * proxy; - gboolean started; + gboolean started; + + DBusGProxy *proxy; + guint proxy_destroy_id; + + guint reconnect_id; } NMDBusManagerPrivate; static gboolean nm_dbus_manager_init_bus (NMDBusManager *self); -static void nm_dbus_manager_cleanup (NMDBusManager *self); +static void nm_dbus_manager_cleanup (NMDBusManager *self, gboolean dispose); static void start_reconnection_timeout (NMDBusManager *self); NMDBusManager * @@ -79,11 +83,18 @@ nm_dbus_manager_init (NMDBusManager *self) } static void -nm_dbus_manager_finalize (GObject *object) +nm_dbus_manager_dispose (GObject *object) { - nm_dbus_manager_cleanup (NM_DBUS_MANAGER (object)); + NMDBusManagerPrivate *priv = NM_DBUS_MANAGER_GET_PRIVATE (object); - G_OBJECT_CLASS (nm_dbus_manager_parent_class)->finalize (object); + nm_dbus_manager_cleanup (NM_DBUS_MANAGER (object), TRUE); + + if (priv->reconnect_id) { + g_source_remove (priv->reconnect_id); + priv->reconnect_id = 0; + } + + G_OBJECT_CLASS (nm_dbus_manager_parent_class)->dispose (object); } static void @@ -91,9 +102,9 @@ nm_dbus_manager_class_init (NMDBusManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = nm_dbus_manager_finalize; + object_class->dispose = nm_dbus_manager_dispose; - nm_dbus_manager_signals[DBUS_CONNECTION_CHANGED] = + signals[DBUS_CONNECTION_CHANGED] = g_signal_new ("dbus-connection-changed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, @@ -101,7 +112,7 @@ nm_dbus_manager_class_init (NMDBusManagerClass *klass) NULL, NULL, _nm_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); - nm_dbus_manager_signals[NAME_OWNER_CHANGED] = + signals[NAME_OWNER_CHANGED] = g_signal_new ("name-owner-changed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, @@ -115,11 +126,15 @@ nm_dbus_manager_class_init (NMDBusManagerClass *klass) /* Only cleanup a specific dbus connection, not all our private data */ static void -nm_dbus_manager_cleanup (NMDBusManager *self) +nm_dbus_manager_cleanup (NMDBusManager *self, gboolean dispose) { NMDBusManagerPrivate *priv = NM_DBUS_MANAGER_GET_PRIVATE (self); if (priv->proxy) { + if (dispose) { + g_signal_handler_disconnect (priv->proxy, priv->proxy_destroy_id); + priv->proxy_destroy_id = 0; + } g_object_unref (priv->proxy); priv->proxy = NULL; } @@ -137,29 +152,33 @@ static gboolean nm_dbus_manager_reconnect (gpointer user_data) { NMDBusManager *self = NM_DBUS_MANAGER (user_data); + NMDBusManagerPrivate *priv = NM_DBUS_MANAGER_GET_PRIVATE (self); g_assert (self != NULL); if (nm_dbus_manager_init_bus (self)) { if (nm_dbus_manager_start_service (self)) { nm_info ("reconnected to the system bus."); - g_signal_emit (self, - nm_dbus_manager_signals[DBUS_CONNECTION_CHANGED], - 0, - NM_DBUS_MANAGER_GET_PRIVATE (self)->connection); + g_signal_emit (self, signals[DBUS_CONNECTION_CHANGED], + 0, priv->connection); return TRUE; } } - nm_dbus_manager_cleanup (self); + nm_dbus_manager_cleanup (self, FALSE); return FALSE; } static void start_reconnection_timeout (NMDBusManager *self) { + NMDBusManagerPrivate *priv = NM_DBUS_MANAGER_GET_PRIVATE (self); + + if (priv->reconnect_id) + g_source_remove (priv->reconnect_id); + /* Schedule timeout for reconnection attempts */ - g_timeout_add_seconds (3, nm_dbus_manager_reconnect, self); + priv->reconnect_id = g_timeout_add_seconds (3, nm_dbus_manager_reconnect, self); } char * @@ -216,10 +235,8 @@ proxy_name_owner_changed (DBusGProxy *proxy, const char *new_owner, gpointer user_data) { - g_signal_emit (NM_DBUS_MANAGER (user_data), - nm_dbus_manager_signals[NAME_OWNER_CHANGED], - 0, - name, old_owner, new_owner); + g_signal_emit (G_OBJECT (user_data), signals[NAME_OWNER_CHANGED], + 0, name, old_owner, new_owner); } static void @@ -231,11 +248,9 @@ destroy_cb (DBusGProxy *proxy, gpointer user_data) nm_info ("disconnected by the system bus."); NM_DBUS_MANAGER_GET_PRIVATE (self)->proxy = NULL; - nm_dbus_manager_cleanup (self); + nm_dbus_manager_cleanup (self, FALSE); - g_signal_emit (G_OBJECT (self), - nm_dbus_manager_signals[DBUS_CONNECTION_CHANGED], - 0, NULL); + g_signal_emit (G_OBJECT (self), signals[DBUS_CONNECTION_CHANGED], 0, NULL); start_reconnection_timeout (self); } @@ -266,21 +281,20 @@ nm_dbus_manager_init_bus (NMDBusManager *self) dbus_connection_set_exit_on_disconnect (priv->connection, FALSE); priv->proxy = dbus_g_proxy_new_for_name (priv->g_connection, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus"); + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus"); - g_signal_connect (priv->proxy, "destroy", - G_CALLBACK (destroy_cb), - self); + priv->proxy_destroy_id = g_signal_connect (priv->proxy, "destroy", + G_CALLBACK (destroy_cb), self); dbus_g_proxy_add_signal (priv->proxy, "NameOwnerChanged", - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); dbus_g_proxy_connect_signal (priv->proxy, - "NameOwnerChanged", - G_CALLBACK (proxy_name_owner_changed), - self, NULL); + "NameOwnerChanged", + G_CALLBACK (proxy_name_owner_changed), + self, NULL); return TRUE; } @@ -312,28 +326,24 @@ nm_dbus_manager_start_service (NMDBusManager *self) #endif if (!dbus_g_proxy_call (priv->proxy, "RequestName", &err, - G_TYPE_STRING, NM_DBUS_SERVICE, - G_TYPE_UINT, flags, - G_TYPE_INVALID, - G_TYPE_UINT, &request_name_result, - G_TYPE_INVALID)) { + G_TYPE_STRING, NM_DBUS_SERVICE, + G_TYPE_UINT, flags, + G_TYPE_INVALID, + G_TYPE_UINT, &request_name_result, + G_TYPE_INVALID)) { nm_warning ("Could not acquire the NetworkManager service.\n" - " Message: '%s'", err->message); + " Error: '%s'", + (err && err->message) ? err->message : "(unknown)"); g_error_free (err); - goto out; + return FALSE; } if (request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { nm_warning ("Could not acquire the NetworkManager service as it is already taken."); - goto out; + return FALSE; } priv->started = TRUE; - - out: - if (!priv->started) - nm_dbus_manager_cleanup (self); - return priv->started; }