Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2009 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/ref_counted.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/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() {
     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() {
     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 RefCountedThreadSafeBase::RefCountedThreadSafeBase() : ref_count_(0) {
     55 #ifndef NDEBUG
     56   in_dtor_ = false;
     57 #endif
     58 }
     59 
     60 RefCountedThreadSafeBase::~RefCountedThreadSafeBase() {
     61 #ifndef NDEBUG
     62   DCHECK(in_dtor_) << "RefCountedThreadSafe object deleted without "
     63                       "calling Release()";
     64 #endif
     65 }
     66 
     67 void RefCountedThreadSafeBase::AddRef() {
     68 #ifndef NDEBUG
     69   DCHECK(!in_dtor_);
     70 #endif
     71   AtomicRefCountInc(&ref_count_);
     72 }
     73 
     74 bool RefCountedThreadSafeBase::Release() {
     75 #ifndef NDEBUG
     76   DCHECK(!in_dtor_);
     77   DCHECK(!AtomicRefCountIsZero(&ref_count_));
     78 #endif
     79   if (!AtomicRefCountDec(&ref_count_)) {
     80 #ifndef NDEBUG
     81     in_dtor_ = true;
     82 #endif
     83     return true;
     84   }
     85   return false;
     86 }
     87 
     88 bool RefCountedThreadSafeBase::HasOneRef() const {
     89   return AtomicRefCountIsOne(
     90       &const_cast<RefCountedThreadSafeBase*>(this)->ref_count_);
     91 }
     92 
     93 }  // namespace subtle
     94 
     95 }  // namespace base
     96