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.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'libindicator/indicator-service.c') diff --git a/libindicator/indicator-service.c b/libindicator/indicator-service.c index e9005db..ed95559 100644 --- a/libindicator/indicator-service.c +++ b/libindicator/indicator-service.c @@ -24,8 +24,6 @@ License along with this library. If not, see #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include -#include #include "indicator-service.h" -- cgit v1.2.3 From 06270832fc023e972cac3c66fcf870a1d5b4a965 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 10:55:06 -0600 Subject: Parsing the XML file for the interface description on class init --- libindicator/indicator-service.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'libindicator/indicator-service.c') diff --git a/libindicator/indicator-service.c b/libindicator/indicator-service.c index ed95559..3635b45 100644 --- a/libindicator/indicator-service.c +++ b/libindicator/indicator-service.c @@ -25,7 +25,11 @@ License along with this library. If not, see #include "config.h" #endif +#include + #include "indicator-service.h" +#include "gen-indicator-service.xml.h" +#include "dbus-shared.h" static void unwatch_core (IndicatorService * service, const gchar * name); static void proxy_destroyed (GObject * proxy, gpointer user_data); @@ -34,9 +38,6 @@ static gboolean watchers_remove (gpointer key, gpointer value, gpointer user_dat static gboolean _indicator_service_server_watch (IndicatorService * service, DBusGMethodInvocation * method); static gboolean _indicator_service_server_un_watch (IndicatorService * service, DBusGMethodInvocation * method); -#include "indicator-service-server.h" -#include "dbus-shared.h" - /* Private Stuff */ /** IndicatorSevicePrivate: @@ -75,6 +76,9 @@ enum { PROP_VERSION }; +static GDBusNodeInfo * node_info = NULL; +static GDBusInterfaceInfo * interface_info = NULL; + /* The strings so that they can be slowly looked up. */ #define PROP_NAME_S "name" #define PROP_VERSION_S "version" @@ -140,6 +144,25 @@ indicator_service_class_init (IndicatorServiceClass *klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); + /* 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 "'"); + } + } + /* Initialize the object as a DBus type */ dbus_g_object_type_install_info(INDICATOR_SERVICE_TYPE, &dbus_glib__indicator_service_server_object_info); -- cgit v1.2.3 From 6ff24e119e625d2217203a64ae4d4003a9ccae09 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 12:43:29 -0600 Subject: Switching the registration of the object over. --- libindicator/indicator-service.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'libindicator/indicator-service.c') diff --git a/libindicator/indicator-service.c b/libindicator/indicator-service.c index 3635b45..21da089 100644 --- a/libindicator/indicator-service.c +++ b/libindicator/indicator-service.c @@ -47,6 +47,8 @@ static gboolean _indicator_service_server_un_watch (IndicatorService * service, @watcher: A list of processes on dbus that are watching us. @this_service_version: The version to hand out that we're implementing. May not be set, so we'll send zero (default). + @dbus_registration: The handle for this object being registered + on dbus. */ typedef struct _IndicatorServicePrivate IndicatorServicePrivate; struct _IndicatorServicePrivate { @@ -57,6 +59,7 @@ struct _IndicatorServicePrivate { guint timeout_length; GHashTable * watchers; guint this_service_version; + guint dbus_registration; }; /* Signals Stuff */ @@ -163,10 +166,6 @@ indicator_service_class_init (IndicatorServiceClass *klass) } } - /* Initialize the object as a DBus type */ - dbus_g_object_type_install_info(INDICATOR_SERVICE_TYPE, - &dbus_glib__indicator_service_server_object_info); - return; } @@ -187,6 +186,7 @@ indicator_service_init (IndicatorService *self) priv->bus = NULL; priv->this_service_version = 0; priv->timeout_length = 500; + priv->dbus_registration = 0; const gchar * timeoutenv = g_getenv("INDICATOR_SERVICE_SHUTDOWN_TIMEOUT"); if (timeoutenv != NULL) { @@ -233,9 +233,13 @@ indicator_service_init (IndicatorService *self) return; } - dbus_g_connection_register_g_object(priv->bus, - INDICATOR_SERVICE_OBJECT, - G_OBJECT(self)); + priv->dbus_registration = g_dbus_connection_register_object(priv->bus, + INDICATOR_SERVICE_OBJECT, + interface_info, + &interface_table, + self, + NULL, + &error); return; } @@ -261,6 +265,12 @@ indicator_service_dispose (GObject *object) priv->timeout = 0; } + if (priv->dbus_registration != 0) { + g_dbus_connection_unregister_object(priv->bus, priv->dbus_registration); + /* Don't care if it fails, there's nothing we can do */ + priv->dbus_registration = 0; + } + G_OBJECT_CLASS (indicator_service_parent_class)->dispose (object); return; } -- cgit v1.2.3 From 844bccb51d71d21c1b2b06332b52ffb030dd7722 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 12:59:25 -0600 Subject: Setting up the VTable --- libindicator/indicator-service.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'libindicator/indicator-service.c') diff --git a/libindicator/indicator-service.c b/libindicator/indicator-service.c index 21da089..39b1332 100644 --- a/libindicator/indicator-service.c +++ b/libindicator/indicator-service.c @@ -79,9 +79,6 @@ enum { PROP_VERSION }; -static GDBusNodeInfo * node_info = NULL; -static GDBusInterfaceInfo * interface_info = NULL; - /* The strings so that they can be slowly looked up. */ #define PROP_NAME_S "name" #define PROP_VERSION_S "version" @@ -99,7 +96,18 @@ static void indicator_service_finalize (GObject *object); 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 try_and_get_name (IndicatorService * service); +static void bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * method, GVariant * params, GDBusMethodInvocation * invocation, gpointer user_data); + +/* GDBus Stuff */ +static GDBusNodeInfo * node_info = NULL; +static GDBusInterfaceInfo * interface_info = NULL; +static GDBusInterfaceVTable interface_table = { + method_call: bus_method_call, + get_property: NULL, /* No properties */ + set_property: NULL /* No properties */ +}; +/* THE define */ G_DEFINE_TYPE (IndicatorService, indicator_service, G_TYPE_OBJECT); static void @@ -366,6 +374,15 @@ get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspe return; } +/* A method has been called from our dbus inteface. Figure out what it + is and dispatch it. */ +static void +bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * method, GVariant * params, GDBusMethodInvocation * invocation, gpointer user_data) +{ + + return; +} + /* A function to remove the signals on a proxy before we destroy it because in this case we've stopped caring. */ static gboolean -- cgit v1.2.3 From 30703e3d5a1d6a735eecdc6977535ec6976c11ab Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 13:52:27 -0600 Subject: Switching the way that we get a name on dbus and removing the dbus_proxy which was used for this previously. --- libindicator/indicator-service.c | 85 +++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 45 deletions(-) (limited to 'libindicator/indicator-service.c') diff --git a/libindicator/indicator-service.c b/libindicator/indicator-service.c index 39b1332..e1521a3 100644 --- a/libindicator/indicator-service.c +++ b/libindicator/indicator-service.c @@ -42,7 +42,6 @@ static gboolean _indicator_service_server_un_watch (IndicatorService * service, /** IndicatorSevicePrivate: @name: The DBus well known name for the service. - @dbus_proxy: A proxy for talking to the dbus bus manager. @timeout: The source ID for the timeout event. @watcher: A list of processes on dbus that are watching us. @this_service_version: The version to hand out that we're @@ -53,7 +52,6 @@ static gboolean _indicator_service_server_un_watch (IndicatorService * service, typedef struct _IndicatorServicePrivate IndicatorServicePrivate; struct _IndicatorServicePrivate { gchar * name; - DBusGProxy * dbus_proxy; DBusGConnection * bus; guint timeout; guint timeout_length; @@ -188,7 +186,6 @@ indicator_service_init (IndicatorService *self) /* Get the private variables in a decent state */ priv->name = NULL; - priv->dbus_proxy = NULL; priv->timeout = 0; priv->watchers = NULL; priv->bus = NULL; @@ -230,17 +227,6 @@ indicator_service_init (IndicatorService *self) } } - 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; - } - priv->dbus_registration = g_dbus_connection_register_object(priv->bus, INDICATOR_SERVICE_OBJECT, interface_info, @@ -248,6 +234,11 @@ indicator_service_init (IndicatorService *self) self, NULL, &error); + if (error != NULL) { + g_error("Unable to register the object to DBus: %s", error->message); + g_error_free(error); + return; + } return; } @@ -263,11 +254,6 @@ indicator_service_dispose (GObject *object) g_hash_table_foreach_remove(priv->watchers, watchers_remove, object); } - if (priv->dbus_proxy != NULL) { - g_object_unref(G_OBJECT(priv->dbus_proxy)); - priv->dbus_proxy = NULL; - } - if (priv->timeout != 0) { g_source_remove(priv->timeout); priv->timeout = 0; @@ -407,34 +393,41 @@ timeout_no_watchers (gpointer data) return FALSE; } -/* The callback from our request to get a well known name - on dbus. If we can't get it we send the shutdown signal. - Else we start the timer to see if anyone cares about us. */ +/* Callback saying that the name we were looking for has been + found and we've got it. Now start the timer to see if anyone + cares about us. */ static void -try_and_get_name_cb (DBusGProxy * proxy, guint status, GError * error, gpointer data) +try_and_get_name_acquired_cb (GDBusConnection * connection, const gchar * name, gpointer user_data) { - IndicatorService * service = INDICATOR_SERVICE(data); - g_return_if_fail(service != NULL); + g_return_if_fail(connection != NULL); + g_return_if_fail(INDICATOR_IS_SERVICE(user_data)); - if (error != NULL) { - g_warning("Unable to send message to request name: %s", error->message); - g_signal_emit(G_OBJECT(data), signals[SHUTDOWN], 0, TRUE); - return; - } + IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(user_data); - if (status != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER && status != DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER) { - /* The already owner seems like it shouldn't ever - happen, but I have a hard time throwing an error - on it as we did achieve our goals. */ - g_warning("Name request failed. Status returned: %d", status); - g_signal_emit(G_OBJECT(data), signals[SHUTDOWN], 0, TRUE); - return; + /* Check to see if we already had a timer, if so we want to + extend it a bit. */ + if (priv->timeout != 0) { + g_source_remove(priv->timeout); + priv->timeout = 0; } - IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(service); /* Allow some extra time at start up as things can be in high contention then. */ - priv->timeout = g_timeout_add(priv->timeout_length * 2, timeout_no_watchers, service); + priv->timeout = g_timeout_add(priv->timeout_length * 2, timeout_no_watchers, user_data); + + return; +} + +/* Callback saying that we didn't get the name, so we need to + shutdown this service. */ +static void +try_and_get_name_lost_cb (GDBusConnection * connection, const gchar * name, gpointer user_data) +{ + g_return_if_fail(connection != NULL); + g_return_if_fail(INDICATOR_IS_SERVICE(user_data)); + + g_warning("Name request failed."); + g_signal_emit(G_OBJECT(data), signals[SHUTDOWN], 0, TRUE); return; } @@ -444,14 +437,16 @@ static void try_and_get_name (IndicatorService * service) { IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(service); - g_return_if_fail(priv->dbus_proxy != NULL); g_return_if_fail(priv->name != NULL); - org_freedesktop_DBus_request_name_async(priv->dbus_proxy, - priv->name, - DBUS_NAME_FLAG_DO_NOT_QUEUE, - try_and_get_name_cb, - service); + g_bus_own_name(G_BUS_TYPE_SESSION, + priv->name, + G_BUS_NAME_OWNER_FLAGS_NONE, + NULL, /* bus acquired */ + try_and_get_name_acquired_cb, /* name acquired */ + try_and_get_name_lost_cb, /* name lost */ + service, + NULL); /* user data destroy */ return; } -- cgit v1.2.3 From 46078343dadc841c52ece2f9afdc9a22f9f152ab Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 14:21:44 -0600 Subject: Fleshing out the bus_method_call functions and tying them into the traditional start points from dbus. --- libindicator/indicator-service.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) (limited to 'libindicator/indicator-service.c') diff --git a/libindicator/indicator-service.c b/libindicator/indicator-service.c index e1521a3..2864e05 100644 --- a/libindicator/indicator-service.c +++ b/libindicator/indicator-service.c @@ -365,7 +365,18 @@ get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspe static void bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * method, GVariant * params, GDBusMethodInvocation * invocation, gpointer user_data) { + IndicatorService * service = INDICATOR_SERVICE(user_data); + GVariant * retval = NULL; + if (g_strcmp0(method, "Watch") == 0) { + retval = bus_watch(service, sender); + } else if (g_strcmp0(method, "UnWatch") == 0) { + unwatch_core(service, sender); + } else { + g_warning("Calling method '%s' on the indicator service and it's unknown", method); + } + + g_method_invocation_return_value(invocation, retval); return; } @@ -491,13 +502,12 @@ proxy_destroyed (GObject * proxy, gpointer user_data) interface "Watch" function. It is an async function so that we can get the sender and store that information. We put them in a list and reset the timeout. */ -static gboolean -_indicator_service_server_watch (IndicatorService * service, DBusGMethodInvocation * method) +static GVariant * +bus_watch (IndicatorService * service, const gchar * sender) { - g_return_val_if_fail(INDICATOR_IS_SERVICE(service), FALSE); + g_return_val_if_fail(INDICATOR_IS_SERVICE(service), NULL); IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(service); - const gchar * sender = dbus_g_method_get_sender(method); if (g_hash_table_lookup(priv->watchers, sender) == NULL) { GError * error = NULL; DBusGProxy * senderproxy = dbus_g_proxy_new_for_name_owner(priv->bus, @@ -521,22 +531,7 @@ _indicator_service_server_watch (IndicatorService * service, DBusGMethodInvocati priv->timeout = 0; } - dbus_g_method_return(method, INDICATOR_SERVICE_VERSION, priv->this_service_version); - return TRUE; -} - -/* A function connecting into the dbus interface for the - "UnWatch" function. It is also an async function to get - the sender and passes everything to unwatch_core to remove it. */ -static gboolean -_indicator_service_server_un_watch (IndicatorService * service, DBusGMethodInvocation * method) -{ - g_return_val_if_fail(INDICATOR_IS_SERVICE(service), FALSE); - - unwatch_core(service, dbus_g_method_get_sender(method)); - - dbus_g_method_return(method); - return TRUE; + return g_variant_new("(uu)", INDICATOR_SERVICE_VERSION, priv->this_service_version); } /* Performs the core of loosing a watcher; it removes them -- cgit v1.2.3 From d75fce1892ce55c7fd50049cd592b1825228e7e8 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 14:22:17 -0600 Subject: Removing unused prototypes --- libindicator/indicator-service.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'libindicator/indicator-service.c') diff --git a/libindicator/indicator-service.c b/libindicator/indicator-service.c index 2864e05..c58416e 100644 --- a/libindicator/indicator-service.c +++ b/libindicator/indicator-service.c @@ -34,9 +34,6 @@ License along with this library. If not, see static void unwatch_core (IndicatorService * service, const gchar * name); static void proxy_destroyed (GObject * proxy, gpointer user_data); static gboolean watchers_remove (gpointer key, gpointer value, gpointer user_data); -/* DBus Prototypes */ -static gboolean _indicator_service_server_watch (IndicatorService * service, DBusGMethodInvocation * method); -static gboolean _indicator_service_server_un_watch (IndicatorService * service, DBusGMethodInvocation * method); /* Private Stuff */ /** -- cgit v1.2.3 From 2696619d1644b71ceeebea7d96dfa9349fadd0e2 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 14:58:52 -0600 Subject: Switch over to getting the GDBus bus instead of the dbus-glib one --- libindicator/indicator-service.c | 76 +++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 32 deletions(-) (limited to 'libindicator/indicator-service.c') diff --git a/libindicator/indicator-service.c b/libindicator/indicator-service.c index c58416e..5f2ed87 100644 --- a/libindicator/indicator-service.c +++ b/libindicator/indicator-service.c @@ -34,6 +34,7 @@ License along with this library. If not, see static void unwatch_core (IndicatorService * service, const gchar * name); static void proxy_destroyed (GObject * proxy, gpointer user_data); static gboolean watchers_remove (gpointer key, gpointer value, gpointer user_data); +static void bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data); /* Private Stuff */ /** @@ -49,7 +50,7 @@ static gboolean watchers_remove (gpointer key, gpointer value, gpointer user_dat typedef struct _IndicatorServicePrivate IndicatorServicePrivate; struct _IndicatorServicePrivate { gchar * name; - DBusGConnection * bus; + GDBusConnection * bus; guint timeout; guint timeout_length; GHashTable * watchers; @@ -205,37 +206,10 @@ indicator_service_init (IndicatorService *self) here because there is no user data to pass the object as well. */ priv->watchers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref); - /* Start talkin' dbus */ - GError * error = NULL; - priv->bus = dbus_g_bus_get(DBUS_BUS_STARTER, &error); - if (error != NULL) { - g_error("Unable to get starter bus: %s", error->message); - g_error_free(error); - - /* Okay, fine let's try the session bus then. */ - /* I think this should automatically, but I can't find confirmation - of that, so we're putting the extra little code in here. */ - error = NULL; - priv->bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); - if (error != NULL) { - g_error("Unable to get session bus: %s", error->message); - g_error_free(error); - return; - } - } - - priv->dbus_registration = g_dbus_connection_register_object(priv->bus, - INDICATOR_SERVICE_OBJECT, - interface_info, - &interface_table, - self, - NULL, - &error); - if (error != NULL) { - g_error("Unable to register the object to DBus: %s", error->message); - g_error_free(error); - return; - } + g_bus_get(G_BUS_TYPE_STARTER, + NULL, /* TODO: Cancellable */ + bus_get_cb, + self); return; } @@ -262,6 +236,11 @@ indicator_service_dispose (GObject *object) priv->dbus_registration = 0; } + if (priv->bus != NULL) { + g_object_unref(priv->bus); + priv->bus = NULL; + } + G_OBJECT_CLASS (indicator_service_parent_class)->dispose (object); return; } @@ -357,6 +336,39 @@ get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspe return; } +/* Callback for getting our connection to DBus */ +static void +bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data) +{ + GError * error = NULL; + GDBusConnection * connection = g_bus_get_finish(res, &error); + + if (error != NULL) { + g_error("OMG! Unable to get a connection to DBus: %s", error->message); + g_error_free(error); + return; + } + + IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(user_data); + priv->bus = connection; + + /* Now register our object on our new connection */ + priv->dbus_registration = g_dbus_connection_register_object(priv->bus, + INDICATOR_SERVICE_OBJECT, + interface_info, + &interface_table, + user_data, + NULL, + &error); + if (error != NULL) { + g_error("Unable to register the object to DBus: %s", error->message); + g_error_free(error); + return; + } + + return; +} + /* A method has been called from our dbus inteface. Figure out what it is and dispatch it. */ static void -- cgit v1.2.3 From 991b87f5eb605a50f3b5a174b9657ae4ebe236e2 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 15:35:34 -0600 Subject: Little clean-ups the compiler found now that it's more happy. --- libindicator/indicator-service.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'libindicator/indicator-service.c') diff --git a/libindicator/indicator-service.c b/libindicator/indicator-service.c index 5f2ed87..d6c1f34 100644 --- a/libindicator/indicator-service.c +++ b/libindicator/indicator-service.c @@ -35,6 +35,7 @@ static void unwatch_core (IndicatorService * service, const gchar * name); static void proxy_destroyed (GObject * proxy, gpointer user_data); static gboolean watchers_remove (gpointer key, gpointer value, gpointer user_data); static void bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data); +static GVariant * bus_watch (IndicatorService * service, const gchar * sender); /* Private Stuff */ /** @@ -385,7 +386,7 @@ bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar g_warning("Calling method '%s' on the indicator service and it's unknown", method); } - g_method_invocation_return_value(invocation, retval); + g_dbus_method_invocation_return_value(invocation, retval); return; } @@ -447,7 +448,7 @@ try_and_get_name_lost_cb (GDBusConnection * connection, const gchar * name, gpoi g_return_if_fail(INDICATOR_IS_SERVICE(user_data)); g_warning("Name request failed."); - g_signal_emit(G_OBJECT(data), signals[SHUTDOWN], 0, TRUE); + g_signal_emit(G_OBJECT(user_data), signals[SHUTDOWN], 0, TRUE); return; } -- cgit v1.2.3 From 33afd01e563f59793ed351f6f236e8905b2fa0cc Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 16:12:43 -0600 Subject: Instead of setting up a proxy to watch the watcher we're setting up a bus name watch on each one. --- libindicator/indicator-service.c | 69 ++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 45 deletions(-) (limited to 'libindicator/indicator-service.c') diff --git a/libindicator/indicator-service.c b/libindicator/indicator-service.c index d6c1f34..e87f174 100644 --- a/libindicator/indicator-service.c +++ b/libindicator/indicator-service.c @@ -32,7 +32,6 @@ License along with this library. If not, see #include "dbus-shared.h" static void unwatch_core (IndicatorService * service, const gchar * name); -static void proxy_destroyed (GObject * proxy, gpointer user_data); static gboolean watchers_remove (gpointer key, gpointer value, gpointer user_data); static void bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data); static GVariant * bus_watch (IndicatorService * service, const gchar * sender); @@ -201,11 +200,11 @@ indicator_service_init (IndicatorService *self) } } - /* NOTE: We're using g_object_unref here because that's what needs to + /* NOTE: We're using g_free here because that's what needs to happen, but you really should call watchers_remove first as well since that disconnects the signals. We can't do that with a callback here because there is no user data to pass the object as well. */ - priv->watchers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref); + priv->watchers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); g_bus_get(G_BUS_TYPE_STARTER, NULL, /* TODO: Cancellable */ @@ -395,7 +394,7 @@ bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar static gboolean watchers_remove (gpointer key, gpointer value, gpointer user_data) { - g_signal_handlers_disconnect_by_func(G_OBJECT(value), G_CALLBACK(proxy_destroyed), user_data); + g_bus_unwatch_name(GPOINTER_TO_UINT(value)); return TRUE; } @@ -472,38 +471,20 @@ try_and_get_name (IndicatorService * service) return; } -typedef struct _hash_table_find_t hash_table_find_t; -struct _hash_table_find_t { - GObject * proxy; - gchar * name; -}; - -/* Look in the hash table for the proxy, as it won't give us - its name. */ -static gboolean -hash_table_find (gpointer key, gpointer value, gpointer user_data) -{ - hash_table_find_t * finddata = (hash_table_find_t *)user_data; - if (value == finddata->proxy) { - finddata->name = key; - return TRUE; - } - return FALSE; -} - -/* If the proxy gets destroyed that's the same as getting an - unwatch signal. Make it so. */ +/* When the watcher vanishes we don't really care about it + anymore. */ static void -proxy_destroyed (GObject * proxy, gpointer user_data) +watcher_vanished_cb (GDBusConnection * connection, const gchar * name, gpointer user_data) { g_return_if_fail(INDICATOR_IS_SERVICE(user_data)); IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(user_data); - hash_table_find_t finddata = {0}; - finddata.proxy = proxy; - - g_hash_table_find(priv->watchers, hash_table_find, &finddata); - unwatch_core(INDICATOR_SERVICE(user_data), finddata.name); + gpointer finddata = g_hash_table_lookup(priv->watchers, name); + if (finddata != NULL) { + unwatch_core(INDICATOR_SERVICE(user_data), name); + } else { + g_warning("Odd, we were watching for '%s' and it disappeard, but then it wasn't in the hashtable.", name); + } return; } @@ -518,21 +499,19 @@ bus_watch (IndicatorService * service, const gchar * sender) g_return_val_if_fail(INDICATOR_IS_SERVICE(service), NULL); IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(service); - if (g_hash_table_lookup(priv->watchers, sender) == NULL) { - GError * error = NULL; - DBusGProxy * senderproxy = dbus_g_proxy_new_for_name_owner(priv->bus, - sender, - "/", - DBUS_INTERFACE_INTROSPECTABLE, - &error); - - g_signal_connect(G_OBJECT(senderproxy), "destroy", G_CALLBACK(proxy_destroyed), service); - - if (error == NULL) { - g_hash_table_insert(priv->watchers, g_strdup(sender), senderproxy); + if (GPOINTER_TO_UINT(g_hash_table_lookup(priv->watchers, sender)) == 0) { + guint watch = g_bus_watch_name_on_connection(priv->bus, + sender, + G_BUS_NAME_WATCHER_FLAGS_NONE, + NULL, /* appeared, we dont' care, should have already happened. */ + watcher_vanished_cb, + service, + NULL); + + if (watch != 0) { + g_hash_table_insert(priv->watchers, g_strdup(sender), GUINT_TO_POINTER(watch)); } else { - g_warning("Unable to create proxy for watcher '%s': %s", sender, error->message); - g_error_free(error); + g_warning("Unable watch for '%s'", sender); } } -- cgit v1.2.3 From 2bbbabcbaee91c6c5f5ab75c31a9a47305228a68 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 23:27:36 -0600 Subject: Switching to the session bus --- libindicator/indicator-service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libindicator/indicator-service.c') diff --git a/libindicator/indicator-service.c b/libindicator/indicator-service.c index e87f174..e22ed66 100644 --- a/libindicator/indicator-service.c +++ b/libindicator/indicator-service.c @@ -206,7 +206,7 @@ indicator_service_init (IndicatorService *self) here because there is no user data to pass the object as well. */ priv->watchers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); - g_bus_get(G_BUS_TYPE_STARTER, + g_bus_get(G_BUS_TYPE_SESSION, NULL, /* TODO: Cancellable */ bus_get_cb, self); -- cgit v1.2.3 From 2fb32b9285feacdaf9e79a4b4cbbf84555f57491 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Sun, 9 Jan 2011 13:34:51 -0600 Subject: Adding in the ability to cancel the connection on short lived objects. --- libindicator/indicator-service.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'libindicator/indicator-service.c') diff --git a/libindicator/indicator-service.c b/libindicator/indicator-service.c index e22ed66..e5eaa5b 100644 --- a/libindicator/indicator-service.c +++ b/libindicator/indicator-service.c @@ -51,6 +51,7 @@ typedef struct _IndicatorServicePrivate IndicatorServicePrivate; struct _IndicatorServicePrivate { gchar * name; GDBusConnection * bus; + GCancellable * bus_cancel; guint timeout; guint timeout_length; GHashTable * watchers; @@ -187,6 +188,7 @@ indicator_service_init (IndicatorService *self) priv->timeout = 0; priv->watchers = NULL; priv->bus = NULL; + priv->bus_cancel = NULL; priv->this_service_version = 0; priv->timeout_length = 500; priv->dbus_registration = 0; @@ -206,8 +208,9 @@ indicator_service_init (IndicatorService *self) here because there is no user data to pass the object as well. */ priv->watchers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + priv->bus_cancel = g_cancellable_new(); g_bus_get(G_BUS_TYPE_SESSION, - NULL, /* TODO: Cancellable */ + priv->bus_cancel, bus_get_cb, self); @@ -241,6 +244,12 @@ indicator_service_dispose (GObject *object) priv->bus = NULL; } + if (priv->bus_cancel != NULL) { + g_cancellable_cancel(priv->bus_cancel); + g_object_unref(priv->bus_cancel); + priv->bus_cancel = NULL; + } + G_OBJECT_CLASS (indicator_service_parent_class)->dispose (object); return; } @@ -350,8 +359,15 @@ bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data) } IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(user_data); + + g_warn_if_fail(priv->bus == NULL); priv->bus = connection; + if (priv->bus_cancel != NULL) { + g_object_unref(priv->bus_cancel); + priv->bus_cancel = NULL; + } + /* Now register our object on our new connection */ priv->dbus_registration = g_dbus_connection_register_object(priv->bus, INDICATOR_SERVICE_OBJECT, @@ -498,7 +514,7 @@ bus_watch (IndicatorService * service, const gchar * sender) { g_return_val_if_fail(INDICATOR_IS_SERVICE(service), NULL); IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(service); - + if (GPOINTER_TO_UINT(g_hash_table_lookup(priv->watchers, sender)) == 0) { guint watch = g_bus_watch_name_on_connection(priv->bus, sender, -- cgit v1.2.3