1 // Copyright (c) 2009 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. 4 5 #include "base/ref_counted.h" 6 7 #include "base/logging.h" 8 #include "base/thread_collision_warner.h" 9 10 namespace base { 11 12 namespace subtle { 13 RefCountedBase()14RefCountedBase::RefCountedBase() 15 : ref_count_(0) 16 #ifndef NDEBUG 17 , in_dtor_(false) 18 #endif 19 { 20 } 21 ~RefCountedBase()22RefCountedBase::~RefCountedBase() { 23 #ifndef NDEBUG 24 DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()"; 25 #endif 26 } 27 AddRef()28void RefCountedBase::AddRef() { 29 // TODO(maruel): Add back once it doesn't assert 500 times/sec. 30 // Current thread books the critical section "AddRelease" without release it. 31 // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_); 32 #ifndef NDEBUG 33 DCHECK(!in_dtor_); 34 #endif 35 ++ref_count_; 36 } 37 Release()38bool RefCountedBase::Release() { 39 // TODO(maruel): Add back once it doesn't assert 500 times/sec. 40 // Current thread books the critical section "AddRelease" without release it. 41 // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_); 42 #ifndef NDEBUG 43 DCHECK(!in_dtor_); 44 #endif 45 if (--ref_count_ == 0) { 46 #ifndef NDEBUG 47 in_dtor_ = true; 48 #endif 49 return true; 50 } 51 return false; 52 } 53 RefCountedThreadSafeBase()54RefCountedThreadSafeBase::RefCountedThreadSafeBase() : ref_count_(0) { 55 #ifndef NDEBUG 56 in_dtor_ = false; 57 #endif 58 } 59 ~RefCountedThreadSafeBase()60RefCountedThreadSafeBase::~RefCountedThreadSafeBase() { 61 #ifndef NDEBUG 62 DCHECK(in_dtor_) << "RefCountedThreadSafe object deleted without " 63 "calling Release()"; 64 #endif 65 } 66 AddRef()67void RefCountedThreadSafeBase::AddRef() { 68 #ifndef NDEBUG 69 DCHECK(!in_dtor_); 70 #endif 71 AtomicRefCountInc(&ref_count_); 72 } 73 Release()74bool RefCountedThreadSafeBase::Release() { 75 #ifndef NDEBUG 76 DCHECK(!in_dtor_); 77 DCHECK(!AtomicRefCountIsZero(&ref_count_)); 78 #endif 79 if (!AtomicRefCountDec(&ref_count_)) { 80 #ifndef NDEBUG 81 in_dtor_ = true; 82 #endif 83 return true; 84 } 85 return false; 86 } 87 HasOneRef() const88bool RefCountedThreadSafeBase::HasOneRef() const { 89 return AtomicRefCountIsOne( 90 &const_cast<RefCountedThreadSafeBase*>(this)->ref_count_); 91 } 92 93 } // namespace subtle 94 95 } // namespace base 96