Merge lp:~victored/cerbere/session-manager-client into lp:~elementary-pantheon/cerbere/cerbere
- session-manager-client
- Merge into cerbere
Proposed by
Victor Martinez
Status: | Merged |
---|---|
Merged at revision: | 30 |
Proposed branch: | lp:~victored/cerbere/session-manager-client |
Merge into: | lp:~elementary-pantheon/cerbere/cerbere |
Diff against target: |
455 lines (+276/-32) 6 files modified
src/CMakeLists.txt (+5/-3) src/Cerbere.vala (+35/-3) src/ProcessInfo.vala (+6/-7) src/SessionManager.vala (+205/-0) src/SettingsManager.vala (+2/-2) src/Watchdog.vala (+23/-17) |
To merge this branch: | bzr merge lp:~victored/cerbere/session-manager-client |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Cody Garver (community) | Approve | ||
Review via email: mp+113806@code.launchpad.net |
Commit message
Description of the change
Say goodbye to the long desktop startup times ...
To post a comment you must log in.
Revision history for this message
Cody Garver (codygarver) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/CMakeLists.txt' | |||
2 | --- src/CMakeLists.txt 2012-06-14 22:29:47 +0000 | |||
3 | +++ src/CMakeLists.txt 2012-07-06 21:51:19 +0000 | |||
4 | @@ -16,6 +16,7 @@ | |||
5 | 16 | VALA_C | 16 | VALA_C |
6 | 17 | Cerbere.vala | 17 | Cerbere.vala |
7 | 18 | SettingsManager.vala | 18 | SettingsManager.vala |
8 | 19 | SessionManager.vala | ||
9 | 19 | Watchdog.vala | 20 | Watchdog.vala |
10 | 20 | ProcessInfo.vala | 21 | ProcessInfo.vala |
11 | 21 | PACKAGES | 22 | PACKAGES |
12 | @@ -26,6 +27,7 @@ | |||
13 | 26 | --target-glib=2.32 # Remember to keep this updated. | 27 | --target-glib=2.32 # Remember to keep this updated. |
14 | 27 | ) | 28 | ) |
15 | 28 | 29 | ||
19 | 29 | add_executable(cerbere ${VALA_C}) | 30 | set(EXEC_NAME ${CMAKE_PROJECT_NAME}) |
20 | 30 | target_link_libraries(cerbere ${DEPS_LIBRARIES}) | 31 | add_executable(${EXEC_NAME} ${VALA_C}) |
21 | 31 | install(TARGETS cerbere RUNTIME DESTINATION bin) | 32 | target_link_libraries(${EXEC_NAME} ${DEPS_LIBRARIES}) |
22 | 33 | install(TARGETS ${EXEC_NAME} RUNTIME DESTINATION bin) | ||
23 | 32 | 34 | ||
24 | === modified file 'src/Cerbere.vala' | |||
25 | --- src/Cerbere.vala 2012-06-14 22:28:44 +0000 | |||
26 | +++ src/Cerbere.vala 2012-07-06 21:51:19 +0000 | |||
27 | @@ -28,17 +28,28 @@ | |||
28 | 28 | public class Cerbere : Application { | 28 | public class Cerbere : Application { |
29 | 29 | 29 | ||
30 | 30 | public static SettingsManager settings { get; private set; default = null; } | 30 | public static SettingsManager settings { get; private set; default = null; } |
32 | 31 | private Watchdog watchdog; | 31 | private Watchdog? watchdog = null; |
33 | 32 | private SessionManager.ClientService? sm_client = null; | ||
34 | 32 | 33 | ||
35 | 33 | construct { | 34 | construct { |
36 | 34 | application_id = "org.pantheon.cerbere"; | 35 | application_id = "org.pantheon.cerbere"; |
37 | 35 | flags = ApplicationFlags.IS_SERVICE; | 36 | flags = ApplicationFlags.IS_SERVICE; |
38 | 37 | Log.set_handler (null, LogLevelFlags.LEVEL_MASK, log_handler); | ||
39 | 38 | } | ||
40 | 39 | |||
41 | 40 | private static void log_handler (string? domain, LogLevelFlags level, string message) { | ||
42 | 41 | if (level >= LogLevelFlags.LEVEL_INFO) | ||
43 | 42 | level = LogLevelFlags.LEVEL_MESSAGE; | ||
44 | 43 | Log.default_handler (domain, level, message); | ||
45 | 36 | } | 44 | } |
46 | 37 | 45 | ||
47 | 38 | protected override void startup () { | 46 | protected override void startup () { |
48 | 47 | // Try to register Cerbere with the session manager. | ||
49 | 48 | // This is a non-blocking action. | ||
50 | 49 | register_session_client_async (); | ||
51 | 50 | |||
52 | 39 | this.settings = new SettingsManager (); | 51 | this.settings = new SettingsManager (); |
55 | 40 | 52 | start_processes (this.settings.process_list); | |
54 | 41 | this.start_processes (this.settings.process_list); | ||
56 | 42 | 53 | ||
57 | 43 | // Monitor changes to the process list | 54 | // Monitor changes to the process list |
58 | 44 | this.settings.process_list_changed.connect (this.start_processes); | 55 | this.settings.process_list_changed.connect (this.start_processes); |
59 | @@ -47,6 +58,27 @@ | |||
60 | 47 | main_loop.run (); | 58 | main_loop.run (); |
61 | 48 | } | 59 | } |
62 | 49 | 60 | ||
63 | 61 | private async void register_session_client_async () { | ||
64 | 62 | if (this.sm_client != null) | ||
65 | 63 | return; | ||
66 | 64 | |||
67 | 65 | this.sm_client = new SessionManager.ClientService (this.application_id); | ||
68 | 66 | |||
69 | 67 | try { | ||
70 | 68 | this.sm_client.register (); | ||
71 | 69 | } catch (SessionManager.ConnectionError e) { | ||
72 | 70 | critical (e.message); | ||
73 | 71 | } | ||
74 | 72 | |||
75 | 73 | if (this.sm_client != null) { | ||
76 | 74 | // The session manager may ask us to quit the service, and so we do. | ||
77 | 75 | this.sm_client.stop_service.connect ( () => { | ||
78 | 76 | message ("Exiting..."); | ||
79 | 77 | this.quit_mainloop (); | ||
80 | 78 | }); | ||
81 | 79 | } | ||
82 | 80 | } | ||
83 | 81 | |||
84 | 50 | private void start_processes (string[] process_list) { | 82 | private void start_processes (string[] process_list) { |
85 | 51 | if (this.watchdog == null) { | 83 | if (this.watchdog == null) { |
86 | 52 | this.watchdog = new Watchdog (); | 84 | this.watchdog = new Watchdog (); |
87 | 53 | 85 | ||
88 | === modified file 'src/ProcessInfo.vala' | |||
89 | --- src/ProcessInfo.vala 2012-06-17 16:22:40 +0000 | |||
90 | +++ src/ProcessInfo.vala 2012-07-06 21:51:19 +0000 | |||
91 | @@ -43,7 +43,7 @@ | |||
92 | 43 | 43 | ||
93 | 44 | public void reset_crash_count () { | 44 | public void reset_crash_count () { |
94 | 45 | this.crash_count = 0; | 45 | this.crash_count = 0; |
96 | 46 | debug ("Crash count of '%s' has been reset", this.command); | 46 | message ("Crash count of '%s' has been reset", this.command); |
97 | 47 | } | 47 | } |
98 | 48 | 48 | ||
99 | 49 | public async void run_async () { | 49 | public async void run_async () { |
100 | @@ -51,10 +51,10 @@ | |||
101 | 51 | } | 51 | } |
102 | 52 | 52 | ||
103 | 53 | private void run () { | 53 | private void run () { |
105 | 54 | message ("STARTING process: %s", command); | 54 | debug ("STARTING process: %s", command); |
106 | 55 | 55 | ||
107 | 56 | if (this.status == Status.RUNNING) { | 56 | if (this.status == Status.RUNNING) { |
109 | 57 | message ("Process %s is already running", command); | 57 | warning ("Process %s is already running. Not starting it again...", command); |
110 | 58 | return; | 58 | return; |
111 | 59 | } | 59 | } |
112 | 60 | 60 | ||
113 | @@ -102,7 +102,7 @@ | |||
114 | 102 | if (pid != this.pid) | 102 | if (pid != this.pid) |
115 | 103 | return; | 103 | return; |
116 | 104 | 104 | ||
118 | 105 | message ("Process '%s' exited", command); | 105 | message ("Process '%s' watch exit", command); |
119 | 106 | 106 | ||
120 | 107 | // Check exit status | 107 | // Check exit status |
121 | 108 | if (Process.if_exited (status) || Process.if_signaled (status) || Process.core_dump (status)) { | 108 | if (Process.if_exited (status) || Process.if_signaled (status) || Process.core_dump (status)) { |
122 | @@ -126,13 +126,12 @@ | |||
123 | 126 | double elapsed_secs = this.timer.elapsed (); | 126 | double elapsed_secs = this.timer.elapsed (); |
124 | 127 | double crash_time_interval_secs = (double)Cerbere.settings.crash_time_interval / 1000.0; | 127 | double crash_time_interval_secs = (double)Cerbere.settings.crash_time_interval / 1000.0; |
125 | 128 | 128 | ||
128 | 129 | debug ("Elapsed time = %f secs", elapsed_secs); | 129 | message ("ET = %f secs\tMin allowed time = %f", elapsed_secs, crash_time_interval_secs); |
127 | 130 | debug ("Min allowed time = %f secs", crash_time_interval_secs); | ||
129 | 131 | 130 | ||
130 | 132 | if (elapsed_secs <= crash_time_interval_secs) { // process crashed | 131 | if (elapsed_secs <= crash_time_interval_secs) { // process crashed |
131 | 133 | this.crash_count ++; | 132 | this.crash_count ++; |
132 | 134 | normal_exit = false; | 133 | normal_exit = false; |
134 | 135 | message ("PROCESS '%s' CRASHED (#%u)", this.command, this.crash_count); | 134 | warning ("PROCESS '%s' CRASHED (#%u)", this.command, this.crash_count); |
135 | 136 | } | 135 | } |
136 | 137 | 136 | ||
137 | 138 | // Remove the current timer | 137 | // Remove the current timer |
138 | 139 | 138 | ||
139 | === added file 'src/SessionManager.vala' | |||
140 | --- src/SessionManager.vala 1970-01-01 00:00:00 +0000 | |||
141 | +++ src/SessionManager.vala 2012-07-06 21:51:19 +0000 | |||
142 | @@ -0,0 +1,205 @@ | |||
143 | 1 | /* -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*- */ | ||
144 | 2 | /* | ||
145 | 3 | * Copyright (C) 2012 Victor Eduardo <victoreduardm@gmail.com> | ||
146 | 4 | * | ||
147 | 5 | * Cerbere is free software; you can redistribute it and/or modify | ||
148 | 6 | * it under the terms of the GNU General Public License as published by | ||
149 | 7 | * the Free Software Foundation; either version 2 of the License, or | ||
150 | 8 | * (at your option) any later version. | ||
151 | 9 | * | ||
152 | 10 | * Cerbere is distributed in the hope that it will be useful, | ||
153 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
154 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
155 | 13 | * GNU General Public License for more details. | ||
156 | 14 | * | ||
157 | 15 | * You should have received a copy of the GNU General Public License | ||
158 | 16 | * along with Cerbere; if not, write to the Free Software | ||
159 | 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, | ||
160 | 18 | * Boston, MA 02110-1301 USA | ||
161 | 19 | * | ||
162 | 20 | * Authors: Victor Eduardo <victoreduardm@gmail.com> | ||
163 | 21 | */ | ||
164 | 22 | |||
165 | 23 | namespace SessionManager { | ||
166 | 24 | |||
167 | 25 | public errordomain ConnectionError { | ||
168 | 26 | CONNECTION_FAILED, | ||
169 | 27 | CLIENT_REGISTRATION_FAILED | ||
170 | 28 | } | ||
171 | 29 | |||
172 | 30 | |||
173 | 31 | /** | ||
174 | 32 | * GNOME Session Manager DBus API | ||
175 | 33 | * | ||
176 | 34 | * API Reference: [[http://www.gnome.org/~mccann/gnome-session/docs/gnome-session.html]] | ||
177 | 35 | * (Consulted on July 4, 2012.) | ||
178 | 36 | */ | ||
179 | 37 | |||
180 | 38 | private const string DBUS_NAME = "org.gnome.SessionManager"; | ||
181 | 39 | private const string DBUS_PATH = "/org/gnome/SessionManager"; | ||
182 | 40 | |||
183 | 41 | [DBus (name = "org.gnome.SessionManager")] | ||
184 | 42 | private interface SessionManager : Object { | ||
185 | 43 | // Many API methods have been left out. Feel free to add them when required. | ||
186 | 44 | public abstract void RegisterClient (string app_id, string client_startup_id, | ||
187 | 45 | out string client_id) throws IOError; | ||
188 | 46 | public abstract void UnregisterClient (ObjectPath client_id) throws IOError; | ||
189 | 47 | } | ||
190 | 48 | |||
191 | 49 | [DBus (name = "org.gnome.SessionManager.ClientPrivate")] | ||
192 | 50 | private interface ClientPrivate : Object { | ||
193 | 51 | public abstract void EndSessionResponse (bool is_ok, string reason) throws IOError; | ||
194 | 52 | public signal void QueryEndSession (uint flags); | ||
195 | 53 | public signal void EndSession (uint flags); | ||
196 | 54 | public signal void CancelEndSession (); | ||
197 | 55 | public signal void Stop (); | ||
198 | 56 | } | ||
199 | 57 | |||
200 | 58 | |||
201 | 59 | /** | ||
202 | 60 | * CLIENT | ||
203 | 61 | * | ||
204 | 62 | * This class handles both the registration of the service, | ||
205 | 63 | * and action requests coming from the session-manager side. | ||
206 | 64 | */ | ||
207 | 65 | |||
208 | 66 | public class ClientService : Object { | ||
209 | 67 | public signal void stop_service (); | ||
210 | 68 | |||
211 | 69 | private SessionManager? session_manager = null; | ||
212 | 70 | private ClientPrivate? client = null; | ||
213 | 71 | private string? client_id = null; | ||
214 | 72 | private string? app_id = null; | ||
215 | 73 | |||
216 | 74 | public ClientService (string app_id) { | ||
217 | 75 | this.app_id = app_id; | ||
218 | 76 | } | ||
219 | 77 | |||
220 | 78 | public void register () throws ConnectionError { | ||
221 | 79 | bool connected = true; | ||
222 | 80 | |||
223 | 81 | if (session_manager == null) { | ||
224 | 82 | connected = connect_session (); | ||
225 | 83 | |||
226 | 84 | if (!connected) { | ||
227 | 85 | throw new ConnectionError.CONNECTION_FAILED ("Could not connect to session manager"); | ||
228 | 86 | } | ||
229 | 87 | } | ||
230 | 88 | |||
231 | 89 | connected = register_client (); | ||
232 | 90 | |||
233 | 91 | if (!connected) { | ||
234 | 92 | // Disconnect from SM | ||
235 | 93 | session_manager = null; | ||
236 | 94 | throw new ConnectionError.CLIENT_REGISTRATION_FAILED ("Unable to register client with session manager"); | ||
237 | 95 | } | ||
238 | 96 | |||
239 | 97 | } | ||
240 | 98 | |||
241 | 99 | public void unregister () { | ||
242 | 100 | return_if_fail (session_manager != null && client_id != null); | ||
243 | 101 | |||
244 | 102 | debug ("Unregistering client: %s", client_id); | ||
245 | 103 | |||
246 | 104 | try { | ||
247 | 105 | session_manager.UnregisterClient (new ObjectPath (client_id)); | ||
248 | 106 | } catch (IOError e) { | ||
249 | 107 | critical (e.message); | ||
250 | 108 | } | ||
251 | 109 | } | ||
252 | 110 | |||
253 | 111 | private bool connect_session () { | ||
254 | 112 | if (session_manager == null) { | ||
255 | 113 | try { | ||
256 | 114 | session_manager = Bus.get_proxy_sync (BusType.SESSION, DBUS_NAME, DBUS_PATH); | ||
257 | 115 | } catch (IOError e) { | ||
258 | 116 | critical (e.message); | ||
259 | 117 | } | ||
260 | 118 | } | ||
261 | 119 | |||
262 | 120 | return session_manager != null; | ||
263 | 121 | } | ||
264 | 122 | |||
265 | 123 | private bool register_client () { | ||
266 | 124 | return_val_if_fail (session_manager != null && app_id != null, false); | ||
267 | 125 | |||
268 | 126 | string? startup_id = Environment.get_variable ("DESKTOP_AUTOSTART_ID"); | ||
269 | 127 | |||
270 | 128 | if (startup_id == null) { | ||
271 | 129 | critical ("Could not get value of environment variable DESKTOP_AUTOSTART_ID"); | ||
272 | 130 | return false; | ||
273 | 131 | } | ||
274 | 132 | |||
275 | 133 | // Register client | ||
276 | 134 | if (client == null) { | ||
277 | 135 | try { | ||
278 | 136 | session_manager.RegisterClient (app_id, startup_id, out client_id); | ||
279 | 137 | } catch (IOError e) { | ||
280 | 138 | critical ("Could not register client: %s", e.message); | ||
281 | 139 | } | ||
282 | 140 | |||
283 | 141 | return_val_if_fail (client_id != null, false); | ||
284 | 142 | |||
285 | 143 | debug ("Registered session manager client: %s", client_id); | ||
286 | 144 | |||
287 | 145 | // Get client | ||
288 | 146 | try { | ||
289 | 147 | client = Bus.get_proxy_sync (BusType.SESSION, DBUS_NAME, client_id); | ||
290 | 148 | } catch (IOError e) { | ||
291 | 149 | critical ("Could not get client: %s", e.message); | ||
292 | 150 | return_val_if_reached (false); | ||
293 | 151 | } | ||
294 | 152 | |||
295 | 153 | debug ("Obtained gnome-session client proxy"); | ||
296 | 154 | |||
297 | 155 | // Connect signals | ||
298 | 156 | client.QueryEndSession.connect (on_client_query_end_session); | ||
299 | 157 | client.EndSession.connect (on_client_end_session); | ||
300 | 158 | client.CancelEndSession.connect (on_client_cancel_end_session); | ||
301 | 159 | client.Stop.connect (on_client_stop); | ||
302 | 160 | } | ||
303 | 161 | |||
304 | 162 | return client != null; | ||
305 | 163 | } | ||
306 | 164 | |||
307 | 165 | |||
308 | 166 | /** ClientPrivate Signal handlers **/ | ||
309 | 167 | |||
310 | 168 | private void on_client_query_end_session (uint flags) { | ||
311 | 169 | debug ("Client query end session"); | ||
312 | 170 | return_if_fail (client != null); | ||
313 | 171 | |||
314 | 172 | send_end_session_response (true); | ||
315 | 173 | } | ||
316 | 174 | |||
317 | 175 | private void on_client_end_session (uint flags) { | ||
318 | 176 | debug ("Client end session"); | ||
319 | 177 | return_if_fail (client != null); | ||
320 | 178 | |||
321 | 179 | send_end_session_response (true); | ||
322 | 180 | on_client_stop (); | ||
323 | 181 | } | ||
324 | 182 | |||
325 | 183 | private void on_client_cancel_end_session () { | ||
326 | 184 | debug ("Client: Received EndSessionCanceled signal"); | ||
327 | 185 | } | ||
328 | 186 | |||
329 | 187 | private void on_client_stop () { | ||
330 | 188 | debug ("Client: Received Stop signal"); | ||
331 | 189 | this.unregister (); | ||
332 | 190 | this.stop_service (); | ||
333 | 191 | } | ||
334 | 192 | |||
335 | 193 | private inline void send_end_session_response (bool is_okay, string reason = "") { | ||
336 | 194 | return_if_fail (client != null); | ||
337 | 195 | |||
338 | 196 | // Tell the session manager whether it's okay to logout, shut down, etc. | ||
339 | 197 | try { | ||
340 | 198 | debug ("Sending is_okay = %s to session manager", is_okay.to_string ()); | ||
341 | 199 | client.EndSessionResponse (true, ""); | ||
342 | 200 | } catch (IOError e) { | ||
343 | 201 | warning ("Couldn't reply to session manager: %s", e.message); | ||
344 | 202 | } | ||
345 | 203 | } | ||
346 | 204 | } | ||
347 | 205 | } | ||
348 | 0 | 206 | ||
349 | === modified file 'src/SettingsManager.vala' | |||
350 | --- src/SettingsManager.vala 2012-06-14 22:28:44 +0000 | |||
351 | +++ src/SettingsManager.vala 2012-07-06 21:51:19 +0000 | |||
352 | @@ -30,7 +30,7 @@ | |||
353 | 30 | static const string CRASH_TIME_INTERVAL_KEY = "crash-time-interval"; | 30 | static const string CRASH_TIME_INTERVAL_KEY = "crash-time-interval"; |
354 | 31 | static const string MONITORED_PROCESSES_KEY = "monitored-processes"; | 31 | static const string MONITORED_PROCESSES_KEY = "monitored-processes"; |
355 | 32 | 32 | ||
357 | 33 | public string[] process_list { get; set; } | 33 | public string[] process_list { get; set; } |
358 | 34 | public uint max_crashes { get; set; default = 0; } | 34 | public uint max_crashes { get; set; default = 0; } |
359 | 35 | public uint crash_time_interval { get; set; default = 0; } | 35 | public uint crash_time_interval { get; set; default = 0; } |
360 | 36 | 36 | ||
361 | @@ -47,6 +47,6 @@ | |||
362 | 47 | } | 47 | } |
363 | 48 | 48 | ||
364 | 49 | private void on_process_list_changed () { | 49 | private void on_process_list_changed () { |
366 | 50 | this.process_list_changed (this.settings.get_strv (MONITORED_PROCESSES_KEY)); | 50 | this.process_list_changed (this.process_list); |
367 | 51 | } | 51 | } |
368 | 52 | } | 52 | } |
369 | 53 | 53 | ||
370 | === modified file 'src/Watchdog.vala' | |||
371 | --- src/Watchdog.vala 2012-06-17 04:31:37 +0000 | |||
372 | +++ src/Watchdog.vala 2012-07-06 21:51:19 +0000 | |||
373 | @@ -25,10 +25,10 @@ | |||
374 | 25 | * Victor Eduardo <victoreduardm@gmail.com> | 25 | * Victor Eduardo <victoreduardm@gmail.com> |
375 | 26 | */ | 26 | */ |
376 | 27 | 27 | ||
378 | 28 | public class Watchdog { | 28 | public class Watchdog : Object { |
379 | 29 | |||
380 | 29 | // Contains ALL the processes that are being monitored | 30 | // Contains ALL the processes that are being monitored |
381 | 30 | private Gee.HashMap<string, ProcessInfo> processes; | 31 | private Gee.HashMap<string, ProcessInfo> processes; |
382 | 31 | private Mutex data_lock; | ||
383 | 32 | 32 | ||
384 | 33 | public Watchdog () { | 33 | public Watchdog () { |
385 | 34 | this.processes = new Gee.HashMap<string, ProcessInfo> (); | 34 | this.processes = new Gee.HashMap<string, ProcessInfo> (); |
386 | @@ -43,16 +43,17 @@ | |||
387 | 43 | return; | 43 | return; |
388 | 44 | 44 | ||
389 | 45 | // Check if a process for this command has already been created | 45 | // Check if a process for this command has already been created |
391 | 46 | if (this.processes.has_key (command)) | 46 | if (this.processes.has_key (command)) { |
392 | 47 | return; | 47 | return; |
393 | 48 | } | ||
394 | 48 | 49 | ||
395 | 49 | // Create new process | 50 | // Create new process |
396 | 50 | var process = new ProcessInfo (command); | 51 | var process = new ProcessInfo (command); |
397 | 51 | 52 | ||
398 | 52 | // Add it to the table | 53 | // Add it to the table |
402 | 53 | this.data_lock.lock (); | 54 | lock (this.processes) { |
403 | 54 | this.processes[command] = process; | 55 | this.processes[command] = process; |
404 | 55 | this.data_lock.unlock (); | 56 | } |
405 | 56 | 57 | ||
406 | 57 | // Exit handler. Respawning occurs here | 58 | // Exit handler. Respawning occurs here |
407 | 58 | process.exited.connect ( (normal_exit) => { | 59 | process.exited.connect ( (normal_exit) => { |
408 | @@ -62,6 +63,8 @@ | |||
409 | 62 | process.reset_crash_count (); | 63 | process.reset_crash_count (); |
410 | 63 | } | 64 | } |
411 | 64 | 65 | ||
412 | 66 | bool remove_process = false; | ||
413 | 67 | |||
414 | 65 | // if still in the list, relaunch if possible | 68 | // if still in the list, relaunch if possible |
415 | 66 | if (command in Cerbere.settings.process_list) { | 69 | if (command in Cerbere.settings.process_list) { |
416 | 67 | // Check if the process is still present in the table since it could have been removed. | 70 | // Check if the process is still present in the table since it could have been removed. |
417 | @@ -73,25 +76,28 @@ | |||
418 | 73 | process.run_async (); // Reload right away | 76 | process.run_async (); // Reload right away |
419 | 74 | } | 77 | } |
420 | 75 | else { | 78 | else { |
423 | 76 | message ("'%s' exceeded the maximum number of crashes allowed (%s). It won't be launched again", | 79 | warning ("'%s' exceeded the maximum number of crashes allowed (%s). It won't be launched again", command, max_crashes.to_string ()); |
424 | 77 | command, max_crashes.to_string ()); | 80 | remove_process = true; |
425 | 78 | } | 81 | } |
426 | 79 | } | 82 | } |
427 | 80 | else { | 83 | else { |
431 | 81 | // If a process is not in the table, it means it wasn't re-launched after it exited, so | 84 | // If a process is not in the table, it means it wasn't re-launched |
432 | 82 | // in theory this code is never reached. | 85 | // after it exited, so in theory this code is never reached. |
433 | 83 | warning ("You should NEVER get this message. If you're getting it, file a bug!"); | 86 | critical ("Please file a bug at http://launchpad.net/cerbere and attach your ~/.xsession-errors file."); |
434 | 84 | } | 87 | } |
435 | 85 | } | 88 | } |
436 | 86 | else { | 89 | else { |
439 | 87 | message ("'%s' is no longer on settings. It will not be monitored anymore", command); | 90 | warning ("'%s' is no longer in settings (not monitored))", command); |
438 | 88 | |||
440 | 89 | process.reset_crash_count (); // reset | 91 | process.reset_crash_count (); // reset |
441 | 92 | remove_process = true; | ||
442 | 93 | } | ||
443 | 90 | 94 | ||
448 | 91 | // Remove from the list. At this point the reference count should drop to 0 and free the process. | 95 | // Remove from the table. At this point the reference count should |
449 | 92 | this.data_lock.lock (); | 96 | // drop to 0 and free the process info. |
450 | 93 | this.processes.unset (command); | 97 | if (remove_process) { |
451 | 94 | this.data_lock.unlock (); | 98 | lock (this.processes) { |
452 | 99 | this.processes.unset (command); | ||
453 | 100 | } | ||
454 | 95 | } | 101 | } |
455 | 96 | }); | 102 | }); |
456 | 97 | 103 |