Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: base/memory/weak_ptr.h

Issue 2966633002: Revert of Make base::WeakPtr::Get() fast (Closed)
Patch Set: resolve conflict Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | base/memory/weak_ptr.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 are pointers to an object that do not affect its lifetime, 5 // Weak pointers are pointers to an object that do not affect its lifetime,
6 // and which may be invalidated (i.e. reset to nullptr) by the object, or its 6 // and which may be invalidated (i.e. reset to nullptr) by the object, or its
7 // owner, at any time, most commonly when the object is about to be deleted. 7 // owner, at any time, most commonly when the object is about to be deleted.
8 8
9 // Weak pointers are useful when an object needs to be accessed safely by one 9 // Weak pointers are useful when an object needs to be accessed safely by one
10 // or more objects other than its owner, and those callers can cope with the 10 // or more objects other than its owner, and those callers can cope with the
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF. 89 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF.
90 90
91 class BASE_EXPORT WeakReference { 91 class BASE_EXPORT WeakReference {
92 public: 92 public:
93 // Although Flag is bound to a specific SequencedTaskRunner, it may be 93 // Although Flag is bound to a specific SequencedTaskRunner, it may be
94 // deleted from another via base::WeakPtr::~WeakPtr(). 94 // deleted from another via base::WeakPtr::~WeakPtr().
95 class BASE_EXPORT Flag : public RefCountedThreadSafe<Flag> { 95 class BASE_EXPORT Flag : public RefCountedThreadSafe<Flag> {
96 public: 96 public:
97 Flag(); 97 Flag();
98 98
99 // Get a pointer to the "Null Flag", a sentinel object used by WeakReference 99 void Invalidate();
100 // objects that don't point to a valid Flag, either because they're default 100 bool IsValid() const;
101 // constructed or because they have been invalidated. This can be used like
102 // any other Flag object, but it is invalidated already from the start, and
103 // its refcount will never reach zero.
104 static Flag* NullFlag();
105
106 void Invalidate() {
107 #if DCHECK_IS_ON()
108 if (this == NullFlag()) {
109 // The Null Flag does not participate in the sequence checks below.
110 // Since its state never changes, it can be accessed from any thread.
111 DCHECK(!is_valid_);
112 return;
113 }
114 // The flag being invalidated with a single ref implies that there are no
115 // weak pointers in existence. Allow deletion on other thread in this
116 // case.
117 DCHECK(sequence_checker_.CalledOnValidSequence() || HasOneRef())
118 << "WeakPtrs must be invalidated on the same sequenced thread.";
119 #endif
120 is_valid_ = 0;
121 }
122
123 // Returns a pointer-sized bitmask of all 1s if valid or all 0s otherwise.
124 uintptr_t IsValid() const {
125 #if DCHECK_IS_ON()
126 if (this == NullFlag()) {
127 // The Null Flag does not participate in the sequence checks below.
128 // Since its state never changes, it can be accessed from any thread.
129 DCHECK(!is_valid_);
130 return 0;
131 }
132 DCHECK(sequence_checker_.CalledOnValidSequence())
133 << "WeakPtrs must be checked on the same sequenced thread.";
134 #endif
135 return is_valid_;
136 }
137 101
138 private: 102 private:
139 friend class base::RefCountedThreadSafe<Flag>; 103 friend class base::RefCountedThreadSafe<Flag>;
140 104
141 enum NullFlagTag { kNullFlagTag };
142 Flag(NullFlagTag);
143
144 ~Flag(); 105 ~Flag();
145 106
146 uintptr_t is_valid_;
147 #if DCHECK_IS_ON()
148 // Even if SequenceChecker is an empty class in non-dcheck builds, it still
149 // takes up space in the class.
150 SequenceChecker sequence_checker_; 107 SequenceChecker sequence_checker_;
151 #endif 108 bool is_valid_;
152 }; 109 };
153 110
154 WeakReference(); 111 WeakReference();
155 explicit WeakReference(const Flag* flag); 112 explicit WeakReference(const Flag* flag);
156 ~WeakReference(); 113 ~WeakReference();
157 114
158 WeakReference(WeakReference&& other); 115 WeakReference(WeakReference&& other);
159 WeakReference(const WeakReference& other); 116 WeakReference(const WeakReference& other);
160 WeakReference& operator=(WeakReference&& other) = default; 117 WeakReference& operator=(WeakReference&& other) = default;
161 WeakReference& operator=(const WeakReference& other) = default; 118 WeakReference& operator=(const WeakReference& other) = default;
162 119
163 uintptr_t is_valid() const { return flag_->IsValid(); } 120 bool is_valid() const;
164 121
165 private: 122 private:
166 // Note: To avoid null-checks, flag_ always points to either Flag::NullFlag()
167 // or some other object.
168 scoped_refptr<const Flag> flag_; 123 scoped_refptr<const Flag> flag_;
169 }; 124 };
170 125
171 class BASE_EXPORT WeakReferenceOwner { 126 class BASE_EXPORT WeakReferenceOwner {
172 public: 127 public:
173 WeakReferenceOwner(); 128 WeakReferenceOwner();
174 ~WeakReferenceOwner(); 129 ~WeakReferenceOwner();
175 130
176 WeakReference GetRef() const; 131 WeakReference GetRef() const;
177 132
178 bool HasRefs() const { 133 bool HasRefs() const {
179 return flag_ != WeakReference::Flag::NullFlag() && !flag_->HasOneRef(); 134 return flag_.get() && !flag_->HasOneRef();
180 } 135 }
181 136
182 void Invalidate(); 137 void Invalidate();
183 138
184 private: 139 private:
185 mutable scoped_refptr<WeakReference::Flag> flag_; 140 mutable scoped_refptr<WeakReference::Flag> flag_;
186 }; 141 };
187 142
188 // This class simplifies the implementation of WeakPtr's type conversion 143 // This class simplifies the implementation of WeakPtr's type conversion
189 // constructor by avoiding the need for a public accessor for ref_. A 144 // constructor by avoiding the need for a public accessor for ref_. A
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 } 229 }
275 template <typename U> 230 template <typename U>
276 WeakPtr(WeakPtr<U>&& other) : WeakPtrBase(std::move(other)) { 231 WeakPtr(WeakPtr<U>&& other) : WeakPtrBase(std::move(other)) {
277 // Need to cast from U* to T* to do pointer adjustment in case of multiple 232 // Need to cast from U* to T* to do pointer adjustment in case of multiple
278 // inheritance. This also enforces the "U is a T" rule. 233 // inheritance. This also enforces the "U is a T" rule.
279 T* t = reinterpret_cast<U*>(other.ptr_); 234 T* t = reinterpret_cast<U*>(other.ptr_);
280 ptr_ = reinterpret_cast<uintptr_t>(t); 235 ptr_ = reinterpret_cast<uintptr_t>(t);
281 } 236 }
282 237
283 T* get() const { 238 T* get() const {
284 // Intentionally bitwise and; see command on Flag::IsValid(). This provides 239 return ref_.is_valid() ? reinterpret_cast<T*>(ptr_) : nullptr;
285 // a fast way of conditionally retrieving the pointer, and conveniently sets
286 // EFLAGS for any null-check performed by the caller.
287 return reinterpret_cast<T*>(ref_.is_valid() & ptr_);
288 } 240 }
289 241
290 T& operator*() const { 242 T& operator*() const {
291 DCHECK(get() != nullptr); 243 DCHECK(get() != nullptr);
292 return *get(); 244 return *get();
293 } 245 }
294 T* operator->() const { 246 T* operator->() const {
295 DCHECK(get() != nullptr); 247 DCHECK(get() != nullptr);
296 return get(); 248 return get();
297 } 249 }
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. 370 // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails.
419 371
420 template <typename Derived> 372 template <typename Derived>
421 WeakPtr<Derived> AsWeakPtr(Derived* t) { 373 WeakPtr<Derived> AsWeakPtr(Derived* t) {
422 return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); 374 return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t);
423 } 375 }
424 376
425 } // namespace base 377 } // namespace base
426 378
427 #endif // BASE_MEMORY_WEAK_PTR_H_ 379 #endif // BASE_MEMORY_WEAK_PTR_H_
OLDNEW
« no previous file with comments | « no previous file | base/memory/weak_ptr.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698