Tweak/Wontfix a few tests that we could care less about.
[chromium-blink-merge.git] / base / weak_ptr.h
blob1bc963e7ef65e19514191e727646c59fd945bcad
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.
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
7 // bound to the lifetime of the referrers. In other words, this is useful when
8 // reference counting is not a good fit.
9 //
10 // A common alternative to weak pointers is to have the shared object hold a
11 // list of all referrers, and then when the shared object is destroyed, it
12 // calls a method on the referrers to tell them to drop their references. This
13 // approach also requires the referrers to tell the shared object when they get
14 // destroyed so that the shared object can remove the referrer from its list of
15 // referrers. Such a solution works, but it is a bit complex.
17 // EXAMPLE:
19 // class Controller : public SupportsWeakPtr<Controller> {
20 // public:
21 // void SpawnWorker() { Worker::StartNew(AsWeakPtr()); }
22 // void WorkComplete(const Result& result) { ... }
23 // };
25 // class Worker {
26 // public:
27 // static void StartNew(const WeakPtr<Controller>& controller) {
28 // Worker* worker = new Worker(controller);
29 // // Kick off asynchronous processing...
30 // }
31 // private:
32 // Worker(const WeakPtr<Controller>& controller)
33 // : controller_(controller) {}
34 // void DidCompleteAsynchronousProcessing(const Result& result) {
35 // if (controller_)
36 // controller_->WorkComplete(result);
37 // }
38 // WeakPtr<Controller> controller_;
39 // };
41 // Given the above classes, a consumer may allocate a Controller object, call
42 // SpawnWorker several times, and then destroy the Controller object before all
43 // of the workers have completed. Because the Worker class only holds a weak
44 // pointer to the Controller, we don't have to worry about the Worker
45 // dereferencing the Controller back pointer after the Controller has been
46 // destroyed.
48 // WARNING: weak pointers are not threadsafe!!! You must only use a WeakPtr
49 // instance on thread where it was created.
51 #ifndef BASE_WEAK_PTR_H_
52 #define BASE_WEAK_PTR_H_
54 #include "base/logging.h"
55 #include "base/non_thread_safe.h"
56 #include "base/ref_counted.h"
58 namespace base {
60 namespace internal {
61 // These classes are part of the WeakPtr implementation.
62 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF.
64 class WeakReference {
65 public:
66 class Flag : public RefCounted<Flag>, public NonThreadSafe {
67 public:
68 Flag(Flag** handle) : handle_(handle) {
71 ~Flag() {
72 if (handle_)
73 *handle_ = NULL;
76 void AddRef() {
77 DCHECK(CalledOnValidThread());
78 RefCounted<Flag>::AddRef();
81 void Release() {
82 DCHECK(CalledOnValidThread());
83 RefCounted<Flag>::Release();
86 void Invalidate() { handle_ = NULL; }
87 bool is_valid() const { return handle_ != NULL; }
89 private:
90 Flag** handle_;
93 WeakReference() {}
94 WeakReference(Flag* flag) : flag_(flag) {}
96 bool is_valid() const { return flag_ && flag_->is_valid(); }
98 private:
99 scoped_refptr<Flag> flag_;
102 class WeakReferenceOwner {
103 public:
104 WeakReferenceOwner() : flag_(NULL) {
107 ~WeakReferenceOwner() {
108 Invalidate();
111 WeakReference GetRef() const {
112 if (!flag_)
113 flag_ = new WeakReference::Flag(&flag_);
114 return WeakReference(flag_);
117 bool HasRefs() const {
118 return flag_ != NULL;
121 void Invalidate() {
122 if (flag_) {
123 flag_->Invalidate();
124 flag_ = NULL;
128 private:
129 mutable WeakReference::Flag* flag_;
132 // This class simplifies the implementation of WeakPtr's type conversion
133 // 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
135 // base class gives us a way to access ref_ in a protected fashion.
136 class WeakPtrBase {
137 public:
138 WeakPtrBase() {
141 protected:
142 WeakPtrBase(const WeakReference& ref) : ref_(ref) {
145 WeakReference ref_;
148 } // namespace internal
150 template <typename T> class SupportsWeakPtr;
151 template <typename T> class WeakPtrFactory;
153 // The WeakPtr class holds a weak reference to |T*|.
155 // This class is designed to be used like a normal pointer. You should always
156 // null-test an object of this class before using it or invoking a method that
157 // may result in the underlying object being destroyed.
159 // EXAMPLE:
161 // class Foo { ... };
162 // WeakPtr<Foo> foo;
163 // if (foo)
164 // foo->method();
166 template <typename T>
167 class WeakPtr : public internal::WeakPtrBase {
168 public:
169 WeakPtr() : ptr_(NULL) {
172 // Allow conversion from U to T provided U "is a" T.
173 template <typename U>
174 WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.get()) {
177 T* get() const { return ref_.is_valid() ? ptr_ : NULL; }
178 operator T*() const { return get(); }
180 T* operator*() const {
181 DCHECK(get() != NULL);
182 return *get();
184 T* operator->() const {
185 DCHECK(get() != NULL);
186 return get();
189 void reset() {
190 ref_ = internal::WeakReference();
191 ptr_ = NULL;
194 private:
195 friend class SupportsWeakPtr<T>;
196 friend class WeakPtrFactory<T>;
198 WeakPtr(const internal::WeakReference& ref, T* ptr)
199 : WeakPtrBase(ref), ptr_(ptr) {
202 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its
203 // value is undefined (as opposed to NULL).
204 T* ptr_;
207 // A class may extend from SupportsWeakPtr to expose weak pointers to itself.
208 // This is useful in cases where you want others to be able to get a weak
209 // pointer to your class. It also has the property that you don't need to
210 // initialize it from your constructor.
211 template <class T>
212 class SupportsWeakPtr {
213 public:
214 SupportsWeakPtr() {}
216 WeakPtr<T> AsWeakPtr() {
217 return WeakPtr<T>(weak_reference_owner_.GetRef(), static_cast<T*>(this));
220 private:
221 internal::WeakReferenceOwner weak_reference_owner_;
222 DISALLOW_COPY_AND_ASSIGN(SupportsWeakPtr);
225 // A class may alternatively be composed of a WeakPtrFactory and thereby
226 // control how it exposes weak pointers to itself. This is helpful if you only
227 // need weak pointers within the implementation of a class. This class is also
228 // useful when working with primitive types. For example, you could have a
229 // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool.
230 template <class T>
231 class WeakPtrFactory {
232 public:
233 explicit WeakPtrFactory(T* ptr) : ptr_(ptr) {
236 WeakPtr<T> GetWeakPtr() {
237 return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_);
240 // Call this method to invalidate all existing weak pointers.
241 void InvalidateWeakPtrs() {
242 weak_reference_owner_.Invalidate();
245 // Call this method to determine if any weak pointers exist.
246 bool HasWeakPtrs() const {
247 return weak_reference_owner_.HasRefs();
250 private:
251 internal::WeakReferenceOwner weak_reference_owner_;
252 T* ptr_;
253 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory);
256 } // namespace base
258 #endif // BASE_WEAK_PTR_H_