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/threading/thread_collision_warner.h" 8 9 namespace base { 10 namespace { 11 12 #if DCHECK_IS_ON() 13 AtomicRefCount g_cross_thread_ref_count_access_allow_count = 0; 14 #endif 15 16 } // namespace 17 18 namespace subtle { 19 HasOneRef() const20bool RefCountedThreadSafeBase::HasOneRef() const { 21 return AtomicRefCountIsOne(&ref_count_); 22 } 23 ~RefCountedThreadSafeBase()24RefCountedThreadSafeBase::~RefCountedThreadSafeBase() { 25 #if DCHECK_IS_ON() 26 DCHECK(in_dtor_) << "RefCountedThreadSafe object deleted without " 27 "calling Release()"; 28 #endif 29 } 30 AddRef() const31void RefCountedThreadSafeBase::AddRef() const { 32 #if DCHECK_IS_ON() 33 DCHECK(!in_dtor_); 34 DCHECK(!needs_adopt_ref_) 35 << "This RefCounted object is created with non-zero reference count." 36 << " The first reference to such a object has to be made by AdoptRef or" 37 << " MakeShared."; 38 #endif 39 AtomicRefCountInc(&ref_count_); 40 } 41 Release() const42bool RefCountedThreadSafeBase::Release() const { 43 #if DCHECK_IS_ON() 44 DCHECK(!in_dtor_); 45 DCHECK(!AtomicRefCountIsZero(&ref_count_)); 46 #endif 47 if (!AtomicRefCountDec(&ref_count_)) { 48 #if DCHECK_IS_ON() 49 in_dtor_ = true; 50 #endif 51 return true; 52 } 53 return false; 54 } 55 56 #if DCHECK_IS_ON() CalledOnValidSequence() const57bool RefCountedBase::CalledOnValidSequence() const { 58 return sequence_checker_.CalledOnValidSequence() || 59 !AtomicRefCountIsZero(&g_cross_thread_ref_count_access_allow_count); 60 } 61 #endif 62 63 } // namespace subtle 64 65 #if DCHECK_IS_ON() ScopedAllowCrossThreadRefCountAccess()66ScopedAllowCrossThreadRefCountAccess::ScopedAllowCrossThreadRefCountAccess() { 67 AtomicRefCountInc(&g_cross_thread_ref_count_access_allow_count); 68 } 69 ~ScopedAllowCrossThreadRefCountAccess()70ScopedAllowCrossThreadRefCountAccess::~ScopedAllowCrossThreadRefCountAccess() { 71 AtomicRefCountDec(&g_cross_thread_ref_count_access_allow_count); 72 } 73 #endif 74 75 } // namespace base 76