OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Weak pointers help in cases where you have many objects referring back to a | 5 // Weak pointers help in cases where you have many objects referring back to a |
6 // shared object and you wish for the lifetime of the shared object to not be | 6 // shared object and you wish for the lifetime of the shared object to not be |
7 // bound to the lifetime of the referrers. In other words, this is useful when | 7 // bound to the lifetime of the referrers. In other words, this is useful when |
8 // reference counting is not a good fit. | 8 // reference counting is not a good fit. |
9 // | 9 // |
10 // A common alternative to weak pointers is to have the shared object hold a | 10 // A common alternative to weak pointers is to have the shared object hold a |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 namespace base { | 58 namespace base { |
59 | 59 |
60 namespace internal { | 60 namespace internal { |
61 // These classes are part of the WeakPtr implementation. | 61 // These classes are part of the WeakPtr implementation. |
62 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF. | 62 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF. |
63 | 63 |
64 class WeakReference { | 64 class WeakReference { |
65 public: | 65 public: |
66 class Flag : public RefCounted<Flag>, public NonThreadSafe { | 66 class Flag : public RefCounted<Flag>, public NonThreadSafe { |
67 public: | 67 public: |
68 Flag(Flag** handle) : handle_(handle) { | 68 Flag(Flag** handle); |
69 } | 69 ~Flag(); |
70 | 70 |
71 ~Flag() { | 71 void AddRef(); |
72 if (handle_) | 72 void Release(); |
73 *handle_ = NULL; | |
74 } | |
75 | |
76 void AddRef() { | |
77 DCHECK(CalledOnValidThread()); | |
78 RefCounted<Flag>::AddRef(); | |
79 } | |
80 | |
81 void Release() { | |
82 DCHECK(CalledOnValidThread()); | |
83 RefCounted<Flag>::Release(); | |
84 } | |
85 | |
86 void Invalidate() { handle_ = NULL; } | 73 void Invalidate() { handle_ = NULL; } |
87 bool is_valid() const { return handle_ != NULL; } | 74 bool is_valid() const { return handle_ != NULL; } |
88 | 75 |
89 private: | 76 private: |
90 Flag** handle_; | 77 Flag** handle_; |
91 }; | 78 }; |
92 | 79 |
93 WeakReference() {} | 80 WeakReference(); |
94 WeakReference(Flag* flag) : flag_(flag) {} | 81 WeakReference(Flag* flag); |
95 | 82 |
96 bool is_valid() const { return flag_ && flag_->is_valid(); } | 83 bool is_valid() const; |
97 | 84 |
98 private: | 85 private: |
99 scoped_refptr<Flag> flag_; | 86 scoped_refptr<Flag> flag_; |
100 }; | 87 }; |
101 | 88 |
102 class WeakReferenceOwner { | 89 class WeakReferenceOwner { |
103 public: | 90 public: |
104 WeakReferenceOwner() : flag_(NULL) { | 91 WeakReferenceOwner(); |
105 } | 92 ~WeakReferenceOwner(); |
106 | 93 |
107 ~WeakReferenceOwner() { | 94 WeakReference GetRef() const; |
108 Invalidate(); | |
109 } | |
110 | |
111 WeakReference GetRef() const { | |
112 if (!flag_) | |
113 flag_ = new WeakReference::Flag(&flag_); | |
114 return WeakReference(flag_); | |
115 } | |
116 | 95 |
117 bool HasRefs() const { | 96 bool HasRefs() const { |
118 return flag_ != NULL; | 97 return flag_ != NULL; |
119 } | 98 } |
120 | 99 |
121 void Invalidate() { | 100 void Invalidate(); |
122 if (flag_) { | |
123 flag_->Invalidate(); | |
124 flag_ = NULL; | |
125 } | |
126 } | |
127 | 101 |
128 private: | 102 private: |
129 mutable WeakReference::Flag* flag_; | 103 mutable WeakReference::Flag* flag_; |
130 }; | 104 }; |
131 | 105 |
132 // This class simplifies the implementation of WeakPtr's type conversion | 106 // This class simplifies the implementation of WeakPtr's type conversion |
133 // constructor by avoiding the need for a public accessor for ref_. A | 107 // constructor by avoiding the need for a public accessor for ref_. A |
134 // WeakPtr<T> cannot access the private members of WeakPtr<U>, so this | 108 // WeakPtr<T> cannot access the private members of WeakPtr<U>, so this |
135 // base class gives us a way to access ref_ in a protected fashion. | 109 // base class gives us a way to access ref_ in a protected fashion. |
136 class WeakPtrBase { | 110 class WeakPtrBase { |
137 public: | 111 public: |
138 WeakPtrBase() { | 112 WeakPtrBase(); |
139 } | |
140 | 113 |
141 protected: | 114 protected: |
142 WeakPtrBase(const WeakReference& ref) : ref_(ref) { | 115 WeakPtrBase(const WeakReference& ref); |
143 } | |
144 | 116 |
145 WeakReference ref_; | 117 WeakReference ref_; |
146 }; | 118 }; |
147 | 119 |
148 } // namespace internal | 120 } // namespace internal |
149 | 121 |
150 template <typename T> class SupportsWeakPtr; | 122 template <typename T> class SupportsWeakPtr; |
151 template <typename T> class WeakPtrFactory; | 123 template <typename T> class WeakPtrFactory; |
152 | 124 |
153 // The WeakPtr class holds a weak reference to |T*|. | 125 // The WeakPtr class holds a weak reference to |T*|. |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 | 221 |
250 private: | 222 private: |
251 internal::WeakReferenceOwner weak_reference_owner_; | 223 internal::WeakReferenceOwner weak_reference_owner_; |
252 T* ptr_; | 224 T* ptr_; |
253 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); | 225 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); |
254 }; | 226 }; |
255 | 227 |
256 } // namespace base | 228 } // namespace base |
257 | 229 |
258 #endif // BASE_WEAK_PTR_H_ | 230 #endif // BASE_WEAK_PTR_H_ |
OLD | NEW |