aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--src/FbTk/RefCount.hh57
-rw-r--r--src/Slit.cc6
-rw-r--r--src/Slit.hh2
4 files changed, 45 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index ff1e160..eee970c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,8 @@
1 (Format: Year/Month/Day) 1 (Format: Year/Month/Day)
2Changes for 1.0rc3: 2Changes for 1.0rc3:
3*07/01/07: 3*07/01/07:
4 * Fix RefCount crash and Slit deconstruction ordering (Simon)
5 RefCount.hh Slit.hh/cc
4 * Support per-window transparency settings. 6 * Support per-window transparency settings.
5 - new "Transparency" menu in the window menu 7 - new "Transparency" menu in the window menu
6 - new apps file attribute: 8 - new apps file attribute:
diff --git a/src/FbTk/RefCount.hh b/src/FbTk/RefCount.hh
index ba2a697..ab4c663 100644
--- a/src/FbTk/RefCount.hh
+++ b/src/FbTk/RefCount.hh
@@ -25,6 +25,7 @@
25namespace FbTk { 25namespace FbTk {
26 26
27/// holds a pointer with reference counting, similar to std:auto_ptr 27/// holds a pointer with reference counting, similar to std:auto_ptr
28
28template <typename Pointer> 29template <typename Pointer>
29class RefCount { 30class RefCount {
30public: 31public:
@@ -43,37 +44,47 @@ public:
43 unsigned int usedBy() const { return (m_refcount != 0 ? *m_refcount : 0); } 44 unsigned int usedBy() const { return (m_refcount != 0 ? *m_refcount : 0); }
44#endif 45#endif
45private: 46private:
46 /// increase referense count 47 /// increase reference count
47 void incRefCount(); 48 void incRefCount();
48 /// decrease referense count 49 /// decrease reference count
49 void decRefCount(); 50 void decRefCount();
51 /// decrease refcount count
52 void decRefCountCount();
50 Pointer *m_data; ///< data holder 53 Pointer *m_data; ///< data holder
51 mutable unsigned int *m_refcount; ///< holds reference counting 54 mutable unsigned int *m_refcount; ///< holds reference counting
55
56 // This one counts the number of active references pointing to the m_refcount data!
57 // when it reaches zero, *then* we can delete it, otherwise someone else might check it.
58 mutable unsigned int *m_refcount_count; ///< holds reference counting
52}; 59};
53 60
54// implementation 61// implementation
55 62
56template <typename Pointer> 63template <typename Pointer>
57RefCount<Pointer>::RefCount():m_data(0), m_refcount(new unsigned int(0)) { 64RefCount<Pointer>::RefCount():m_data(0), m_refcount(new unsigned int(0)), m_refcount_count(new unsigned int(1)) {
58 65
59} 66}
60 67
61template <typename Pointer> 68template <typename Pointer>
62RefCount<Pointer>::RefCount(RefCount<Pointer> &copy): 69RefCount<Pointer>::RefCount(RefCount<Pointer> &copy):
63 m_data(copy.m_data), 70 m_data(copy.m_data),
64 m_refcount(copy.m_refcount) { 71 m_refcount(copy.m_refcount),
72 m_refcount_count(copy.m_refcount_count) {
73 (*m_refcount_count)++;
65 incRefCount(); 74 incRefCount();
66} 75}
67 76
68template <typename Pointer> 77template <typename Pointer>
69RefCount<Pointer>::RefCount(Pointer *p):m_data(p), m_refcount(new unsigned int(0)) { 78RefCount<Pointer>::RefCount(Pointer *p):m_data(p), m_refcount(new unsigned int(0)), m_refcount_count(new unsigned int(1)) {
70 incRefCount(); 79 incRefCount();
71} 80}
72 81
73template <typename Pointer> 82template <typename Pointer>
74RefCount<Pointer>::RefCount(const RefCount<Pointer> &copy): 83RefCount<Pointer>::RefCount(const RefCount<Pointer> &copy):
75 m_data(copy.m_data), 84 m_data(copy.m_data),
76 m_refcount(copy.m_refcount) { 85 m_refcount(copy.m_refcount),
86 m_refcount_count(copy.m_refcount_count) {
87 (*m_refcount_count)++;
77 incRefCount(); 88 incRefCount();
78} 89}
79 90
@@ -86,6 +97,8 @@ template <typename Pointer>
86RefCount<Pointer> &RefCount<Pointer>::operator = (const RefCount<Pointer> &copy) { 97RefCount<Pointer> &RefCount<Pointer>::operator = (const RefCount<Pointer> &copy) {
87 decRefCount(); // dec current ref count 98 decRefCount(); // dec current ref count
88 m_refcount = copy.m_refcount; // set new ref count 99 m_refcount = copy.m_refcount; // set new ref count
100 m_refcount_count = copy.m_refcount_count;
101 (*m_refcount_count)++;
89 m_data = copy.m_data; // set new data pointer 102 m_data = copy.m_data; // set new data pointer
90 incRefCount(); // inc new ref count 103 incRefCount(); // inc new ref count
91 return *this; 104 return *this;
@@ -96,27 +109,35 @@ RefCount<Pointer> &RefCount<Pointer>::operator = (Pointer *p) {
96 decRefCount(); 109 decRefCount();
97 m_data = p; // set data pointer 110 m_data = p; // set data pointer
98 m_refcount = new unsigned int(0); // create new counter 111 m_refcount = new unsigned int(0); // create new counter
112 m_refcount_count = new unsigned int(1);
99 incRefCount(); 113 incRefCount();
100 return *this; 114 return *this;
101} 115}
102 116
103template <typename Pointer> 117template <typename Pointer>
104void RefCount<Pointer>::decRefCount() { 118void RefCount<Pointer>::decRefCount() {
105 if (m_refcount == 0) 119 if (m_refcount != 0) {
106 return; 120 (*m_refcount)--;
107 if (*m_refcount == 0) { // already zero, then delete refcount 121 if (*m_refcount == 0) { // destroy m_data and m_refcount if nobody else is using this
108 delete m_refcount; 122 if (m_data != 0)
109 m_refcount = 0; 123 delete m_data;
110 return; 124 m_data = 0;
125 }
111 } 126 }
112 (*m_refcount)--; 127 decRefCountCount();
113 if (*m_refcount == 0) { // destroy m_data and m_refcount if nobody else is using this 128}
114 if (m_data != 0) 129
115 delete m_data; 130template <typename Pointer>
116 m_data = 0; 131void RefCount<Pointer>::decRefCountCount() {
132 if (*m_refcount_count == 0)
133 return; // shouldnt happen
134 (*m_refcount_count)--;
135 if (*m_refcount_count == 0) {
117 delete m_refcount; 136 delete m_refcount;
118 m_refcount = 0; 137 delete m_refcount_count;
119 } 138 }
139 m_refcount = 0;
140 m_refcount_count = 0;
120} 141}
121 142
122template <typename Pointer> 143template <typename Pointer>
diff --git a/src/Slit.cc b/src/Slit.cc
index e9e2e91..fb12ca6 100644
--- a/src/Slit.cc
+++ b/src/Slit.cc
@@ -261,12 +261,12 @@ unsigned int Slit::s_eventmask = SubstructureRedirectMask | ButtonPressMask |
261Slit::Slit(BScreen &scr, FbTk::XLayer &layer, const char *filename) 261Slit::Slit(BScreen &scr, FbTk::XLayer &layer, const char *filename)
262 : m_hidden(false), 262 : m_hidden(false),
263 m_screen(scr), 263 m_screen(scr),
264 m_slitmenu(scr.menuTheme(),
265 scr.imageControl(),
266 *scr.layerManager().getLayer(Layer::MENU)),
267 m_clientlist_menu(scr.menuTheme(), 264 m_clientlist_menu(scr.menuTheme(),
268 scr.imageControl(), 265 scr.imageControl(),
269 *scr.layerManager().getLayer(Layer::MENU)), 266 *scr.layerManager().getLayer(Layer::MENU)),
267 m_slitmenu(scr.menuTheme(),
268 scr.imageControl(),
269 *scr.layerManager().getLayer(Layer::MENU)),
270 frame(scr.rootWindow()), 270 frame(scr.rootWindow()),
271 //For KDE dock applets 271 //For KDE dock applets
272 m_kwm1_dockwindow(XInternAtom(FbTk::App::instance()->display(), 272 m_kwm1_dockwindow(XInternAtom(FbTk::App::instance()->display(),
diff --git a/src/Slit.hh b/src/Slit.hh
index cb5b11c..ef1c58e 100644
--- a/src/Slit.hh
+++ b/src/Slit.hh
@@ -145,8 +145,8 @@ private:
145 FbTk::Timer m_timer; 145 FbTk::Timer m_timer;
146 146
147 SlitClients m_client_list; 147 SlitClients m_client_list;
148 FbMenu m_slitmenu, m_clientlist_menu;
149 std::auto_ptr<LayerMenu> m_layermenu; 148 std::auto_ptr<LayerMenu> m_layermenu;
149 FbMenu m_clientlist_menu, m_slitmenu;
150 std::string m_filename; 150 std::string m_filename;
151 151
152 struct frame { 152 struct frame {