1 /*
2  *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "rtc_base/weak_ptr.h"
12 
13 // The implementation is borrowed from chromium except that it does not
14 // implement SupportsWeakPtr.
15 
16 namespace rtc {
17 namespace internal {
18 
Flag()19 WeakReference::Flag::Flag() : is_valid_(true) {
20   // Flags only become bound when checked for validity, or invalidated,
21   // so that we can check that later validity/invalidation operations on
22   // the same Flag take place on the same sequence.
23   checker_.Detach();
24 }
25 
Invalidate()26 void WeakReference::Flag::Invalidate() {
27   RTC_DCHECK(checker_.IsCurrent())
28       << "WeakPtrs must be invalidated on the same sequence.";
29   is_valid_ = false;
30 }
31 
IsValid() const32 bool WeakReference::Flag::IsValid() const {
33   RTC_DCHECK(checker_.IsCurrent())
34       << "WeakPtrs must be checked on the same sequence.";
35   return is_valid_;
36 }
37 
~Flag()38 WeakReference::Flag::~Flag() {}
39 
WeakReference()40 WeakReference::WeakReference() {}
41 
WeakReference(const Flag * flag)42 WeakReference::WeakReference(const Flag* flag) : flag_(flag) {}
43 
~WeakReference()44 WeakReference::~WeakReference() {}
45 
46 WeakReference::WeakReference(WeakReference&& other) = default;
47 
48 WeakReference::WeakReference(const WeakReference& other) = default;
49 
is_valid() const50 bool WeakReference::is_valid() const {
51   return flag_.get() && flag_->IsValid();
52 }
53 
WeakReferenceOwner()54 WeakReferenceOwner::WeakReferenceOwner() {}
55 
~WeakReferenceOwner()56 WeakReferenceOwner::~WeakReferenceOwner() {
57   Invalidate();
58 }
59 
GetRef() const60 WeakReference WeakReferenceOwner::GetRef() const {
61   // If we hold the last reference to the Flag then create a new one.
62   if (!HasRefs())
63     flag_ = new RefCountedObject<WeakReference::Flag>();
64 
65   return WeakReference(flag_.get());
66 }
67 
Invalidate()68 void WeakReferenceOwner::Invalidate() {
69   if (flag_.get()) {
70     flag_->Invalidate();
71     flag_ = nullptr;
72   }
73 }
74 
WeakPtrBase()75 WeakPtrBase::WeakPtrBase() {}
76 
~WeakPtrBase()77 WeakPtrBase::~WeakPtrBase() {}
78 
WeakPtrBase(const WeakReference & ref)79 WeakPtrBase::WeakPtrBase(const WeakReference& ref) : ref_(ref) {}
80 
81 }  // namespace internal
82 }  // namespace rtc
83