Merge lp:~smspillaz/compiz-core/compiz-core.glib-mainloop-fixes into lp:compiz-core/0.9.5

Proposed by Sam Spilsbury
Status: Merged
Merged at revision: 2939
Proposed branch: lp:~smspillaz/compiz-core/compiz-core.glib-mainloop-fixes
Merge into: lp:compiz-core/0.9.5
Diff against target: 525 lines (+213/-64)
13 files modified
src/CMakeLists.txt (+1/-0)
src/eventsource.cpp (+2/-10)
src/main.cpp (+2/-13)
src/privateeventsource.h (+4/-3)
src/privateiosource.h (+5/-3)
src/privatescreen.h (+13/-5)
src/privatesignalsource.h (+55/-0)
src/screen.cpp (+46/-10)
src/signalsource.cpp (+65/-0)
src/timer/src/privatetimeoutsource.h (+3/-2)
src/timer/src/timer.cpp (+2/-2)
tests/integration/xig/CMakeLists.txt (+14/-15)
tests/integration/xig/scripts/restart.conf (+1/-1)
To merge this branch: bzr merge lp:~smspillaz/compiz-core/compiz-core.glib-mainloop-fixes
Reviewer Review Type Date Requested Status
Alan Griffiths Approve
Review via email: mp+89537@code.launchpad.net

Description of the change

Fix some of the GLib mainloop implementation in compiz

1. Don't use Glib::RefPtr for sources as they are broken (unref will cause a crash on a destroyed source)
2. Don't g_main_context_iteration in order to flush the event queue
3. Use XFlush instead
4. Handle signals using glib's signal sources so that they are safely dispatched back to the mainloop
5. Enabled the failing xig tests because of ^ (they will pass when https://code.launchpad.net/~smspillaz/xig/xig.disconnect-signals/+merge/89535 is merged)

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> 1. Don't use Glib::RefPtr for sources as they are broken (unref will cause a crash on a destroyed source)

I'm slightly puzzled as it appears the prior code already uses raw pointers. (And if Glib::RefPtr is broken how do other uses work?)

review: Approve
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

> > 1. Don't use Glib::RefPtr for sources as they are broken (unref will cause a
> crash on a destroyed source)
>
> I'm slightly puzzled as it appears the prior code already uses raw pointers.

Yes, only CompEventSource * did

> (And if Glib::RefPtr is broken how do other uses work?)

Its only broken for GSource * wrappers.

Eg, the underlying GSource * is free'd in the main loop, and glibmm doesn't catch the GDestroyNotify callback for when that happens so when the pointer goes out of scope, it attempts to free the underlying GSource * and this crashes

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-01-20 15:42:52 +0000
3+++ src/CMakeLists.txt 2012-01-21 13:43:23 +0000
4@@ -99,6 +99,7 @@
5 ${CMAKE_CURRENT_SOURCE_DIR}/modifierhandler.cpp
6 ${CMAKE_CURRENT_SOURCE_DIR}/propertywriter.cpp
7 ${CMAKE_CURRENT_SOURCE_DIR}/eventsource.cpp
8+ ${CMAKE_CURRENT_SOURCE_DIR}/signalsource.cpp
9 ${CMAKE_CURRENT_SOURCE_DIR}/stackdebugger.cpp
10
11 ${_bcop_sources}
12
13=== modified file 'src/eventsource.cpp'
14--- src/eventsource.cpp 2011-08-19 14:25:11 +0000
15+++ src/eventsource.cpp 2012-01-21 13:43:23 +0000
16@@ -26,11 +26,9 @@
17
18 #include "privatescreen.h"
19
20-//Glib::RefPtr <CompEventSource>
21-CompEventSource*
22+CompEventSource *
23 CompEventSource::create ()
24 {
25- // return Glib::RefPtr <CompEventSource> (new CompEventSource ());
26 return new CompEventSource ();
27 }
28
29@@ -62,13 +60,7 @@
30 bool
31 CompEventSource::callback ()
32 {
33- if (restartSignal || shutDown)
34- {
35- screen->priv->mainloop->quit ();
36- return false;
37- }
38- else
39- screen->priv->processEvents ();
40+ screen->priv->processEvents ();
41 return true;
42 }
43
44
45=== modified file 'src/main.cpp'
46--- src/main.cpp 2012-01-19 18:12:31 +0000
47+++ src/main.cpp 2012-01-21 13:43:23 +0000
48@@ -57,7 +57,7 @@
49 }
50
51 static void
52-signalHandler (int sig)
53+chldSignalHandler (int sig)
54 {
55 int status;
56
57@@ -65,14 +65,6 @@
58 case SIGCHLD:
59 waitpid (-1, &status, WNOHANG | WUNTRACED);
60 break;
61- case SIGHUP:
62- restartSignal = true;
63- break;
64- case SIGINT:
65- case SIGTERM:
66- shutDown = true;
67- default:
68- break;
69 }
70 }
71
72@@ -248,10 +240,7 @@
73 programArgc = argc;
74 programArgv = argv;
75
76- signal (SIGHUP, signalHandler);
77- signal (SIGCHLD, signalHandler);
78- signal (SIGINT, signalHandler);
79- signal (SIGTERM, signalHandler);
80+ signal (SIGCHLD, chldSignalHandler);
81
82 if (!manager.parseArguments (argc, argv))
83 return 0;
84
85=== modified file 'src/privateeventsource.h'
86--- src/privateeventsource.h 2011-08-19 14:25:11 +0000
87+++ src/privateeventsource.h 2012-01-21 13:43:23 +0000
88@@ -31,9 +31,11 @@
89 {
90 public:
91
92+ virtual ~CompEventSource ();
93+
94 static
95- // Glib::RefPtr <CompEventSource> create ();
96- CompEventSource* create ();
97+ CompEventSource *
98+ create ();
99
100 sigc::connection connect (const sigc::slot <bool> &slot);
101
102@@ -45,7 +47,6 @@
103 bool callback ();
104
105 CompEventSource ();
106- virtual ~CompEventSource ();
107
108 private:
109
110
111=== modified file 'src/privateiosource.h'
112--- src/privateiosource.h 2011-07-04 16:25:20 +0000
113+++ src/privateiosource.h 2012-01-21 13:43:23 +0000
114@@ -31,10 +31,12 @@
115 {
116 public:
117
118+ virtual ~CompWatchFd ();
119+
120 static
121- Glib::RefPtr <CompWatchFd> create (int,
122- Glib::IOCondition,
123- FdWatchCallBack);
124+ CompWatchFd * create (int,
125+ Glib::IOCondition,
126+ FdWatchCallBack);
127
128 protected:
129
130
131=== modified file 'src/privatescreen.h'
132--- src/privatescreen.h 2012-01-19 18:12:31 +0000
133+++ src/privatescreen.h 2012-01-21 13:43:23 +0000
134@@ -41,6 +41,7 @@
135 #include "privatetimeoutsource.h"
136 #include "privateiosource.h"
137 #include "privateeventsource.h"
138+#include "privatesignalsource.h"
139
140 #include "core_options.h"
141
142@@ -382,21 +383,28 @@
143
144 void setDefaultWindowAttributes (XWindowAttributes *);
145
146+ void handleSignal (int signum);
147+
148 public:
149
150 PrivateScreen *priv;
151
152 Glib::RefPtr <Glib::MainLoop> mainloop;
153- // See https://bugzilla.gnome.org/show_bug.cgi?id=561885
154- // Glib::RefPtr <CompEventSource> source;
155- CompEventSource* source;
156- Glib::RefPtr <CompTimeoutSource> timeout;
157+
158+ /* We cannot use RefPtrs. See
159+ * https://bugzilla.gnome.org/show_bug.cgi?id=561885
160+ */
161+ CompEventSource * source;
162+ CompTimeoutSource * timeout;
163+ CompSignalSource * sighupSource;
164+ CompSignalSource * sigtermSource;
165+ CompSignalSource * sigintSource;
166 Glib::RefPtr <Glib::MainContext> ctx;
167
168 CompFileWatchList fileWatch;
169 CompFileWatchHandle lastFileWatchHandle;
170
171- std::list<Glib::RefPtr <CompWatchFd> > watchFds;
172+ std::list< CompWatchFd * > watchFds;
173 CompWatchFdHandle lastWatchFdHandle;
174
175 std::map<CompString, CompPrivate> valueMap;
176
177=== added file 'src/privatesignalsource.h'
178--- src/privatesignalsource.h 1970-01-01 00:00:00 +0000
179+++ src/privatesignalsource.h 2012-01-21 13:43:23 +0000
180@@ -0,0 +1,55 @@
181+/*
182+ * Copyright © 2012 Canonical, Ltd.
183+ *
184+ * Permission to use, copy, modify, distribute, and sell this software
185+ * and its documentation for any purpose is hereby granted without
186+ * fee, provided that the above copyright notice appear in all copies
187+ * and that both that copyright notice and this permission notice
188+ * appear in supporting documentation, and that the name of
189+ * Canonical, Ltd. not be used in advertising or publicity pertaining to
190+ * distribution of the software without specific, written prior permission.
191+ * Canonical, Ltd. makes no representations about the suitability of this
192+ * software for any purpose. It is provided "as is" without express or
193+ * implied warranty.
194+ *
195+ * CANONICAL LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
196+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
197+ * NO EVENT SHALL Canonical, Ltd. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
198+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
199+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
200+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
201+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
202+ *
203+ * Author: Sam Spilsbury <sam.spilsbury@canonical.com>
204+ */
205+
206+#include <boost/function.hpp>
207+
208+#include <glib.h>
209+
210+class CompSignalSource
211+{
212+ public:
213+
214+ ~CompSignalSource ();
215+
216+ typedef boost::function <void (int)> callbackFunc;
217+
218+ static
219+ CompSignalSource *
220+ create (int signum,
221+ const callbackFunc &);
222+
223+ protected:
224+
225+ explicit CompSignalSource (int signum, const callbackFunc &);
226+
227+ private:
228+
229+ static gboolean callback (gpointer user_data);
230+ static void destroyed (gpointer user_data);
231+
232+ callbackFunc mFunc;
233+ int mSignal;
234+ gint mSource;
235+};
236
237=== modified file 'src/screen.cpp'
238--- src/screen.cpp 2012-01-20 12:59:05 +0000
239+++ src/screen.cpp 2012-01-21 13:43:23 +0000
240@@ -112,17 +112,34 @@
241 }
242
243 void
244+PrivateScreen::handleSignal (int signum)
245+{
246+ switch (signum)
247+ {
248+ case SIGINT:
249+ case SIGTERM:
250+ shutDown = true;
251+ break;
252+ case SIGHUP:
253+ restartSignal = true;
254+ break;
255+ default:
256+ break;
257+ }
258+
259+ if (shutDown || restartSignal)
260+ mainloop->quit ();
261+}
262+
263+void
264 CompScreen::eventLoop ()
265 {
266- priv->ctx = Glib::MainContext::get_default ();
267- priv->mainloop = Glib::MainLoop::create (priv->ctx, false);
268 priv->source = CompEventSource::create ();
269 priv->timeout = CompTimeoutSource::create (priv->ctx);
270
271 priv->source->attach (priv->ctx);
272
273- /* Kick the event loop */
274- priv->ctx->iteration (false);
275+ XFlush (priv->dpy);
276
277 priv->mainloop->run ();
278 }
279@@ -191,12 +208,16 @@
280 (this, &CompWatchFd::internalCallback));
281 }
282
283-Glib::RefPtr <CompWatchFd>
284+CompWatchFd::~CompWatchFd ()
285+{
286+}
287+
288+CompWatchFd *
289 CompWatchFd::create (int fd,
290 Glib::IOCondition events,
291 FdWatchCallBack callback)
292 {
293- return Glib::RefPtr <CompWatchFd> (new CompWatchFd (fd, events, callback));
294+ return new CompWatchFd (fd, events, callback);
295 }
296
297 CompWatchFdHandle
298@@ -219,7 +240,7 @@
299 if (events & POLLHUP)
300 gEvents |= Glib::IO_HUP;
301
302- Glib::RefPtr <CompWatchFd> watchFd = CompWatchFd::create (fd, gEvents, callBack);
303+ CompWatchFd *watchFd = CompWatchFd::create (fd, gEvents, callBack);
304
305 watchFd->attach (priv->ctx);
306
307@@ -238,8 +259,8 @@
308 void
309 CompScreen::removeWatchFd (CompWatchFdHandle handle)
310 {
311- std::list<Glib::RefPtr <CompWatchFd> >::iterator it;
312- Glib::RefPtr <CompWatchFd> w;
313+ std::list<CompWatchFd * >::iterator it;
314+ CompWatchFd * w;
315
316 for (it = priv->watchFds.begin();
317 it != priv->watchFds.end (); it++)
318@@ -259,7 +280,7 @@
319 return;
320 }
321
322- w.reset ();
323+ delete w;
324 priv->watchFds.erase (it);
325 }
326
327@@ -4363,6 +4384,12 @@
328 int nvisinfo;
329 XSetWindowAttributes attrib;
330
331+ priv->ctx = Glib::MainContext::get_default ();
332+ priv->mainloop = Glib::MainLoop::create (priv->ctx, false);
333+ priv->sighupSource = CompSignalSource::create (SIGHUP, boost::bind (&PrivateScreen::handleSignal, priv, _1));
334+ priv->sigintSource = CompSignalSource::create (SIGINT, boost::bind (&PrivateScreen::handleSignal, priv, _1));
335+ priv->sigtermSource = CompSignalSource::create (SIGTERM, boost::bind (&PrivateScreen::handleSignal, priv, _1));
336+
337 dpy = priv->dpy = XOpenDisplay (name);
338 if (!priv->dpy)
339 {
340@@ -4371,6 +4398,8 @@
341 return false;
342 }
343
344+ XSynchronize (dpy, TRUE);
345+
346 // priv->connection = XGetXCBConnection (priv->dpy);
347
348 snprintf (priv->displayString, 255, "DISPLAY=%s",
349@@ -4932,4 +4961,11 @@
350
351 PrivateScreen::~PrivateScreen ()
352 {
353+ delete timeout;
354+ delete source;
355+
356+ foreach (CompWatchFd *fd, watchFds)
357+ delete fd;
358+
359+ watchFds.clear ();
360 }
361
362=== added file 'src/signalsource.cpp'
363--- src/signalsource.cpp 1970-01-01 00:00:00 +0000
364+++ src/signalsource.cpp 2012-01-21 13:43:23 +0000
365@@ -0,0 +1,65 @@
366+/*
367+ * Copyright © 2012 Canonical, Ltd.
368+ *
369+ * Permission to use, copy, modify, distribute, and sell this software
370+ * and its documentation for any purpose is hereby granted without
371+ * fee, provided that the above copyright notice appear in all copies
372+ * and that both that copyright notice and this permission notice
373+ * appear in supporting documentation, and that the name of
374+ * Canonical, Ltd. not be used in advertising or publicity pertaining to
375+ * distribution of the software without specific, written prior permission.
376+ * Canonical, Ltd. makes no representations about the suitability of this
377+ * software for any purpose. It is provided "as is" without express or
378+ * implied warranty.
379+ *
380+ * CANONICAL LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
381+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
382+ * NO EVENT SHALL Canonical, Ltd. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
383+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
384+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
385+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
386+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
387+ *
388+ * Author: Sam Spilsbury <sam.spilsbury@canonical.com>
389+ */
390+
391+#include "privatesignalsource.h"
392+#include <glib-unix.h>
393+
394+CompSignalSource *
395+CompSignalSource::create (int signum, const callbackFunc &f)
396+{
397+ return new CompSignalSource (signum, f);
398+}
399+
400+CompSignalSource::CompSignalSource (int signum, const callbackFunc &f) :
401+ mFunc (f),
402+ mSignal (signum),
403+ mSource (g_unix_signal_add_full (G_PRIORITY_HIGH,
404+ signum,
405+ CompSignalSource::callback,
406+ this,
407+ CompSignalSource::destroyed))
408+{
409+}
410+
411+gboolean
412+CompSignalSource::callback (gpointer user_data)
413+{
414+ CompSignalSource *self = static_cast <CompSignalSource *> (user_data);
415+ self->mFunc (self->mSignal);
416+ return TRUE;
417+}
418+
419+void
420+CompSignalSource::destroyed (gpointer user_data)
421+{
422+ CompSignalSource *self = static_cast <CompSignalSource *> (user_data);
423+ self->mSource = 0;
424+}
425+
426+CompSignalSource::~CompSignalSource ()
427+{
428+ if (mSource)
429+ g_source_remove (mSource);
430+}
431
432=== modified file 'src/timer/src/privatetimeoutsource.h'
433--- src/timer/src/privatetimeoutsource.h 2012-01-12 06:48:58 +0000
434+++ src/timer/src/privatetimeoutsource.h 2012-01-21 13:43:23 +0000
435@@ -34,7 +34,9 @@
436 {
437 public:
438
439- static Glib::RefPtr <CompTimeoutSource> create (Glib::RefPtr <Glib::MainContext> &ctx);
440+ virtual ~CompTimeoutSource ();
441+
442+ static CompTimeoutSource * create (Glib::RefPtr <Glib::MainContext> &ctx);
443 sigc::connection connect (const sigc::slot <bool> &slot);
444
445 protected:
446@@ -45,7 +47,6 @@
447 bool callback ();
448
449 explicit CompTimeoutSource (Glib::RefPtr <Glib::MainContext> &ctx);
450- virtual ~CompTimeoutSource ();
451
452 friend class CompTimer;
453 };
454
455=== modified file 'src/timer/src/timer.cpp'
456--- src/timer/src/timer.cpp 2012-01-19 18:12:31 +0000
457+++ src/timer/src/timer.cpp 2012-01-21 13:43:23 +0000
458@@ -69,10 +69,10 @@
459 return connect_generic (slot);
460 }
461
462-Glib::RefPtr <CompTimeoutSource>
463+CompTimeoutSource *
464 CompTimeoutSource::create (Glib::RefPtr <Glib::MainContext> &ctx)
465 {
466- return Glib::RefPtr <CompTimeoutSource> (new CompTimeoutSource (ctx));
467+ return new CompTimeoutSource (ctx);
468 }
469
470 #define COMPIZ_TIMEOUT_WAIT 15
471
472=== modified file 'tests/integration/xig/CMakeLists.txt'
473--- tests/integration/xig/CMakeLists.txt 2012-01-20 16:29:27 +0000
474+++ tests/integration/xig/CMakeLists.txt 2012-01-21 13:43:23 +0000
475@@ -10,21 +10,20 @@
476
477 add_subdirectory (src)
478
479- #add_test (compiz-xig-test-startup
480- # ${CMAKE_CURRENT_BINARY_DIR}/src/compiz-xig-test-runner startup)
481-
482- # Disabled as compiz is crashing on SIGHUP
483- #add_test (compiz-xig-test-restart
484- # ${CMAKE_CURRENT_BINARY_DIR}/src/compiz-xig-test-runner restart)
485-
486- #add_test (compiz-xig-test-xserver-quit
487- # ${CMAKE_CURRENT_BINARY_DIR}/src/compiz-xig-test-runner xserver-quit)
488-
489- #add_test (compiz-xig-test-new-window
490- # ${CMAKE_CURRENT_BINARY_DIR}/src/compiz-xig-test-runner new-window)
491-
492- #add_test (compiz-xig-test-existing-window
493- # ${CMAKE_CURRENT_BINARY_DIR}/src/compiz-xig-test-runner existing-window)
494+ add_test (compiz-xig-test-startup
495+ ${CMAKE_CURRENT_BINARY_DIR}/src/compiz-xig-test-runner startup)
496+
497+ add_test (compiz-xig-test-restart
498+ ${CMAKE_CURRENT_BINARY_DIR}/src/compiz-xig-test-runner restart)
499+
500+ add_test (compiz-xig-test-xserver-quit
501+ ${CMAKE_CURRENT_BINARY_DIR}/src/compiz-xig-test-runner xserver-quit)
502+
503+ add_test (compiz-xig-test-new-window
504+ ${CMAKE_CURRENT_BINARY_DIR}/src/compiz-xig-test-runner new-window)
505+
506+ add_test (compiz-xig-test-existing-window
507+ ${CMAKE_CURRENT_BINARY_DIR}/src/compiz-xig-test-runner existing-window)
508
509 else (COMPIZ_XIG_TEST_FOUND)
510
511
512=== modified file 'tests/integration/xig/scripts/restart.conf'
513--- tests/integration/xig/scripts/restart.conf 2012-01-20 16:29:27 +0000
514+++ tests/integration/xig/scripts/restart.conf 2012-01-21 13:43:23 +0000
515@@ -10,9 +10,9 @@
516
517 # Restart
518 #?*RESTART-COMPIZ
519-#?COMPIZ EXIT STATUS=1
520 #?X CLIENT-DISCONNECTED
521 #?X CLIENT-CONNECTED
522
523 #?*STOP-COMPIZ
524+#?X CLIENT-DISCONNECTED
525 #?COMPIZ EXIT STATUS=0

Subscribers

People subscribed via source and target branches