From 529ce66c4498e661281b83852cfbde03a918956e Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 15 Jan 2010 15:04:20 -0600 Subject: API changes required to have locations for the entries. --- libindicator/indicator-object.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'libindicator') diff --git a/libindicator/indicator-object.h b/libindicator/indicator-object.h index c100d02..0356d1c 100644 --- a/libindicator/indicator-object.h +++ b/libindicator/indicator-object.h @@ -40,6 +40,8 @@ G_BEGIN_DECLS #define INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED_ID (g_signal_lookup(INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED, INDICATOR_OBJECT_TYPE)) #define INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED "entry-removed" #define INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED_ID (g_signal_lookup(INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED, INDICATOR_OBJECT_TYPE)) +#define INDICATOR_OBJECT_SIGNAL_ENTRY_MOVED "entry-moved" +#define INDICATOR_OBJECT_SIGNAL_ENTRY_MOVED_ID (g_signal_lookup(INDICATOR_OBJECT_SIGNAL_ENTRY_MOVED, INDICATOR_OBJECT_TYPE)) typedef struct _IndicatorObject IndicatorObject; typedef struct _IndicatorObjectClass IndicatorObjectClass; @@ -62,12 +64,14 @@ typedef struct _IndicatorObjectEntry IndicatorObjectEntry; a #GList of #IndicatorObjectEntries. The list should be under the ownership of the caller but the entires will not be. + @get_location: Returns the location that a particular entry + should be placed in. This is really only relevant for + indicators that have more than one entry. @entry_added: Slot for #IndicatorObject::entry-added @entry_removed: Slot for #IndicatorObject::entry-removed + @entry_moved: Slot for #IndicatorObject::entry-moved @indicator_object_reserved_1: Reserved for future use @indicator_object_reserved_2: Reserved for future use - @indicator_object_reserved_3: Reserved for future use - @indicator_object_reserved_4: Reserved for future use */ struct _IndicatorObjectClass { GObjectClass parent_class; @@ -78,16 +82,16 @@ struct _IndicatorObjectClass { GtkMenu * (*get_menu) (IndicatorObject * io); GList * (*get_entries) (IndicatorObject * io); + guint (*get_location) (IndicatorObject * io, IndicatorObjectEntry * entry); /* Signals */ void (*entry_added) (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer user_data); void (*entry_removed) (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer user_data); + void (*entry_moved) (IndicatorObject * io, IndicatorObjectEntry * entry, guint old_pos, guint new_pos, gpointer user_data); /* Reserved */ void (* indicator_object_reserved_1) (void); void (* indicator_object_reserved_2) (void); - void (* indicator_object_reserved_3) (void); - void (* indicator_object_reserved_4) (void); }; /** @@ -117,6 +121,7 @@ GType indicator_object_get_type (void); IndicatorObject * indicator_object_new_from_file (const gchar * file); GList * indicator_object_get_entries (IndicatorObject * io); +guint indicator_object_get_location (IndicatorObject * io, IndicatorObjectEntry * entry); G_END_DECLS -- cgit v1.2.3 From 14b58238f792f17285dc61c6adb00ca764a5a3b6 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 15 Jan 2010 15:16:30 -0600 Subject: Setting up the move signal, which required custom marshallers. --- libindicator/Makefile.am | 8 ++++++++ libindicator/indicator-object-marshal.list | 1 + libindicator/indicator-object.c | 16 ++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 libindicator/indicator-object-marshal.list (limited to 'libindicator') diff --git a/libindicator/Makefile.am b/libindicator/Makefile.am index 6d5c627..19247ce 100644 --- a/libindicator/Makefile.am +++ b/libindicator/Makefile.am @@ -1,8 +1,11 @@ BUILT_SOURCES = CLEANFILES = +DISTCLEANFILES = EXTRA_DIST = \ indicator.pc.in +include $(top_srcdir)/Makefile.am.marshal + libindicatorincludedir=$(includedir)/libindicator-0.3/libindicator indicator_headers = \ @@ -21,6 +24,8 @@ libindicator_la_SOURCES = \ $(indicator_headers) \ dbus-shared.h \ indicator-object.c \ + indicator-object-marshal.h \ + indicator-object-marshal.c \ indicator-service.c \ indicator-service-manager.c @@ -35,6 +40,9 @@ libindicator_la_LIBADD = \ pkgconfig_DATA = indicator.pc pkgconfigdir = $(libdir)/pkgconfig +glib_marshal_list = indicator-object-marshal.list +glib_marshal_prefix = _indicator_object_marshal + ################################## # DBus Specs ################################## diff --git a/libindicator/indicator-object-marshal.list b/libindicator/indicator-object-marshal.list new file mode 100644 index 0000000..5c11033 --- /dev/null +++ b/libindicator/indicator-object-marshal.list @@ -0,0 +1 @@ +VOID: POINTER, UINT, UINT diff --git a/libindicator/indicator-object.c b/libindicator/indicator-object.c index e87fa5f..8e1edef 100644 --- a/libindicator/indicator-object.c +++ b/libindicator/indicator-object.c @@ -27,6 +27,7 @@ License along with this library. If not, see #include "indicator.h" #include "indicator-object.h" +#include "indicator-object-marshal.h" /** IndicatorObjectPrivate: @@ -54,6 +55,7 @@ struct _IndicatorObjectPrivate { enum { ENTRY_ADDED, ENTRY_REMOVED, + ENTRY_MOVED, LAST_SIGNAL }; @@ -116,6 +118,20 @@ indicator_object_class_init (IndicatorObjectClass *klass) NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER, G_TYPE_NONE); + /** + IndicatorObject::entry-moved: + @arg0: The #IndicatorObject object + + Signaled when an entry is removed and should + be removed by the person using this object. + */ + signals[ENTRY_MOVED] = g_signal_new (INDICATOR_OBJECT_SIGNAL_ENTRY_MOVED, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IndicatorObjectClass, entry_moved), + NULL, NULL, + _indicator_object_marshal_VOID__POINTER_UINT_UINT, + G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_NONE); return; } -- cgit v1.2.3 From d334db5071495817e9dea5b50a2fc27709058410 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 15 Jan 2010 15:28:31 -0600 Subject: Fixing the signal comments. --- libindicator/indicator-object.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'libindicator') diff --git a/libindicator/indicator-object.c b/libindicator/indicator-object.c index 8e1edef..3b00c97 100644 --- a/libindicator/indicator-object.c +++ b/libindicator/indicator-object.c @@ -92,7 +92,9 @@ indicator_object_class_init (IndicatorObjectClass *klass) /** IndicatorObject::entry-added: @arg0: The #IndicatorObject object - + @arg1: A pointer to the #IndicatorObjectEntry that + is being added. + Signaled when a new entry is added and should be shown by the person using this object. */ @@ -107,7 +109,9 @@ indicator_object_class_init (IndicatorObjectClass *klass) /** IndicatorObject::entry-removed: @arg0: The #IndicatorObject object - + @arg1: A pointer to the #IndicatorObjectEntry that + is being removed. + Signaled when an entry is removed and should be removed by the person using this object. */ @@ -121,9 +125,13 @@ indicator_object_class_init (IndicatorObjectClass *klass) /** IndicatorObject::entry-moved: @arg0: The #IndicatorObject object - - Signaled when an entry is removed and should - be removed by the person using this object. + @arg1: A pointer to the #IndicatorObjectEntry that + is being moved. + @arg2: The old location of the entry + @arg3: The new location of the entry + + When the order of the entries change, then this signal + is sent to tell the new location. */ signals[ENTRY_MOVED] = g_signal_new (INDICATOR_OBJECT_SIGNAL_ENTRY_MOVED, G_TYPE_FROM_CLASS(klass), -- cgit v1.2.3 From 308e4db1bc070b6f548817fa6fe9297e64434613 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 15 Jan 2010 15:35:55 -0600 Subject: Fleshing out the get_location function as much as they're implemented here. --- libindicator/indicator-object.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'libindicator') diff --git a/libindicator/indicator-object.c b/libindicator/indicator-object.c index 3b00c97..f186a4f 100644 --- a/libindicator/indicator-object.c +++ b/libindicator/indicator-object.c @@ -88,6 +88,7 @@ indicator_object_class_init (IndicatorObjectClass *klass) klass->get_image = NULL; klass->get_entries = get_entries_default; + klass->get_location = NULL; /** IndicatorObject::entry-added: @@ -366,3 +367,29 @@ indicator_object_get_entries (IndicatorObject * io) g_error("No get_entries function on object. It must have been deleted?!?!"); return NULL; } + +/** + indicator_object_get_location: + @io: #IndicatorObject to query + @entry: The #IndicatorObjectEntry to look for. + + This function looks on the class for the object and calls + it's #IndicatorObjectClass::get_location function. If the + function doesn't exist it returns zero. + + Return value: Location of the @entry in the display or + zero if no location is specified. +*/ +guint +indicator_object_get_location (IndicatorObject * io, IndicatorObjectEntry * entry) +{ + g_return_val_if_fail(INDICATOR_IS_OBJECT(io), 0); + IndicatorObjectClass * class = INDICATOR_OBJECT_GET_CLASS(io); + + if (class->get_location) { + return class->get_location(io, entry); + } + + g_error("No get_entries function on object. It must have been deleted?!?!"); + return 0; +} -- cgit v1.2.3 From c25db995a7c12f9b0460e903633d01926c9b4aed Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 15 Jan 2010 16:08:35 -0600 Subject: No error on not having a get_location function. We'll just return zero. --- libindicator/indicator-object.c | 1 - 1 file changed, 1 deletion(-) (limited to 'libindicator') diff --git a/libindicator/indicator-object.c b/libindicator/indicator-object.c index f186a4f..87cd648 100644 --- a/libindicator/indicator-object.c +++ b/libindicator/indicator-object.c @@ -390,6 +390,5 @@ indicator_object_get_location (IndicatorObject * io, IndicatorObjectEntry * entr return class->get_location(io, entry); } - g_error("No get_entries function on object. It must have been deleted?!?!"); return 0; } -- cgit v1.2.3 From 41559b3cc70cffacc023a6a21cca41b5b1070447 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 15 Jan 2010 19:54:42 -0600 Subject: Getting a multiplier, and providing a way to override it using an environment variable. --- libindicator/indicator-service-manager.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'libindicator') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index 69b1343..ee29767 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -25,6 +25,8 @@ License along with this library. If not, see #include "config.h" #endif +#include + #include #include @@ -60,6 +62,10 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; +/* We multiply our timeouts by in ms. This can be overriden by + the environment variable INDICATOR_SERVICE_RESTART_TIMEOUT. */ +static guint timeout_multiplier = 100; +#define TIMEOUT_ENV_NAME "INDICATOR_SERVICE_RESTART_TIMEOUT" /* Properties */ /* Enum for the properties so that they can be quickly @@ -136,6 +142,15 @@ indicator_service_manager_class_init (IndicatorServiceManagerClass *klass) 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /* Look to see if there is an environment variable effecting + the restart interval. This is in the class init as it should + only happen once. */ + const gchar * restart_env = g_getenv(TIMEOUT_ENV_NAME); + if (restart_env != NULL) { + timeout_multiplier = atoi(restart_env); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Time out multipler set to: %d", timeout_multiplier); + } + return; } -- cgit v1.2.3 From b9344c35f45a52ab15462746998d1b11b63e5928 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 15 Jan 2010 20:38:04 -0600 Subject: Reset the restart_count when we start, and start to bring in 'start_service_again' to begin to throttle the restarts. --- libindicator/indicator-service-manager.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'libindicator') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index ee29767..6c6dca9 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -43,6 +43,7 @@ License along with this library. If not, see @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 { @@ -52,6 +53,7 @@ struct _IndicatorServiceManagerPrivate { gboolean connected; guint this_service_version; DBusGConnection * bus; + guint restart_count; }; /* Signals Stuff */ @@ -93,6 +95,7 @@ static void indicator_service_manager_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 start_service (IndicatorServiceManager * service); +static void start_service_again (IndicatorServiceManager * manager); G_DEFINE_TYPE (IndicatorServiceManager, indicator_service_manager, G_TYPE_OBJECT); @@ -169,6 +172,7 @@ indicator_service_manager_init (IndicatorServiceManager *self) priv->connected = FALSE; priv->this_service_version = 0; priv->bus = NULL; + priv->restart_count = 0; /* Start talkin' dbus */ GError * error = NULL; @@ -327,6 +331,12 @@ watch_cb (DBusGProxy * proxy, guint service_api_version, guint this_service_vers return; } + /* 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 + drop and we can start another service quickly. */ + priv->restart_count = 0; + 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); @@ -358,11 +368,13 @@ start_service_cb (DBusGProxy * proxy, guint status, GError * error, gpointer use 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; } @@ -423,6 +435,18 @@ start_service (IndicatorServiceManager * service) return; } +/* This function tries to start a new service, perhaps + after a timeout that it determines. The real issue + here is that it throttles restarting if we're not + being successful. */ +static void +start_service_again (IndicatorServiceManager * manager) +{ + + + return; +} + /* API */ /** -- cgit v1.2.3 From 2ce95b0279e75123beef7cdc1b440b03ffb56c55 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 15 Jan 2010 21:15:30 -0600 Subject: Filling out the function to start it again, and adding in the function to respond to the timeout. --- libindicator/indicator-service-manager.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'libindicator') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index 6c6dca9..0c552d4 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -435,6 +435,18 @@ start_service (IndicatorServiceManager * service) return; } +/* The callback that starts the service for real after + the timeout as determined in 'start_service_again'. + This could be in the idle or a timer. */ +static gboolean +start_service_again_cb (gpointer data) +{ + IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(data); + priv->restart_count++; + start_service(INDICATOR_SERVICE_MANAGER(data)); + return FALSE; +} + /* This function tries to start a new service, perhaps after a timeout that it determines. The real issue here is that it throttles restarting if we're not @@ -442,7 +454,17 @@ start_service (IndicatorServiceManager * service) static void start_service_again (IndicatorServiceManager * manager) { + IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(manager); + if (priv->restart_count == 0) { + /* First time, do it in idle */ + g_idle_add(start_service_again_cb, manager); + } else { + /* Not our first time 'round the block. Let's slow this down. */ + if (priv->restart_count > 16) + priv->restart_count = 16; /* Not more than 1024x */ + g_timeout_add((1 << priv->restart_count) * timeout_multiplier, start_service_again_cb, manager); + } return; } -- cgit v1.2.3 From 9bccc146b8f1ee955d713fec30d7f5faf2ce88c1 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 15 Jan 2010 21:25:48 -0600 Subject: Setting up the signal for when the proxies falls down, we restart. --- libindicator/indicator-service-manager.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'libindicator') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index 0c552d4..1a8db07 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -94,6 +94,7 @@ 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); @@ -385,6 +386,7 @@ start_service_cb (DBusGProxy * proxy, guint status, GError * error, gpointer use INDICATOR_SERVICE_INTERFACE, &error); 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, @@ -423,6 +425,7 @@ start_service (IndicatorServiceManager * service) 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' @@ -435,6 +438,14 @@ start_service (IndicatorServiceManager * service) return; } +/* Responds to the destory event of the proxy and starts + setting up to restart the service. */ +static void +service_proxy_destroyed (DBusGProxy * proxy, gpointer user_data) +{ + return start_service_again(INDICATOR_SERVICE_MANAGER(user_data)); +} + /* The callback that starts the service for real after the timeout as determined in 'start_service_again'. This could be in the idle or a timer. */ -- cgit v1.2.3 From deabfe64bf3b306c1c068665c4d8324dee7f5435 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 15 Jan 2010 21:40:03 -0600 Subject: Switching what our enviroment variable is for, let's just stop the whole thing instead of playing with it. --- libindicator/indicator-service-manager.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'libindicator') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index 1a8db07..42160ee 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -64,10 +64,9 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -/* We multiply our timeouts by in ms. This can be overriden by - the environment variable INDICATOR_SERVICE_RESTART_TIMEOUT. */ -static guint timeout_multiplier = 100; -#define TIMEOUT_ENV_NAME "INDICATOR_SERVICE_RESTART_TIMEOUT" +/* If this env variable is set, we don't restart */ +#define TIMEOUT_ENV_NAME "INDICATOR_SERVICE_RESTART_DISABLE" +#define TIMEOUT_MULTIPLIER 100 /* In ms */ /* Properties */ /* Enum for the properties so that they can be quickly @@ -146,15 +145,6 @@ indicator_service_manager_class_init (IndicatorServiceManagerClass *klass) 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /* Look to see if there is an environment variable effecting - the restart interval. This is in the class init as it should - only happen once. */ - const gchar * restart_env = g_getenv(TIMEOUT_ENV_NAME); - if (restart_env != NULL) { - timeout_multiplier = atoi(restart_env); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Time out multipler set to: %d", timeout_multiplier); - } - return; } @@ -465,6 +455,11 @@ start_service_again_cb (gpointer data) static void start_service_again (IndicatorServiceManager * manager) { + /* Allow the restarting to be disabled */ + if (g_getenv(TIMEOUT_ENV_NAME)) { + return; + } + IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(manager); if (priv->restart_count == 0) { @@ -474,7 +469,7 @@ start_service_again (IndicatorServiceManager * manager) /* Not our first time 'round the block. Let's slow this down. */ if (priv->restart_count > 16) priv->restart_count = 16; /* Not more than 1024x */ - g_timeout_add((1 << priv->restart_count) * timeout_multiplier, start_service_again_cb, manager); + g_timeout_add((1 << priv->restart_count) * TIMEOUT_MULTIPLIER, start_service_again_cb, manager); } return; -- cgit v1.2.3 From 62d8c1c86b21ab250342900324565f1b95ac2da8 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 15 Jan 2010 22:16:45 -0600 Subject: Handling the connected signal as well, making sure we emit it. --- libindicator/indicator-service-manager.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'libindicator') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index 42160ee..9d56a9f 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -455,18 +455,24 @@ start_service_again_cb (gpointer data) static void start_service_again (IndicatorServiceManager * manager) { + IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(manager); + /* Allow the restarting to be disabled */ if (g_getenv(TIMEOUT_ENV_NAME)) { + priv->connected = FALSE; + g_signal_emit(manager, signals[CONNECTION_CHANGE], 0, FALSE, TRUE); return; } - IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(manager); - if (priv->restart_count == 0) { /* First time, do it in idle */ g_idle_add(start_service_again_cb, manager); } else { /* Not our first time 'round the block. Let's slow this down. */ + if (priv->connected) { + priv->connected = FALSE; + g_signal_emit(manager, signals[CONNECTION_CHANGE], 0, FALSE, TRUE); + } if (priv->restart_count > 16) priv->restart_count = 16; /* Not more than 1024x */ g_timeout_add((1 << priv->restart_count) * TIMEOUT_MULTIPLIER, start_service_again_cb, manager); -- cgit v1.2.3 From 079c2b517deba95385ac47eea1fd6560aef3aacb Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Fri, 15 Jan 2010 22:28:13 -0600 Subject: It's a fundamental mistake to believe that we can protect people using this interface from the disconnection. We have no information to say that the new service starting will come up in the same state as the one before it. We need the individual implementers to verify that. Now we need to fix that. This commit does so. --- libindicator/indicator-service-manager.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'libindicator') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index 9d56a9f..891f49e 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -433,6 +433,11 @@ start_service (IndicatorServiceManager * service) static void service_proxy_destroyed (DBusGProxy * proxy, 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); + } return start_service_again(INDICATOR_SERVICE_MANAGER(user_data)); } @@ -459,8 +464,6 @@ start_service_again (IndicatorServiceManager * manager) /* Allow the restarting to be disabled */ if (g_getenv(TIMEOUT_ENV_NAME)) { - priv->connected = FALSE; - g_signal_emit(manager, signals[CONNECTION_CHANGE], 0, FALSE, TRUE); return; } @@ -469,10 +472,6 @@ start_service_again (IndicatorServiceManager * manager) g_idle_add(start_service_again_cb, manager); } else { /* Not our first time 'round the block. Let's slow this down. */ - if (priv->connected) { - priv->connected = FALSE; - g_signal_emit(manager, signals[CONNECTION_CHANGE], 0, FALSE, TRUE); - } if (priv->restart_count > 16) priv->restart_count = 16; /* Not more than 1024x */ g_timeout_add((1 << priv->restart_count) * TIMEOUT_MULTIPLIER, start_service_again_cb, manager); -- cgit v1.2.3 From c72ff4f03fb1fb7c28c2c8c5dda429dc12f45cd5 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 21 Jan 2010 09:49:02 -0600 Subject: Setting up the watch_cb function so that in errors it'll try to restart. As most errors will be fixed by trying again. --- libindicator/indicator-service-manager.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'libindicator') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index 891f49e..a06e192 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -67,6 +67,10 @@ static guint signals[LAST_SIGNAL] = { 0 }; /* If this env variable is set, we don't restart */ #define TIMEOUT_ENV_NAME "INDICATOR_SERVICE_RESTART_DISABLE" #define TIMEOUT_MULTIPLIER 100 /* In ms */ +/* What to reset the restart_count to if we know that we're + in a recoverable error condition, but waiting a little bit + will probably make things better. 5 ~= 3 sec. */ +#define TIMEOUT_A_LITTLE_WHILE 5 /* Properties */ /* Enum for the properties so that they can be quickly @@ -319,6 +323,7 @@ watch_cb (DBusGProxy * proxy, guint service_api_version, guint this_service_vers if (error != NULL) { g_warning("Unable to set watch on '%s': '%s'", priv->name, error->message); g_error_free(error); + start_service_again(INDICATOR_SERVICE_MANAGER(user_data)); return; } @@ -331,12 +336,20 @@ 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); + + /* Let's make us wait a little while, then try again */ + priv->restart_count = TIMEOUT_A_LITTLE_WHILE; + start_service_again(INDICATOR_SERVICE_MANAGER(user_data)); return; } 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); + + /* Let's make us wait a little while, then try again */ + priv->restart_count = TIMEOUT_A_LITTLE_WHILE; + start_service_again(INDICATOR_SERVICE_MANAGER(user_data)); return; } -- cgit v1.2.3 From 4a7af569bd96c25cbf028fd7144fd2f5d6262a3c Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 21 Jan 2010 10:25:27 -0600 Subject: In case we're restarting because of the 'Watch' returning failure we'd have a valid 'service_proxy' object to kill --- libindicator/indicator-service-manager.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'libindicator') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index a06e192..5d1bd91 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -411,6 +411,11 @@ start_service (IndicatorServiceManager * service) g_return_if_fail(priv->dbus_proxy != NULL); g_return_if_fail(priv->name != NULL); + if (priv->service_proxy != NULL) { + g_object_unref(priv->service_proxy); + 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, -- cgit v1.2.3 From 0219e0e7d51086cc691367e8deda356ac2b6aabc Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 21 Jan 2010 10:30:52 -0600 Subject: Adding in tracking of the restart idle function and making sure we don't do it twice. --- libindicator/indicator-service-manager.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'libindicator') diff --git a/libindicator/indicator-service-manager.c b/libindicator/indicator-service-manager.c index 5d1bd91..7bb9a9b 100644 --- a/libindicator/indicator-service-manager.c +++ b/libindicator/indicator-service-manager.c @@ -54,6 +54,7 @@ struct _IndicatorServiceManagerPrivate { guint this_service_version; DBusGConnection * bus; guint restart_count; + gint restart_source; }; /* Signals Stuff */ @@ -168,6 +169,7 @@ indicator_service_manager_init (IndicatorServiceManager *self) priv->this_service_version = 0; priv->bus = NULL; priv->restart_count = 0; + priv->restart_source = 0; /* Start talkin' dbus */ GError * error = NULL; @@ -201,6 +203,13 @@ indicator_service_manager_dispose (GObject *object) { IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(object); + /* Removing the idle task to restart if it exists. */ + if (priv->restart_source != 0) { + g_source_remove(priv->restart_source); + } + /* Block any restart calls */ + priv->restart_source = -1; + /* If we were connected we need to make sure to tell people that it's no longer the case. */ if (priv->connected) { @@ -468,6 +477,7 @@ start_service_again_cb (gpointer data) IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(data); priv->restart_count++; start_service(INDICATOR_SERVICE_MANAGER(data)); + priv->restart_source = 0; return FALSE; } @@ -480,6 +490,12 @@ start_service_again (IndicatorServiceManager * manager) { IndicatorServiceManagerPrivate * priv = INDICATOR_SERVICE_MANAGER_GET_PRIVATE(manager); + /* If we've already got a restart source running then + let's not do this again. */ + if (priv->restart_source != 0) { + return; + } + /* Allow the restarting to be disabled */ if (g_getenv(TIMEOUT_ENV_NAME)) { return; @@ -492,7 +508,7 @@ start_service_again (IndicatorServiceManager * manager) /* Not our first time 'round the block. Let's slow this down. */ if (priv->restart_count > 16) priv->restart_count = 16; /* Not more than 1024x */ - g_timeout_add((1 << priv->restart_count) * TIMEOUT_MULTIPLIER, start_service_again_cb, manager); + priv->restart_source = g_timeout_add((1 << priv->restart_count) * TIMEOUT_MULTIPLIER, start_service_again_cb, manager); } return; -- cgit v1.2.3