Merge lp:~brandontschaefer/unity/mt-grab-mem-leak-reference-counting-crash-fix into lp:unity

Proposed by Brandon Schaefer
Status: Merged
Approved by: Łukasz Zemczak
Approved revision: no longer in the source branch.
Merged at revision: 2841
Proposed branch: lp:~brandontschaefer/unity/mt-grab-mem-leak-reference-counting-crash-fix
Merge into: lp:unity
Diff against target: 448 lines (+53/-57)
12 files modified
plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-group.cpp (+1/-1)
plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-group.h (+4/-6)
plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-impl-factory.cpp (+2/-2)
plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-impl-factory.h (+3/-5)
plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-window.h (+1/-1)
plugins/unity-mt-grab-handles/src/unity-mt-grab-handle.cpp (+3/-3)
plugins/unity-mt-grab-handles/src/unity-mt-grab-handle.h (+6/-8)
plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.cpp (+17/-13)
plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.h (+6/-8)
plugins/unity-mt-grab-handles/src/unity-mt-texture.cpp (+2/-2)
plugins/unity-mt-grab-handles/src/unity-mt-texture.h (+3/-4)
tests/test_grabhandle.cpp (+5/-4)
To merge this branch: bzr merge lp:~brandontschaefer/unity/mt-grab-mem-leak-reference-counting-crash-fix
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) Approve
Łukasz Zemczak Approve
PS Jenkins bot continuous-integration Pending
Review via email: mp+129316@code.launchpad.net

Commit message

Fix reference counting problem which leads to memory leaks and a crash in MT grab handles.

Description of the change

=== Problem ===
Reference counting problem causes Window/memory leaks which causes a map to not free XIDs causing a crash (hard to reproduce)

The problem is there is a vector mGrabHandles which stores a shard_ptr then the shared_ptr is pushed inside of a map mInputHandle. So when a window closes there is more then 1 things references each grab handle window so it never gets cleaned up.

=== Fix ===
Change the map to store weak ptrs, now when a window is closed everything gets cleaned up.

=== Test ===
Working on coming up with something, a manual test wouldn't work well here since it is hard to reproduce the crash.

To post a comment you must log in.
Revision history for this message
Łukasz Zemczak (sil2100) wrote :

Ok, tested, working, not causing any regressions - but is there a known manual test to reproduce this issue?

review: Approve
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Looks good for me, not sure it is easily possible to add an unit test here, though.

review: Approve
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

@Lukaz

The only way I could get the crash was to do the following:

repeat 20-30 times
  open terminal
  toggle grab handles
  close window

Then open 2 terminal windows and click back and fourth between them (clicking on the boarders as well because those are different windows.)

The crash comes when on of the windows your click is in map (from one of the closed windows). So it is slightly hard to reproduce....

@Marco
I was trying to look at a unit test but the only way I can think to test this would be to:
Open a window/ toggle grab handles on/ close window.
Then assert the map size that holds all the grab handle windows gets smaller (as before it was not)

Ill see what I can do.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-group.cpp'
2--- plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-group.cpp 2011-12-22 09:56:31 +0000
3+++ plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-group.cpp 2012-10-13 20:28:20 +0000
4@@ -40,7 +40,7 @@
5 }
6
7 void
8-unity::MT::GrabHandleGroup::raiseHandle(const boost::shared_ptr <const unity::MT::GrabHandle> &h)
9+unity::MT::GrabHandleGroup::raiseHandle(const std::shared_ptr <const unity::MT::GrabHandle> &h)
10 {
11 mOwner->raiseGrabHandle (h);
12 }
13
14=== modified file 'plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-group.h'
15--- plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-group.h 2011-12-21 08:18:47 +0000
16+++ plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-group.h 2012-10-13 20:28:20 +0000
17@@ -22,9 +22,7 @@
18 #include <Nux/Nux.h>
19 #include <glib.h>
20 #include <boost/noncopyable.hpp>
21-#include <boost/shared_ptr.hpp>
22-#include <boost/enable_shared_from_this.hpp>
23-#include <boost/weak_ptr.hpp>
24+#include <memory>
25
26 #include "unity-mt-grab-handle.h"
27 #include "unity-mt-texture.h"
28@@ -37,12 +35,12 @@
29 extern unsigned int FADE_MSEC;
30
31 class GrabHandleGroup :
32- public boost::enable_shared_from_this <GrabHandleGroup>,
33+ public std::enable_shared_from_this <GrabHandleGroup>,
34 boost::noncopyable
35 {
36 public:
37
38- typedef boost::shared_ptr <GrabHandleGroup> Ptr;
39+ typedef std::shared_ptr <GrabHandleGroup> Ptr;
40
41 static GrabHandleGroup::Ptr create (GrabHandleWindow *owner,
42 std::vector<TextureSize> &textures);
43@@ -59,7 +57,7 @@
44
45 void hide();
46 void show(unsigned int handles = ~0);
47- void raiseHandle (const boost::shared_ptr <const unity::MT::GrabHandle> &);
48+ void raiseHandle (const std::shared_ptr <const unity::MT::GrabHandle> &);
49
50 std::vector <TextureLayout> layout(unsigned int handles);
51
52
53=== modified file 'plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-impl-factory.cpp'
54--- plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-impl-factory.cpp 2011-12-23 07:13:19 +0000
55+++ plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-impl-factory.cpp 2012-10-13 20:28:20 +0000
56@@ -19,9 +19,9 @@
57 #include "unity-mt-grab-handle-impl-factory.h"
58 #include "unity-mt-grab-handle.h"
59
60-boost::shared_ptr <unity::MT::GrabHandle::ImplFactory> unity::MT::GrabHandle::ImplFactory::mDefault;
61+std::shared_ptr <unity::MT::GrabHandle::ImplFactory> unity::MT::GrabHandle::ImplFactory::mDefault;
62
63-boost::shared_ptr <unity::MT::GrabHandle::ImplFactory>
64+std::shared_ptr <unity::MT::GrabHandle::ImplFactory>
65 unity::MT::GrabHandle::ImplFactory::Default()
66 {
67 return mDefault;
68
69=== modified file 'plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-impl-factory.h'
70--- plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-impl-factory.h 2011-12-23 07:13:19 +0000
71+++ plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-impl-factory.h 2012-10-13 20:28:20 +0000
72@@ -22,9 +22,7 @@
73 #include <Nux/Nux.h>
74 #include <glib.h>
75 #include <boost/noncopyable.hpp>
76-#include <boost/shared_ptr.hpp>
77-#include <boost/enable_shared_from_this.hpp>
78-#include <boost/weak_ptr.hpp>
79+#include <memory>
80
81 #include "unity-mt-grab-handle.h"
82
83@@ -38,7 +36,7 @@
84
85 virtual ~ImplFactory() {};
86
87- static boost::shared_ptr <ImplFactory>
88+ static std::shared_ptr <ImplFactory>
89 Default();
90
91 static void
92@@ -48,7 +46,7 @@
93
94 protected:
95
96- static boost::shared_ptr <ImplFactory> mDefault;
97+ static std::shared_ptr <ImplFactory> mDefault;
98
99 ImplFactory() {};
100 };
101
102=== modified file 'plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-window.h'
103--- plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-window.h 2011-12-21 08:18:47 +0000
104+++ plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-window.h 2012-10-13 20:28:20 +0000
105@@ -37,7 +37,7 @@
106 int y,
107 unsigned int direction,
108 unsigned int button) = 0;
109- virtual void raiseGrabHandle (const boost::shared_ptr <const unity::MT::GrabHandle> &) = 0;
110+ virtual void raiseGrabHandle (const std::shared_ptr <const unity::MT::GrabHandle> &) = 0;
111 };
112
113 };
114
115=== modified file 'plugins/unity-mt-grab-handles/src/unity-mt-grab-handle.cpp'
116--- plugins/unity-mt-grab-handles/src/unity-mt-grab-handle.cpp 2011-12-21 08:18:47 +0000
117+++ plugins/unity-mt-grab-handles/src/unity-mt-grab-handle.cpp 2012-10-13 20:28:20 +0000
118@@ -55,7 +55,7 @@
119 unity::MT::GrabHandle::raise () const
120 {
121 unity::MT::GrabHandleGroup::Ptr ghg = mOwner.lock ();
122- boost::shared_ptr <const unity::MT::GrabHandle> gh = shared_from_this ();
123+ std::shared_ptr <const unity::MT::GrabHandle> gh = shared_from_this ();
124 ghg->raiseHandle (gh);
125 }
126
127@@ -98,7 +98,7 @@
128 unity::MT::GrabHandle::GrabHandle(Texture::Ptr texture,
129 unsigned int width,
130 unsigned int height,
131- const boost::shared_ptr <GrabHandleGroup> &owner,
132+ const std::shared_ptr <GrabHandleGroup> &owner,
133 unsigned int id) :
134 mOwner(owner),
135 mTexture (texture),
136@@ -110,7 +110,7 @@
137
138 unity::MT::GrabHandle::Ptr
139 unity::MT::GrabHandle::create (Texture::Ptr texture, unsigned int width, unsigned int height,
140- const boost::shared_ptr <GrabHandleGroup> &owner,
141+ const std::shared_ptr <GrabHandleGroup> &owner,
142 unsigned int id)
143 {
144 unity::MT::GrabHandle::Ptr p (new unity::MT::GrabHandle (texture, width, height, owner, id));
145
146=== modified file 'plugins/unity-mt-grab-handles/src/unity-mt-grab-handle.h'
147--- plugins/unity-mt-grab-handles/src/unity-mt-grab-handle.h 2011-12-21 08:18:47 +0000
148+++ plugins/unity-mt-grab-handles/src/unity-mt-grab-handle.h 2012-10-13 20:28:20 +0000
149@@ -21,10 +21,8 @@
150
151 #include <Nux/Nux.h>
152 #include <glib.h>
153+#include <memory>
154 #include <boost/noncopyable.hpp>
155-#include <boost/shared_ptr.hpp>
156-#include <boost/enable_shared_from_this.hpp>
157-#include <boost/weak_ptr.hpp>
158
159 #include "unity-mt-texture.h"
160 #include "unity-mt-grab-handle-window.h"
161@@ -79,17 +77,17 @@
162 class GrabHandleGroup;
163
164 class GrabHandle :
165- public boost::enable_shared_from_this <GrabHandle>,
166+ public std::enable_shared_from_this <GrabHandle>,
167 boost::noncopyable
168 {
169 public:
170
171- typedef boost::shared_ptr <GrabHandle> Ptr;
172+ typedef std::shared_ptr <GrabHandle> Ptr;
173
174 static GrabHandle::Ptr create (Texture::Ptr texture,
175 unsigned int width,
176 unsigned int height,
177- const boost::shared_ptr <GrabHandleGroup> &owner,
178+ const std::shared_ptr <GrabHandleGroup> &owner,
179 unsigned int id);
180 ~GrabHandle();
181
182@@ -160,10 +158,10 @@
183 GrabHandle(Texture::Ptr texture,
184 unsigned int width,
185 unsigned int height,
186- const boost::shared_ptr <GrabHandleGroup> &owner,
187+ const std::shared_ptr <GrabHandleGroup> &owner,
188 unsigned int id);
189
190- boost::weak_ptr <GrabHandleGroup> mOwner;
191+ std::weak_ptr <GrabHandleGroup> mOwner;
192 Texture::Ptr mTexture;
193 unsigned int mId;
194 nux::Geometry mRect;
195
196=== modified file 'plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.cpp'
197--- plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.cpp 2012-09-13 10:56:42 +0000
198+++ plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.cpp 2012-10-13 20:28:20 +0000
199@@ -35,7 +35,8 @@
200 unity::MT::Texture::Ptr
201 unity::MT::X11TextureFactory::create ()
202 {
203- return boost::shared_static_cast <unity::MT::Texture> (unity::MT::X11Texture::Ptr (new unity::MT::X11Texture (mWrap)));
204+ unity::MT::Texture::Ptr tp(static_cast<unity::MT::Texture*> (new unity::MT::X11Texture(mWrap)));
205+ return tp;
206 }
207
208 unity::MT::X11Texture::X11Texture (const GLTexture::List &t)
209@@ -151,7 +152,7 @@
210 }
211
212 void
213-UnityMTGrabHandlesWindow::raiseGrabHandle (const boost::shared_ptr <const unity::MT::GrabHandle> &h)
214+UnityMTGrabHandlesWindow::raiseGrabHandle (const std::shared_ptr <const unity::MT::GrabHandle> &h)
215 {
216 UnityMTGrabHandlesScreen::get (screen)->raiseHandle (h, window->frame ());
217 }
218@@ -202,12 +203,13 @@
219 }
220
221 void
222-UnityMTGrabHandlesScreen::raiseHandle (const boost::shared_ptr <const unity::MT::GrabHandle> &h,
223+UnityMTGrabHandlesScreen::raiseHandle (const std::shared_ptr <const unity::MT::GrabHandle> &h,
224 Window owner)
225 {
226 for (const auto &pair : mInputHandles)
227 {
228- if (*pair.second == *h)
229+ const unity::MT::GrabHandle::Ptr gh = pair.second.lock();
230+ if (*gh == *h)
231 {
232 unsigned int mask = CWSibling | CWStackMode;
233 XWindowChanges xwc;
234@@ -322,10 +324,11 @@
235
236 if (it != mInputHandles.end())
237 {
238- if (it->second)
239- it->second->buttonPress (event->xbutton.x_root,
240- event->xbutton.y_root,
241- event->xbutton.button);
242+ const unity::MT::GrabHandle::Ptr gh = it->second.lock();
243+ if (gh)
244+ gh->buttonPress (event->xbutton.x_root,
245+ event->xbutton.y_root,
246+ event->xbutton.button);
247 }
248
249 break;
250@@ -346,8 +349,9 @@
251
252 if (it != mInputHandles.end())
253 {
254- if (it->second)
255- it->second->reposition (0, 0, unity::MT::PositionLock);
256+ const unity::MT::GrabHandle::Ptr gh = it->second.lock();
257+ if (gh)
258+ gh->reposition (0, 0, unity::MT::PositionLock);
259 }
260
261 break;
262@@ -457,7 +461,7 @@
263 * region */
264 CompRegion reg = CompRegion(layout.second.x, layout.second.y, layout.second.width, layout.second.height);
265
266- for(GLTexture * tex : boost::shared_static_cast <unity::MT::X11Texture> (layout.first)->get ())
267+ for(GLTexture * tex : static_cast<unity::MT::X11Texture*>(layout.first.get())->get())
268 {
269 GLTexture::MatrixList matl;
270 GLTexture::Matrix mat = tex->matrix();
271@@ -633,7 +637,7 @@
272 void
273 UnityMTGrabHandlesScreen::addHandleWindow(const unity::MT::GrabHandle::Ptr &h, Window w)
274 {
275- mInputHandles.insert(std::pair <Window, const unity::MT::GrabHandle::Ptr> (w, h));
276+ mInputHandles.insert(std::make_pair(w, h));
277 }
278
279 void
280@@ -774,7 +778,7 @@
281 GLTexture::List t = GLTexture::readImageToTexture(fname, pname,
282 size);
283
284- (boost::shared_static_cast <unity::MT::X11TextureFactory> (unity::MT::Texture::Factory::Default ()))->setActiveWrap (t);
285+ (static_cast<unity::MT::X11TextureFactory*>(unity::MT::Texture::Factory::Default().get())->setActiveWrap(t));
286
287 mHandleTextures.at(i).first = unity::MT::Texture::Factory::Default ()->create ();
288 mHandleTextures.at (i).second.width = size.width ();
289
290=== modified file 'plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.h'
291--- plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.h 2012-09-13 10:56:42 +0000
292+++ plugins/unity-mt-grab-handles/src/unity-mt-grab-handles.h 2012-10-13 20:28:20 +0000
293@@ -22,9 +22,7 @@
294 #include <composite/composite.h>
295 #include <opengl/opengl.h>
296 #include <boost/noncopyable.hpp>
297-#include <boost/shared_ptr.hpp>
298-#include <boost/enable_shared_from_this.hpp>
299-#include <boost/weak_ptr.hpp>
300+#include <memory>
301
302 #include <core/atoms.h>
303
304@@ -72,7 +70,7 @@
305 {
306 public:
307
308- typedef boost::shared_ptr <X11Texture> Ptr;
309+ typedef std::shared_ptr <X11Texture> Ptr;
310
311 X11Texture (const GLTexture::List &t);
312
313@@ -124,7 +122,7 @@
314
315 private:
316
317- boost::weak_ptr <unity::MT::GrabHandle> mGrabHandle;
318+ std::weak_ptr <unity::MT::GrabHandle> mGrabHandle;
319 Window mIpw;
320 Display *mDpy;
321 };
322@@ -175,7 +173,7 @@
323 void preparePaint(int);
324 void donePaint();
325
326- void raiseHandle (const boost::shared_ptr <const unity::MT::GrabHandle> &,
327+ void raiseHandle (const std::shared_ptr <const unity::MT::GrabHandle> &,
328 Window owner);
329
330 std::vector <unity::MT::TextureSize> & textures()
331@@ -188,7 +186,7 @@
332 std::list <unity::MT::GrabHandleGroup::Ptr> mGrabHandles;
333 std::vector <unity::MT::TextureSize> mHandleTextures;
334
335- std::map <Window, const unity::MT::GrabHandle::Ptr> mInputHandles;
336+ std::map <Window, const std::weak_ptr <unity::MT::GrabHandle> > mInputHandles;
337 CompWindowVector mLastClientListStacking;
338 Atom mCompResizeWindowAtom;
339
340@@ -243,7 +241,7 @@
341
342 protected:
343
344- void raiseGrabHandle (const boost::shared_ptr <const unity::MT::GrabHandle> &h);
345+ void raiseGrabHandle (const std::shared_ptr <const unity::MT::GrabHandle> &h);
346 void requestMovement (int x,
347 int y,
348 unsigned int direction,
349
350=== modified file 'plugins/unity-mt-grab-handles/src/unity-mt-texture.cpp'
351--- plugins/unity-mt-grab-handles/src/unity-mt-texture.cpp 2011-12-23 07:19:07 +0000
352+++ plugins/unity-mt-grab-handles/src/unity-mt-texture.cpp 2012-10-13 20:28:20 +0000
353@@ -18,7 +18,7 @@
354
355 #include "unity-mt-texture.h"
356
357-boost::shared_ptr <unity::MT::Texture::Factory> unity::MT::Texture::Factory::mDefault;
358+std::shared_ptr <unity::MT::Texture::Factory> unity::MT::Texture::Factory::mDefault;
359
360 unity::MT::Texture::Factory::Factory ()
361 {
362@@ -34,7 +34,7 @@
363 mDefault.reset (f);
364 }
365
366-boost::shared_ptr <unity::MT::Texture::Factory>
367+std::shared_ptr <unity::MT::Texture::Factory>
368 unity::MT::Texture::Factory::Default ()
369 {
370 return mDefault;
371
372=== modified file 'plugins/unity-mt-grab-handles/src/unity-mt-texture.h'
373--- plugins/unity-mt-grab-handles/src/unity-mt-texture.h 2011-12-23 07:19:07 +0000
374+++ plugins/unity-mt-grab-handles/src/unity-mt-texture.h 2012-10-13 20:28:20 +0000
375@@ -21,7 +21,6 @@
376
377 #include <Nux/Nux.h>
378 #include <boost/noncopyable.hpp>
379-#include <boost/shared_ptr.hpp>
380
381 namespace unity
382 {
383@@ -31,7 +30,7 @@
384 {
385 public:
386
387- typedef boost::shared_ptr <Texture> Ptr;
388+ typedef std::shared_ptr <Texture> Ptr;
389
390 virtual ~Texture ();
391
392@@ -48,7 +47,7 @@
393 static void
394 SetDefault (Factory *);
395
396- static boost::shared_ptr <Factory>
397+ static std::shared_ptr <Factory>
398 Default ();
399
400 protected:
401@@ -57,7 +56,7 @@
402
403 private:
404
405- static boost::shared_ptr <unity::MT::Texture::Factory> mDefault;
406+ static std::shared_ptr <unity::MT::Texture::Factory> mDefault;
407 };
408
409 protected:
410
411=== modified file 'tests/test_grabhandle.cpp'
412--- tests/test_grabhandle.cpp 2011-12-23 01:28:05 +0000
413+++ tests/test_grabhandle.cpp 2012-10-13 20:28:20 +0000
414@@ -7,7 +7,7 @@
415 #include <unity-mt-grab-handle-group.h>
416 #include <unity-mt-grab-handle-impl-factory.h>
417 #include <unity-mt-texture.h>
418-#include <boost/shared_ptr.hpp>
419+#include <memory>
420
421 unsigned int unity::MT::MaximizedHorzMask = (1 << 0);
422 unsigned int unity::MT::MaximizedVertMask = (1 << 1);
423@@ -95,7 +95,7 @@
424 class MockGrabHandleTexture : public unity::MT::Texture
425 {
426 public:
427- typedef boost::shared_ptr <MockGrabHandleTexture> Ptr;
428+ typedef std::shared_ptr <MockGrabHandleTexture> Ptr;
429 MockGrabHandleTexture () : unity::MT::Texture () {};
430 };
431
432@@ -112,13 +112,14 @@
433 public:
434 MockGrabHandleWindow () : GrabHandleWindow () {};
435 MOCK_METHOD4 (requestMovement, void (int, int, unsigned int, unsigned int));
436- MOCK_METHOD1 (raiseGrabHandle, void (const boost::shared_ptr <const unity::MT::GrabHandle> &));
437+ MOCK_METHOD1 (raiseGrabHandle, void (const std::shared_ptr <const unity::MT::GrabHandle> &));
438 };
439
440 Texture::Ptr
441 MockGrabHandleTextureFactory::create ()
442 {
443- return boost::shared_static_cast <Texture> (MockGrabHandleTexture::Ptr (new MockGrabHandleTexture ()));
444+ Texture::Ptr pt(static_cast<unity::MT::Texture*>(new MockGrabHandleTexture()));
445+ return pt;
446 }
447
448 GrabHandle::Impl *