Chromium Code Reviews| 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 |