1 // Copyright (c) 2011 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/memory/ref_counted.h" 6 7 #include "base/logging.h" 8 #include "base/threading/thread_collision_warner.h" 9 10 namespace base { 11 12 namespace subtle { 13 14 RefCountedBase::RefCountedBase() 15 : ref_count_(0) 16 #ifndef NDEBUG 17 , in_dtor_(false) 18 #endif 19 { 20 } 21 22 RefCountedBase::~RefCountedBase() { 23 #ifndef NDEBUG 24 DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()"; 25 #endif 26 } 27 28 void RefCountedBase::AddRef() const { 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 38 bool RefCountedBase::Release() const { 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 54 bool RefCountedThreadSafeBase::HasOneRef() const { 55 return AtomicRefCountIsOne( 56 &const_cast<RefCountedThreadSafeBase*>(this)->ref_count_); 57 } 58 59 RefCountedThreadSafeBase::RefCountedThreadSafeBase() : ref_count_(0) { 60 #ifndef NDEBUG 61 in_dtor_ = false; 62 #endif 63 } 64 65 RefCountedThreadSafeBase::~RefCountedThreadSafeBase() { 66 #ifndef NDEBUG 67 DCHECK(in_dtor_) << "RefCountedThreadSafe object deleted without " 68 "calling Release()"; 69 #endif 70 } 71 72 void RefCountedThreadSafeBase::AddRef() const { 73 #ifndef NDEBUG 74 DCHECK(!in_dtor_); 75 #endif 76 AtomicRefCountInc(&ref_count_); 77 } 78 79 bool RefCountedThreadSafeBase::Release() const { 80 #ifndef NDEBUG 81 DCHECK(!in_dtor_); 82 DCHECK(!AtomicRefCountIsZero(&ref_count_)); 83 #endif 84 if (!AtomicRefCountDec(&ref_count_)) { 85 #ifndef NDEBUG 86 in_dtor_ = true; 87 #endif 88 return true; 89 } 90 return false; 91 } 92 93 } // namespace subtle 94 95 } // namespace base 96