• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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() const20 bool RefCountedThreadSafeBase::HasOneRef() const {
21   return AtomicRefCountIsOne(&ref_count_);
22 }
23 
~RefCountedThreadSafeBase()24 RefCountedThreadSafeBase::~RefCountedThreadSafeBase() {
25 #if DCHECK_IS_ON()
26   DCHECK(in_dtor_) << "RefCountedThreadSafe object deleted without "
27                       "calling Release()";
28 #endif
29 }
30 
AddRef() const31 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 
Release() const42 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()
CalledOnValidSequence() const57 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()
ScopedAllowCrossThreadRefCountAccess()66 ScopedAllowCrossThreadRefCountAccess::ScopedAllowCrossThreadRefCountAccess() {
67   AtomicRefCountInc(&g_cross_thread_ref_count_access_allow_count);
68 }
69 
~ScopedAllowCrossThreadRefCountAccess()70 ScopedAllowCrossThreadRefCountAccess::~ScopedAllowCrossThreadRefCountAccess() {
71   AtomicRefCountDec(&g_cross_thread_ref_count_access_allow_count);
72 }
73 #endif
74 
75 }  // namespace base
76