aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk')
-rw-r--r--src/FbTk/RefCount.hh57
1 files changed, 39 insertions, 18 deletions
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>