From 55ae3fd12fae5dd33ad30704e85f053e29a3bf83 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 10:23:39 -0600 Subject: Removing the dbus-glib headers --- libindicator/indicator-service-manager.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'libindicator/indicator-service-manager.c') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index 20eddec..cced611 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -27,9 +27,6 @@ License along with this library. If not, see #include -#include -#include - #include "indicator-service-manager.h" #include "indicator-service-client.h" #include "dbus-shared.h" -- cgit v1.2.3 From 9552d2d484f7e09c5cc5a6489a5f54bb53945103 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 16:37:42 -0600 Subject: Switching around headers to the new world order --- libindicator/indicator-service-manager.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'libindicator/indicator-service-manager.c') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index cced611..096e9ca 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -26,9 +26,10 @@ License along with this library. If not, see #endif #include +#include #include "indicator-service-manager.h" -#include "indicator-service-client.h" +#include "gen-indicator-service.xml.h" #include "dbus-shared.h" /* Private Stuff */ -- cgit v1.2.3 From 037ed98f165aa9e2f27d9fa38edf360b00290505 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 16:44:03 -0600 Subject: Removing the bus and dbus_proxy variables as we won't need them anymore. --- libindicator/indicator-service-manager.c | 33 -------------------------------- 1 file changed, 33 deletions(-) (limited to 'libindicator/indicator-service-manager.c') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index 096e9ca..31856a0 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -36,21 +36,17 @@ License along with this library. If not, see /** IndicatorServiceManagerPrivate: @name: The well known dbus name the service should be on. - @dbus_proxy: A proxy to talk to the dbus daemon. @service_proxy: The proxy to the service itself. @connected: Whether we're connected to the service or not. @this_service_version: The version of the service that we're looking for. - @bus: A reference to the bus so we don't have to keep getting it. @restart_count: The number of times we've restarted this service. */ typedef struct _IndicatorServiceManagerPrivate IndicatorServiceManagerPrivate; struct _IndicatorServiceManagerPrivate { gchar * name; - DBusGProxy * dbus_proxy; DBusGProxy * service_proxy; gboolean connected; guint this_service_version; - DBusGConnection * bus; guint restart_count; gint restart_source; }; @@ -161,34 +157,12 @@ indicator_service_manager_init (IndicatorServiceManager *self) /* Get the private variables in a decent state */ priv->name = NULL; - priv->dbus_proxy = NULL; priv->service_proxy = NULL; priv->connected = FALSE; priv->this_service_version = 0; - priv->bus = NULL; priv->restart_count = 0; priv->restart_source = 0; - /* Start talkin' dbus */ - GError * error = NULL; - priv->bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); - if (error != NULL) { - g_error("Unable to get session bus for manager: %s", error->message); - g_error_free(error); - return; - } - - priv->dbus_proxy = dbus_g_proxy_new_for_name_owner(priv->bus, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - &error); - if (error != NULL) { - g_error("Unable to get the proxy to DBus: %s", error->message); - g_error_free(error); - return; - } - return; } @@ -215,12 +189,6 @@ indicator_service_manager_dispose (GObject *object) g_signal_emit(object, signals[CONNECTION_CHANGE], 0, FALSE, TRUE); } - /* Destory our DBus proxy, we won't need it. */ - if (priv->dbus_proxy != NULL) { - g_object_unref(G_OBJECT(priv->dbus_proxy)); - priv->dbus_proxy = NULL; - } - /* If we have a proxy, tell it we're shutting down. Just to be polite about it. */ if (priv->service_proxy != NULL) { @@ -424,7 +392,6 @@ start_service (IndicatorServiceManager * service) GError * error = NULL; IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(service); - g_return_if_fail(priv->dbus_proxy != NULL); g_return_if_fail(priv->name != NULL); if (priv->service_proxy != NULL) { -- cgit v1.2.3 From 70bfa89bf97d62f03b04822aee4e03c56d1b4dfc Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 22:42:16 -0600 Subject: Replacing the service proxy with a brand new GDBus one --- libindicator/indicator-service-manager.c | 188 +++++++++++++++++-------------- 1 file changed, 105 insertions(+), 83 deletions(-) (limited to 'libindicator/indicator-service-manager.c') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index 31856a0..b5457ff 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -44,7 +44,7 @@ License along with this library. If not, see typedef struct _IndicatorServiceManagerPrivate IndicatorServiceManagerPrivate; struct _IndicatorServiceManagerPrivate { gchar * name; - DBusGProxy * service_proxy; + GDBusProxy * service_proxy; gboolean connected; guint this_service_version; guint restart_count; @@ -92,9 +92,11 @@ static void indicator_service_manager_finalize (GObject *object); /* Prototypes */ static void set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static void service_proxy_destroyed (DBusGProxy * proxy, gpointer user_data); static void start_service (IndicatorServiceManager * service); static void start_service_again (IndicatorServiceManager * manager); +static void unwatch (GDBusProxy * proxy); +static void service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data); +static void service_proxy_name_change (GObject * object, GParamSpec * pspec, gpointer user_data); G_DEFINE_TYPE (IndicatorServiceManager, indicator_service_manager, G_TYPE_OBJECT); @@ -192,7 +194,7 @@ indicator_service_manager_dispose (GObject *object) /* If we have a proxy, tell it we're shutting down. Just to be polite about it. */ if (priv->service_proxy != NULL) { - dbus_g_proxy_call_no_reply(priv->service_proxy, "UnWatch", G_TYPE_INVALID); + unwatch(priv->service_proxy); } /* Destory our service proxy, we won't need it. */ @@ -284,6 +286,22 @@ get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspe return; } +/* Small little function to make a long function call a little + bit cleaner. */ +static void +unwatch (GDBusProxy * proxy) +{ + g_dbus_proxy_call(proxy, + "UnWatch", + NULL, /* parameters */ + G_DBUS_CALL_FLAGS_NONE, + -1, /* timeout */ + NULL, /* cancelable */ + NULL, /* callback */ + NULL); /* user data */ + return; +} + /* A callback from telling a service that we want to watch it. It gives us the service API version and the version of the other APIs it supports. We check both of those. @@ -291,10 +309,13 @@ get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspe signal a connection change to tell the rest of the world that we have a service now. */ static void -watch_cb (DBusGProxy * proxy, guint service_api_version, guint this_service_version, GError * error, gpointer user_data) +watch_cb (GObject * object, GAsyncResult * res, gpointer user_data) { + GError * error = NULL; IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(user_data); + GVariant * params = g_dbus_proxy_call_finish(G_DBUS_PROXY(object), res, &error); + if (error != NULL) { g_warning("Unable to set watch on '%s': '%s'", priv->name, error->message); g_error_free(error); @@ -302,6 +323,12 @@ watch_cb (DBusGProxy * proxy, guint service_api_version, guint this_service_vers return; } + guint service_api_version; + guint this_service_version; + + g_variant_get(params, "(uu)", &service_api_version, &this_service_version); + g_object_unref(params); + /* We've done it, now let's stop counting. */ /* Note: we're not checking versions. Because, the hope is that the guy holding the name we want with the wrong version will @@ -310,7 +337,7 @@ watch_cb (DBusGProxy * proxy, guint service_api_version, guint this_service_vers if (service_api_version != INDICATOR_SERVICE_VERSION) { g_warning("Service is using a different version of the service interface. Expecting %d and got %d.", INDICATOR_SERVICE_VERSION, service_api_version); - dbus_g_proxy_call_no_reply(priv->service_proxy, "UnWatch", G_TYPE_INVALID); + unwatch(priv->service_proxy); /* Let's make us wait a little while, then try again */ priv->restart_count = TIMEOUT_A_LITTLE_WHILE; @@ -320,7 +347,7 @@ watch_cb (DBusGProxy * proxy, guint service_api_version, guint this_service_vers if (this_service_version != priv->this_service_version) { g_warning("Service is using a different API version than the manager. Expecting %d and got %d.", priv->this_service_version, this_service_version); - dbus_g_proxy_call_no_reply(priv->service_proxy, "UnWatch", G_TYPE_INVALID); + unwatch(priv->service_proxy); /* Let's make us wait a little while, then try again */ priv->restart_count = TIMEOUT_A_LITTLE_WHILE; @@ -336,52 +363,6 @@ watch_cb (DBusGProxy * proxy, guint service_api_version, guint this_service_vers return; } -/* The callback after asking the dbus-daemon to start a - service for us. It can return success or failure, on - failure we can't do much. But, with sucess, we start - to build a proxy and tell the service that we're watching. */ -static void -start_service_cb (DBusGProxy * proxy, guint status, GError * error, gpointer user_data) -{ - IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(user_data); - - if (error != NULL) { - g_warning("Unable to start service '%s': %s", priv->name, error->message); - start_service_again(INDICATOR_SERVICE_MANAGER(user_data)); - return; - } - - if (status != DBUS_START_REPLY_SUCCESS && status != DBUS_START_REPLY_ALREADY_RUNNING) { - g_warning("Status of starting the process '%s' was an error: %d", priv->name, status); - start_service_again(INDICATOR_SERVICE_MANAGER(user_data)); - return; - } - - /* Woot! it's running. Let's do it some more. */ - priv->service_proxy = dbus_g_proxy_new_for_name_owner(priv->bus, - priv->name, - INDICATOR_SERVICE_OBJECT, - INDICATOR_SERVICE_INTERFACE, - &error); - - if (error != NULL || priv->service_proxy == NULL) { - g_warning("Unable to create service proxy on '%s': %s", priv->name, error == NULL ? "(null)" : error->message); - priv->service_proxy = NULL; /* Should be already, but we want to be *really* sure. */ - g_error_free(error); - start_service_again(INDICATOR_SERVICE_MANAGER(user_data)); - return; - } - - g_object_add_weak_pointer(G_OBJECT(priv->service_proxy), (gpointer *)&(priv->service_proxy)); - g_signal_connect(G_OBJECT(priv->service_proxy), "destroy", G_CALLBACK(service_proxy_destroyed), user_data); - - org_ayatana_indicator_service_watch_async(priv->service_proxy, - watch_cb, - user_data); - - return; -} - /* The function that handles getting us connected to the service. In many cases it will start the service, but if the service is already there it just allocates the service proxy and acts @@ -389,7 +370,6 @@ start_service_cb (DBusGProxy * proxy, guint status, GError * error, gpointer use static void start_service (IndicatorServiceManager * service) { - GError * error = NULL; IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(service); g_return_if_fail(priv->name != NULL); @@ -399,47 +379,89 @@ start_service (IndicatorServiceManager * service) priv->service_proxy = NULL; } - /* Check to see if we can get a proxy to it first. */ - priv->service_proxy = dbus_g_proxy_new_for_name_owner(priv->bus, - priv->name, - INDICATOR_SERVICE_OBJECT, - INDICATOR_SERVICE_INTERFACE, - &error); + g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + interface_info, + priv->name, + INDICATOR_SERVICE_INTERFACE, + INDICATOR_SERVICE_OBJECT, + NULL, /* cancelable */ + service_proxy_cb, + service); + + return; +} + +/* Callback from trying to create the proxy for the serivce, this + could include starting the service. Sometime it'll fail and + we'll try to start that dang service again! */ +static void +service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) +{ + GError * error = NULL; + GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); - if (error != NULL || priv->service_proxy == NULL) { - /* We don't care about the error, just start the service anyway. */ + if (error != NULL) { + /* Unable to create the proxy, eh, let's try again + in a bit */ g_error_free(error); - org_freedesktop_DBus_start_service_by_name_async (priv->dbus_proxy, - priv->name, - 0, - start_service_cb, - service); - } else { - g_object_add_weak_pointer(G_OBJECT(priv->service_proxy), (gpointer *)&(priv->service_proxy)); - g_signal_connect(G_OBJECT(priv->service_proxy), "destroy", G_CALLBACK(service_proxy_destroyed), service); - - /* If we got a proxy just because we're good people then - we need to call watch on it just like 'start_service_cb' - does. */ - org_ayatana_indicator_service_watch_async(priv->service_proxy, - watch_cb, - service); + start_service_again(INDICATOR_SERVICE_MANAGER(user_data)); + return; } + gchar * name = g_dbus_proxy_get_name_owner(proxy); + if (name == NULL) { + /* Hmm, since creating the proxy should start it, it seems very + odd that it wouldn't have an owner at this point. But, all + we can do is try again. */ + g_object_unref(proxy); + start_service_again(INDICATOR_SERVICE_MANAGER(user_data)); + return; + } + g_free(name); + + IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(user_data); + priv->service_proxy = proxy; + + /* Signal for drop */ + g_signal_connect(G_OBJECT(priv->service_proxy), "notify::g-name-owner", G_CALLBACK(service_proxy_name_change), user_data); + + /* Send watch */ + g_dbus_proxy_call(priv->service_proxy, + "Watch", + NULL, /* params */ + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, /* cancel */ + watch_cb, + user_data); + return; } -/* Responds to the destory event of the proxy and starts - setting up to restart the service. */ +/* Responds to the name owner changing of the proxy, this + usually means the service died. We're dropping the proxy + and recreating it so that it'll restart the service. */ static void -service_proxy_destroyed (DBusGProxy * proxy, gpointer user_data) +service_proxy_name_change (GObject * object, GParamSpec * pspec, gpointer user_data) { IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(user_data); - if (priv->connected) { - priv->connected = FALSE; - g_signal_emit(G_OBJECT(user_data), signals[CONNECTION_CHANGE], 0, FALSE, TRUE); + gchar * name = g_dbus_proxy_get_name_owner(priv->service_proxy); + + if (name == NULL) { + if (priv->connected) { + priv->connected = FALSE; + g_signal_emit(G_OBJECT(user_data), signals[CONNECTION_CHANGE], 0, FALSE, TRUE); + } + + start_service_again(INDICATOR_SERVICE_MANAGER(user_data)); + } else { + /* This case is an oddity, and really can only be a weird race + condition. So we're going to ignore it for now. */ + g_free(name); } - return start_service_again(INDICATOR_SERVICE_MANAGER(user_data)); + + return; } /* The callback that starts the service for real after -- cgit v1.2.3 From 20f3cbb90f83169f0961939c62ecdefc463dd41d Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 22:43:36 -0600 Subject: Adding in creating the interface info from the XML files --- libindicator/indicator-service-manager.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'libindicator/indicator-service-manager.c') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index b5457ff..5dbaf5c 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -80,6 +80,10 @@ enum { #define PROP_NAME_S "name" #define PROP_VERSION_S "version" +/* GDBus Stuff */ +static GDBusNodeInfo * node_info = NULL; +static GDBusInterfaceInfo * interface_info = NULL; + /* GObject Stuff */ #define INDICATOR_SERVICE_MANAGER_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_SERVICE_MANAGER_TYPE, IndicatorServiceManagerPrivate)) @@ -146,6 +150,25 @@ indicator_service_manager_class_init (IndicatorServiceManagerClass *klass) 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /* Setting up the DBus interfaces */ + if (node_info == NULL) { + GError * error = NULL; + + node_info = g_dbus_node_info_new_for_xml(_indicator_service, &error); + if (error != NULL) { + g_error("Unable to parse Indicator Service Interface description: %s", error->message); + g_error_free(error); + } + } + + if (interface_info == NULL) { + interface_info = g_dbus_node_info_lookup_interface(node_info, INDICATOR_SERVICE_INTERFACE); + + if (interface_info == NULL) { + g_error("Unable to find interface '" INDICATOR_SERVICE_INTERFACE "'"); + } + } + return; } -- cgit v1.2.3 From 32515c5c55fdaf758be01dd6a7294ee62545757a Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 23:26:05 -0600 Subject: Out of order parameters. --- libindicator/indicator-service-manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libindicator/indicator-service-manager.c') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index 5dbaf5c..7b2cae9 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -406,8 +406,8 @@ start_service (IndicatorServiceManager * service) G_DBUS_PROXY_FLAGS_NONE, interface_info, priv->name, - INDICATOR_SERVICE_INTERFACE, INDICATOR_SERVICE_OBJECT, + INDICATOR_SERVICE_INTERFACE, NULL, /* cancelable */ service_proxy_cb, service); -- cgit v1.2.3 From 8d3f43fcf3a1cbf9f325360fa0f97f576ff7b002 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Sun, 9 Jan 2011 13:56:02 -0600 Subject: Making getting the proxy and watching cancellable so that we don't get weird crashes. --- libindicator/indicator-service-manager.c | 33 ++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'libindicator/indicator-service-manager.c') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index 7b2cae9..c85f97b 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -45,10 +45,12 @@ typedef struct _IndicatorServiceManagerPrivate IndicatorServiceManagerPrivate; struct _IndicatorServiceManagerPrivate { gchar * name; GDBusProxy * service_proxy; + GCancellable * service_proxy_cancel; gboolean connected; guint this_service_version; guint restart_count; gint restart_source; + GCancellable * watch_cancel; }; /* Signals Stuff */ @@ -183,10 +185,12 @@ indicator_service_manager_init (IndicatorServiceManager *self) /* Get the private variables in a decent state */ priv->name = NULL; priv->service_proxy = NULL; + priv->service_proxy_cancel = NULL; priv->connected = FALSE; priv->this_service_version = 0; priv->restart_count = 0; priv->restart_source = 0; + priv->watch_cancel = NULL; return; } @@ -214,6 +218,22 @@ indicator_service_manager_dispose (GObject *object) g_signal_emit(object, signals[CONNECTION_CHANGE], 0, FALSE, TRUE); } + /* If we're still getting the proxy, stop looking so we + can then clean up some more. */ + if (priv->service_proxy_cancel != NULL) { + g_cancellable_cancel(priv->service_proxy_cancel); + g_object_unref(priv->service_proxy_cancel); + priv->service_proxy_cancel = NULL; + } + + /* If we've sent a watch, cancel looking for the reply before + sending the unwatch */ + if (priv->watch_cancel != NULL) { + g_cancellable_cancel(priv->watch_cancel); + g_object_unref(priv->watch_cancel); + priv->watch_cancel = NULL; + } + /* If we have a proxy, tell it we're shutting down. Just to be polite about it. */ if (priv->service_proxy != NULL) { @@ -402,13 +422,17 @@ start_service (IndicatorServiceManager * service) priv->service_proxy = NULL; } + if (priv->service_proxy_cancel == NULL) { + priv->service_proxy_cancel = g_cancellable_new(); + } + g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, interface_info, priv->name, INDICATOR_SERVICE_OBJECT, INDICATOR_SERVICE_INTERFACE, - NULL, /* cancelable */ + priv->service_proxy_cancel, service_proxy_cb, service); @@ -449,13 +473,18 @@ service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) /* Signal for drop */ g_signal_connect(G_OBJECT(priv->service_proxy), "notify::g-name-owner", G_CALLBACK(service_proxy_name_change), user_data); + /* Build cancelable if we need it */ + if (priv->watch_cancel == NULL) { + priv->watch_cancel = g_cancellable_new(); + } + /* Send watch */ g_dbus_proxy_call(priv->service_proxy, "Watch", NULL, /* params */ G_DBUS_CALL_FLAGS_NONE, -1, - NULL, /* cancel */ + priv->watch_cancel, watch_cb, user_data); -- cgit v1.2.3 From 664e39bbed088df649d3135a0fd1c09f1fd882b6 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Sun, 9 Jan 2011 16:58:41 -0600 Subject: Using variant_unref instead of object_unref as it's a variant --- libindicator/indicator-service-manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libindicator/indicator-service-manager.c') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index c85f97b..4f98a5c 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -370,7 +370,7 @@ watch_cb (GObject * object, GAsyncResult * res, gpointer user_data) guint this_service_version; g_variant_get(params, "(uu)", &service_api_version, &this_service_version); - g_object_unref(params); + g_variant_unref(params); /* We've done it, now let's stop counting. */ /* Note: we're not checking versions. Because, the hope is that -- cgit v1.2.3 From 4a3d68bb35a2f371708568e199bdb0fc92af4ef5 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Sun, 9 Jan 2011 17:06:45 -0600 Subject: Using the GCancellable to detect if we're already creating a proxy so that we don't do it twice. --- libindicator/indicator-service-manager.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'libindicator/indicator-service-manager.c') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index 4f98a5c..34b6baa 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -417,14 +417,17 @@ start_service (IndicatorServiceManager * service) g_return_if_fail(priv->name != NULL); + if (priv->service_proxy_cancel != NULL) { + /* A service proxy is being gotten currently */ + return; + } + if (priv->service_proxy != NULL) { g_object_unref(priv->service_proxy); priv->service_proxy = NULL; } - if (priv->service_proxy_cancel == NULL) { - priv->service_proxy_cancel = g_cancellable_new(); - } + priv->service_proxy_cancel = g_cancellable_new(); g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, @@ -446,13 +449,24 @@ static void service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) { GError * error = NULL; + + IndicatorServiceManager * service = INDICATOR_SERVICE_MANAGER(user_data); + g_return_if_fail(service != NULL); + GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); + IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(user_data); + + if (priv->service_proxy_cancel != NULL) { + g_object_unref(priv->service_proxy_cancel); + priv->service_proxy_cancel = NULL; + } + if (error != NULL) { /* Unable to create the proxy, eh, let's try again in a bit */ g_error_free(error); - start_service_again(INDICATOR_SERVICE_MANAGER(user_data)); + start_service_again(service); return; } @@ -462,12 +476,13 @@ service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) odd that it wouldn't have an owner at this point. But, all we can do is try again. */ g_object_unref(proxy); - start_service_again(INDICATOR_SERVICE_MANAGER(user_data)); + start_service_again(service); return; } g_free(name); - IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(user_data); + /* Okay, we're good to grab the proxy at this point, we're + sure that it's ours. */ priv->service_proxy = proxy; /* Signal for drop */ -- cgit v1.2.3