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 10namespace base { 11 12namespace subtle { 13 14RefCountedBase::RefCountedBase() 15 : ref_count_(0) 16#ifndef NDEBUG 17 , in_dtor_(false) 18#endif 19 { 20} 21 22RefCountedBase::~RefCountedBase() { 23#ifndef NDEBUG 24 DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()"; 25#endif 26} 27 28void 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 38bool 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 54bool RefCountedThreadSafeBase::HasOneRef() const { 55 return AtomicRefCountIsOne( 56 &const_cast<RefCountedThreadSafeBase*>(this)->ref_count_); 57} 58 59RefCountedThreadSafeBase::RefCountedThreadSafeBase() : ref_count_(0) { 60#ifndef NDEBUG 61 in_dtor_ = false; 62#endif 63} 64 65RefCountedThreadSafeBase::~RefCountedThreadSafeBase() { 66#ifndef NDEBUG 67 DCHECK(in_dtor_) << "RefCountedThreadSafe object deleted without " 68 "calling Release()"; 69#endif 70} 71 72void RefCountedThreadSafeBase::AddRef() const { 73#ifndef NDEBUG 74 DCHECK(!in_dtor_); 75#endif 76 AtomicRefCountInc(&ref_count_); 77} 78 79bool 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