1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_UI_LIBGTK2UI_G_OBJECT_DESTRUCTOR_FILO_H_
6 #define CHROME_BROWSER_UI_LIBGTK2UI_G_OBJECT_DESTRUCTOR_FILO_H_
12 #include "base/basictypes.h"
15 template <typename T
> struct DefaultSingletonTraits
;
18 typedef struct _GObject GObject
;
22 // This class hooks calls to g_object_weak_ref()/unref() and executes them in
23 // FILO order. This is important if there are several hooks to the single object
24 // (set up at different levels of class hierarchy) and the lowest hook (set up
25 // first) is deleting self - it must be called last (among hooks for the given
26 // object). Unfortunately Glib does not provide this guarantee.
30 // static void OnDestroyedThunk(gpointer data, GObject *where_the_object_was) {
31 // reinterpret_cast<MyClass*>(data)->OnDestroyed(where_the_object_was);
33 // void MyClass::OnDestroyed(GObject *where_the_object_was) {
39 // ui::GObjectDestructorFILO::GetInstance()->Connect(
40 // G_OBJECT(my_widget), &OnDestroyedThunk, this);
42 // MyClass::~MyClass() {
44 // ui::GObjectDestructorFILO::GetInstance()->Disconnect(
45 // G_OBJECT(my_widget), &OnDestroyedThunk, this);
49 // TODO(glotov): Probably worth adding ScopedGObjectDtor<T>.
51 // This class is a singleton. Not thread safe. Must be called within UI thread.
52 class GObjectDestructorFILO
{
54 typedef void (*DestructorHook
)(void* context
, GObject
* where_the_object_was
);
56 static GObjectDestructorFILO
* GetInstance();
57 void Connect(GObject
* object
, DestructorHook callback
, void* context
);
58 void Disconnect(GObject
* object
, DestructorHook callback
, void* context
);
62 Hook(GObject
* o
, DestructorHook cb
, void* ctx
)
63 : object(o
), callback(cb
), context(ctx
) {
65 bool equal(GObject
* o
, DestructorHook cb
, void* ctx
) const {
66 return object
== o
&& callback
== cb
&& context
== ctx
;
69 DestructorHook callback
;
72 typedef std::list
<Hook
> HandlerList
;
73 typedef std::map
<GObject
*, HandlerList
> HandlerMap
;
75 GObjectDestructorFILO();
76 ~GObjectDestructorFILO();
77 friend struct base::DefaultSingletonTraits
<GObjectDestructorFILO
>;
79 void WeakNotify(GObject
* where_the_object_was
);
80 static void WeakNotifyThunk(gpointer data
, GObject
* where_the_object_was
) {
81 reinterpret_cast<GObjectDestructorFILO
*>(data
)->WeakNotify(
82 where_the_object_was
);
85 HandlerMap handler_map_
;
87 DISALLOW_COPY_AND_ASSIGN(GObjectDestructorFILO
);
90 } // namespace libgtk2ui
92 #endif // CHROME_BROWSER_UI_LIBGTK2UI_G_OBJECT_DESTRUCTOR_FILO_H_