From 71e88584de26bce75424c661fe93915285bf34ee Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 6 Jan 2011 15:08:46 -0600 Subject: Removing dbus-glib from the build --- configure.ac | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 365ebea..340472e 100644 --- a/configure.ac +++ b/configure.ac @@ -49,15 +49,13 @@ AC_ARG_WITH([gtk], [with_gtk=2]) AS_IF([test "x$with_gtk" = x3], [PKG_CHECK_MODULES(LIBINDICATOR, gtk+-3.0 >= $GTK3_REQUIRED_VERSION - gio-unix-2.0 >= $GIO_UNIX_REQUIRED_VERSION - dbus-glib-1 >= $DBUS_REQUIRED_VERSION) + gio-unix-2.0 >= $GIO_UNIX_REQUIRED_VERSION) AC_SUBST(LIBINDICATOR_CFLAGS) AC_SUBST(LIBINDICATOR_LIBS) ], [test "x$with_gtk" = x2], [PKG_CHECK_MODULES(LIBINDICATOR, gtk+-2.0 >= $GTK_REQUIRED_VERSION - gio-unix-2.0 >= $GIO_UNIX_REQUIRED_VERSION - dbus-glib-1 >= $DBUS_REQUIRED_VERSION) + gio-unix-2.0 >= $GIO_UNIX_REQUIRED_VERSION) AC_SUBST(LIBINDICATOR_CFLAGS) AC_SUBST(LIBINDICATOR_LIBS) ], -- cgit v1.2.3 From 977ed233111f24e8ef2213d35ec86a6a3fdc981e Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 10:18:42 -0600 Subject: Changing the way the dbus xml is handled. --- libindicator/Makefile.am | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/libindicator/Makefile.am b/libindicator/Makefile.am index 39cb2b7..9f2a222 100644 --- a/libindicator/Makefile.am +++ b/libindicator/Makefile.am @@ -31,6 +31,8 @@ libindicatorinclude_HEADERS = \ libindicator_la_SOURCES = \ $(indicator_headers) \ dbus-shared.h \ + gen-indicator-service.xml.h \ + gen-indicator-service.xml.c \ indicator-object.c \ indicator-object-enum-types.c \ indicator-desktop-shortcuts.c \ @@ -100,23 +102,19 @@ CLEANFILES += \ DBUS_SPECS = \ indicator-service.xml -%-client.h: %.xml - dbus-binding-tool \ - --prefix=_$(subst -,_,$(basename $(notdir $<)))_client \ - --mode=glib-client \ - --output=$@ \ - $< +gen-%.xml.h: %.xml + @echo "Building $@ from $<" + @echo "extern const char * _$(subst -,_,$(subst .,_,$(basename $<)));" > $@ -%-server.h: %.xml - dbus-binding-tool \ - --prefix=_$(subst -,_,$(basename $(notdir $<)))_server \ - --mode=glib-server \ - --output=$@ \ - $< +gen-%.xml.c: %.xml + @echo "Building $@ from $<" + @echo "const char * _$(subst -,_,$(subst .,_,$(basename $<))) = " > $@ + @sed -e "s:\":\\\\\":g" -e s:^:\": -e s:\$$:\\\\n\": $< >> $@ + @echo ";" >> $@ BUILT_SOURCES += \ - $(DBUS_SPECS:.xml=-client.h) \ - $(DBUS_SPECS:.xml=-server.h) + gen-indicator-service.xml.h \ + gen-indicator-service.xml.c CLEANFILES += $(BUILT_SOURCES) -- cgit v1.2.3 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 --- libindicator/indicator-service.c | 2 -- 2 files changed, 5 deletions(-) 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" 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(-) 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(-) 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(-) 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(-) 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(-) 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(-) 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(-) 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(-) 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(-) 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 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(-) 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(-) 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 a6e9bff1b41ddba73ec3ddf9946024f8404d6c0f Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 7 Jan 2011 20:01:37 -0600 Subject: Ignoring the new files --- .bzrignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.bzrignore b/.bzrignore index 1c213cf..5f78c4a 100644 --- a/.bzrignore +++ b/.bzrignore @@ -169,3 +169,6 @@ libindicator/libindicator3_la-indicator-service-manager.lo libindicator/libindicator3_la-indicator-service.lo libindicator/libindicator_la-indicator-object-enum-types.lo libindicator/s-enum-types-h +libindicator/gen-indicator-service.xml.c +libindicator/gen-indicator-service.xml.h +libindicator/libindicator_la-gen-indicator-service.xml.lo -- 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(-) 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(+) 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(-) 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 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(-) 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(-) 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 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(-) 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(-) 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(-) 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