Home | History | Annotate | Download | only in memory
      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 
     20 bool RefCountedThreadSafeBase::HasOneRef() const {
     21   return AtomicRefCountIsOne(&ref_count_);
     22 }
     23 
     24 RefCountedThreadSafeBase::~RefCountedThreadSafeBase() {
     25 #if DCHECK_IS_ON()
     26   DCHECK(in_dtor_) << "RefCountedThreadSafe object deleted without "
     27                       "calling Release()";
     28 #endif
     29 }
     30 
     31 void 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 
     42 bool 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()
     57 bool 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()
     66 ScopedAllowCrossThreadRefCountAccess::ScopedAllowCrossThreadRefCountAccess() {
     67   AtomicRefCountInc(&g_cross_thread_ref_count_access_allow_count);
     68 }
     69 
     70 ScopedAllowCrossThreadRefCountAccess::~ScopedAllowCrossThreadRefCountAccess() {
     71   AtomicRefCountDec(&g_cross_thread_ref_count_access_allow_count);
     72 }
     73 #endif
     74 
     75 }  // namespace base
     76