Merge lp:~a-j-buxton/libindicator/remove-timeout into lp:libindicator/14.04

Proposed by Alistair Buxton
Status: Needs review
Proposed branch: lp:~a-j-buxton/libindicator/remove-timeout
Merge into: lp:libindicator/14.04
Diff against target: 175 lines (+4/-81)
1 file modified
libindicator/indicator-service.c (+4/-81)
To merge this branch: bzr merge lp:~a-j-buxton/libindicator/remove-timeout
Reviewer Review Type Date Requested Status
Ted Gould Pending
Review via email: mp+198070@code.launchpad.net

Description of the change

This removes the timeout shutdown code from indicator-service.

This code was intended to allow the services to shut down automatically when using dbus activation and nothing was using the service any more. Indicators are now started by upstart or xdg-autostart, and this code becomes a problem. If the indicator is started by upstart and it exits, upstart will just keep running it again and again until it kills the job "respawning too fast". If the service was started by xdg-autostart and it decides to exit, nothing will start it again. This leads to indicators mysteriously disappearing from the panel, or never loading up in the first place due to race conditions.

If you haven't, please also see:

https://code.launchpad.net/~ted/libindicator/upstart-no-dbus/+merge/166269

This is another MR on libindicator dealing with the upstart changes, but as far as I can tell it does not deal with this specific issue.

To post a comment you must log in.

Unmerged revisions

519. By Alistair Buxton

Remove the shutdown timeout.

Since indicators are now started by upstart, and not on demand, this
code is not needed.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libindicator/indicator-service.c'
2--- libindicator/indicator-service.c 2013-10-24 02:08:35 +0000
3+++ libindicator/indicator-service.c 2013-12-06 14:39:26 +0000
4@@ -42,7 +42,6 @@
5 /**
6 IndicatorSevicePrivate:
7 @name: The DBus well known name for the service.
8- @timeout: The source ID for the timeout event.
9 @watcher: A list of processes on dbus that are watching us.
10 @this_service_version: The version to hand out that we're
11 implementing. May not be set, so we'll send zero (default).
12@@ -54,8 +53,6 @@
13 gchar * name;
14 GDBusConnection * bus;
15 GCancellable * bus_cancel;
16- guint timeout;
17- guint timeout_length;
18 GHashTable * watchers;
19 guint this_service_version;
20 guint dbus_registration;
21@@ -188,24 +185,13 @@
22
23 /* Get the private variables in a decent state */
24 priv->name = NULL;
25- priv->timeout = 0;
26 priv->watchers = NULL;
27 priv->bus = NULL;
28 priv->bus_cancel = NULL;
29 priv->this_service_version = 0;
30- priv->timeout_length = 500;
31 priv->dbus_registration = 0;
32 priv->replace_mode = FALSE;
33
34- const gchar * timeoutenv = g_getenv("INDICATOR_SERVICE_SHUTDOWN_TIMEOUT");
35- if (timeoutenv != NULL) {
36- gdouble newtimeout = g_strtod(timeoutenv, NULL);
37- if (newtimeout >= 1.0f) {
38- priv->timeout_length = newtimeout;
39- g_debug("Setting shutdown timeout to: %u", priv->timeout_length);
40- }
41- }
42-
43 const gchar * replaceenv = g_getenv("INDICATOR_SERVICE_REPLACE_MODE");
44 if (replaceenv != NULL) {
45 priv->replace_mode = TRUE;
46@@ -226,8 +212,7 @@
47 return;
48 }
49
50-/* Unrefcounting the proxies and making sure that our
51- timeout doesn't come to haunt us. */
52+/* Unrefcounting the proxies. */
53 static void
54 indicator_service_dispose (GObject *object)
55 {
56@@ -235,11 +220,6 @@
57
58 g_clear_pointer (&priv->watchers, g_hash_table_destroy);
59
60- if (priv->timeout != 0) {
61- g_source_remove(priv->timeout);
62- priv->timeout = 0;
63- }
64-
65 if (priv->dbus_registration != 0) {
66 g_dbus_connection_unregister_object(priv->bus, priv->dbus_registration);
67 /* Don't care if it fails, there's nothing we can do */
68@@ -415,43 +395,14 @@
69 return;
70 }
71
72-/* This is the function that gets executed if we timeout
73- because there are no watchers. We sent the shutdown
74- signal and hope someone does something sane with it. */
75-static gboolean
76-timeout_no_watchers (gpointer data)
77-{
78- g_warning("No watchers, service timing out.");
79- if (g_getenv("INDICATOR_ALLOW_NO_WATCHERS") == NULL) {
80- g_signal_emit(G_OBJECT(data), signals[SHUTDOWN], 0, TRUE);
81- } else {
82- g_warning("\tblocked by environment variable.");
83- }
84- return FALSE;
85-}
86-
87 /* Callback saying that the name we were looking for has been
88- found and we've got it. Now start the timer to see if anyone
89- cares about us. */
90+ found and we've got it. */
91 static void
92 try_and_get_name_acquired_cb (GDBusConnection * connection, const gchar * name, gpointer user_data)
93 {
94 g_return_if_fail(connection != NULL);
95 g_return_if_fail(INDICATOR_IS_SERVICE(user_data));
96
97- IndicatorServicePrivate * priv = INDICATOR_SERVICE_GET_PRIVATE(user_data);
98-
99- /* Check to see if we already had a timer, if so we want to
100- extend it a bit. */
101- if (priv->timeout != 0) {
102- g_source_remove(priv->timeout);
103- priv->timeout = 0;
104- }
105-
106- /* Allow some extra time at start up as things can be in high
107- contention then. */
108- priv->timeout = g_timeout_add(priv->timeout_length * 2, timeout_no_watchers, user_data);
109-
110 return;
111 }
112
113@@ -480,15 +431,6 @@
114
115 g_dbus_connection_send_message(connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL);
116 g_object_unref(message);
117-
118- /* Check to see if we need to clean up a timeout */
119- if (priv->timeout != 0) {
120- g_source_remove(priv->timeout);
121- priv->timeout = 0;
122- }
123-
124- /* Set a timeout for no watchers if we can't get the name */
125- priv->timeout = g_timeout_add(priv->timeout_length * 4, timeout_no_watchers, user_data);
126 }
127
128 return;
129@@ -534,7 +476,7 @@
130 /* Here is the function that gets called by the dbus
131 interface "Watch" function. It is an async function so
132 that we can get the sender and store that information. We
133- put them in a list and reset the timeout. */
134+ put them in a list. */
135 static GVariant *
136 bus_watch (IndicatorService * service, const gchar * sender)
137 {
138@@ -557,17 +499,11 @@
139 }
140 }
141
142- if (priv->timeout != 0) {
143- g_source_remove(priv->timeout);
144- priv->timeout = 0;
145- }
146-
147 return g_variant_new("(uu)", INDICATOR_SERVICE_VERSION, priv->this_service_version);
148 }
149
150 /* Performs the core of loosing a watcher; it removes them
151- from the list of watchers. If there are none left, it then
152- starts the timer for the shutdown signal. */
153+ from the list of watchers. */
154 static void
155 unwatch_core (IndicatorService * service, const gchar * name)
156 {
157@@ -587,19 +523,6 @@
158 g_warning("Unable to find watcher who is unwatching: %s", name);
159 }
160
161- /* If we're out of watchers set the timeout for shutdown */
162- if (g_hash_table_size(priv->watchers) == 0) {
163- if (priv->timeout != 0) {
164- /* This should never really happen, but let's ensure that
165- bad things don't happen if it does. */
166- g_warning("No watchers timeout set twice. Resolving, but odd.");
167- g_source_remove(priv->timeout);
168- priv->timeout = 0;
169- }
170- /* If we don't get a new watcher quickly, we'll shutdown. */
171- priv->timeout = g_timeout_add(priv->timeout_length, timeout_no_watchers, service);
172- }
173-
174 return;
175 }
176

Subscribers

People subscribed via source and target branches