OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 25 matching lines...) Expand all Loading... | |
36 #define CHECK_REF_COUNTED_LIFECYCLE 1 | 36 #define CHECK_REF_COUNTED_LIFECYCLE 1 |
37 #endif | 37 #endif |
38 | 38 |
39 // This base class holds the non-template methods and attributes. | 39 // This base class holds the non-template methods and attributes. |
40 // The RefCounted class inherits from it reducing the template bloat | 40 // The RefCounted class inherits from it reducing the template bloat |
41 // generated by the compiler (technique called template hoisting). | 41 // generated by the compiler (technique called template hoisting). |
42 class RefCountedBase { | 42 class RefCountedBase { |
43 public: | 43 public: |
44 void ref() | 44 void ref() |
45 { | 45 { |
46 #if CHECK_REF_COUNTED_LIFECYCLE | 46 refBase(); |
47 // Start thread verification as soon as the ref count gets to 2. This | |
48 // heuristic reflects the fact that items are often created on one threa d | |
49 // and then given to another thread to be used. | |
50 // FIXME: Make this restriction tigher. Especially as we move to more | |
51 // common methods for sharing items across threads like CrossThreadCopie r.h | |
52 // We should be able to add a "detachFromThread" method to make this exp licit. | |
53 if (m_refCount == 1) | |
54 m_verifier.setShared(true); | |
55 // If this assert fires, it either indicates a thread safety issue or | |
56 // that the verification needs to change. See ThreadRestrictionVerifier for | |
57 // the different modes. | |
58 ASSERT(m_verifier.isSafeToUse()); | |
59 ASSERT(!m_deletionHasBegun); | |
60 ASSERT(!m_adoptionIsRequired); | |
61 #endif | |
62 ++m_refCount; | |
63 } | 47 } |
64 | 48 |
65 bool hasOneRef() const | 49 bool hasOneRef() const |
66 { | 50 { |
67 #if CHECK_REF_COUNTED_LIFECYCLE | 51 #if CHECK_REF_COUNTED_LIFECYCLE |
68 ASSERT(m_verifier.isSafeToUse()); | 52 ASSERT(m_verifier.isSafeToUse()); |
69 ASSERT(!m_deletionHasBegun); | 53 ASSERT(!m_deletionHasBegun); |
70 #endif | 54 #endif |
71 return m_refCount == 1; | 55 return m_refCount == 1; |
72 } | 56 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
128 } | 112 } |
129 | 113 |
130 ~RefCountedBase() | 114 ~RefCountedBase() |
131 { | 115 { |
132 #if CHECK_REF_COUNTED_LIFECYCLE | 116 #if CHECK_REF_COUNTED_LIFECYCLE |
133 ASSERT(m_deletionHasBegun); | 117 ASSERT(m_deletionHasBegun); |
134 ASSERT(!m_adoptionIsRequired); | 118 ASSERT(!m_adoptionIsRequired); |
135 #endif | 119 #endif |
136 } | 120 } |
137 | 121 |
122 void refBase() | |
123 { | |
124 #if CHECK_REF_COUNTED_LIFECYCLE | |
Mads Ager (chromium)
2013/05/29 12:31:06
When we get into the situation that we have an obj
haraken
2013/05/29 13:37:05
Disabled the check to make the test case workable.
| |
125 // Start thread verification as soon as the ref count gets to 2. This | |
126 // heuristic reflects the fact that items are often created on one threa d | |
127 // and then given to another thread to be used. | |
128 // FIXME: Make this restriction tigher. Especially as we move to more | |
129 // common methods for sharing items across threads like CrossThreadCopie r.h | |
130 // We should be able to add a "detachFromThread" method to make this exp licit. | |
131 if (m_refCount == 1) | |
132 m_verifier.setShared(true); | |
133 // If this assert fires, it either indicates a thread safety issue or | |
134 // that the verification needs to change. See ThreadRestrictionVerifier for | |
135 // the different modes. | |
136 ASSERT(m_verifier.isSafeToUse()); | |
137 ASSERT(!m_deletionHasBegun); | |
138 ASSERT(!m_adoptionIsRequired); | |
139 #endif | |
140 ++m_refCount; | |
141 } | |
142 | |
138 // Returns whether the pointer should be freed or not. | 143 // Returns whether the pointer should be freed or not. |
139 bool derefBase() | 144 bool derefBase() |
140 { | 145 { |
141 #if CHECK_REF_COUNTED_LIFECYCLE | 146 #if CHECK_REF_COUNTED_LIFECYCLE |
142 ASSERT(m_verifier.isSafeToUse()); | 147 ASSERT(m_verifier.isSafeToUse()); |
143 ASSERT(!m_deletionHasBegun); | 148 ASSERT(!m_deletionHasBegun); |
144 ASSERT(!m_adoptionIsRequired); | 149 ASSERT(!m_adoptionIsRequired); |
145 #endif | 150 #endif |
146 | 151 |
147 ASSERT(m_refCount > 0); | 152 ASSERT(m_refCount > 0); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
189 if (!object) | 194 if (!object) |
190 return; | 195 return; |
191 ASSERT(!object->m_deletionHasBegun); | 196 ASSERT(!object->m_deletionHasBegun); |
192 object->m_adoptionIsRequired = false; | 197 object->m_adoptionIsRequired = false; |
193 } | 198 } |
194 #endif | 199 #endif |
195 | 200 |
196 template<typename T> class RefCounted : public RefCountedBase { | 201 template<typename T> class RefCounted : public RefCountedBase { |
197 WTF_MAKE_NONCOPYABLE(RefCounted); WTF_MAKE_FAST_ALLOCATED; | 202 WTF_MAKE_NONCOPYABLE(RefCounted); WTF_MAKE_FAST_ALLOCATED; |
198 public: | 203 public: |
204 void ref() | |
205 { | |
206 refBase(); | |
207 } | |
208 | |
199 void deref() | 209 void deref() |
200 { | 210 { |
201 if (derefBase()) | 211 if (derefBase()) |
202 delete static_cast<T*>(this); | 212 delete static_cast<T*>(this); |
203 } | 213 } |
204 | 214 |
205 protected: | 215 protected: |
206 RefCounted() { } | 216 RefCounted() { } |
207 ~RefCounted() | 217 ~RefCounted() |
208 { | 218 { |
209 } | 219 } |
210 }; | 220 }; |
211 | 221 |
212 template<typename T> class RefCountedCustomAllocated : public RefCountedBase { | 222 template<typename T> class RefCountedCustomAllocated : public RefCountedBase { |
213 WTF_MAKE_NONCOPYABLE(RefCountedCustomAllocated); | 223 WTF_MAKE_NONCOPYABLE(RefCountedCustomAllocated); |
214 | 224 |
215 public: | 225 public: |
226 void ref() | |
227 { | |
228 refBase(); | |
229 } | |
230 | |
216 void deref() | 231 void deref() |
217 { | 232 { |
218 if (derefBase()) | 233 if (derefBase()) |
219 delete static_cast<T*>(this); | 234 delete static_cast<T*>(this); |
220 } | 235 } |
221 | 236 |
222 protected: | 237 protected: |
223 ~RefCountedCustomAllocated() | 238 ~RefCountedCustomAllocated() |
224 { | 239 { |
225 } | 240 } |
(...skipping 18 matching lines...) Expand all Loading... | |
244 inline void RefCountedBase::setDispatchQueueForVerifier(dispatch_queue_t) { } | 259 inline void RefCountedBase::setDispatchQueueForVerifier(dispatch_queue_t) { } |
245 #endif | 260 #endif |
246 #endif // HAVE(DISPATCH_H) | 261 #endif // HAVE(DISPATCH_H) |
247 | 262 |
248 } // namespace WTF | 263 } // namespace WTF |
249 | 264 |
250 using WTF::RefCounted; | 265 using WTF::RefCounted; |
251 using WTF::RefCountedCustomAllocated; | 266 using WTF::RefCountedCustomAllocated; |
252 | 267 |
253 #endif // RefCounted_h | 268 #endif // RefCounted_h |
OLD | NEW |