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/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