blob: 2fd670b35532a61c9fd7dff8f9d01f73c32e591c [file] [log] [blame]
[email protected]3125d6462009-09-01 20:50:171// 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.
4
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.
16//
17// EXAMPLE:
18//
19// class Controller : public SupportsWeakPtr {
20// public:
21// void SpawnWorker() { Worker::StartNew(GetWeakPtr()); }
22// void WorkComplete(const Result& result) { ... }
23// };
24//
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// };
40//
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.
47//
48// WARNING: weak pointers are not threadsafe!!! You must only use a WeakPtr
49// instance on thread where it was created.
50
51#ifndef BASE_WEAK_PTR_H_
52#define BASE_WEAK_PTR_H_
53
54#include "base/logging.h"
55#include "base/non_thread_safe.h"
56#include "base/ref_counted.h"
57
58namespace base {
59
60namespace internal {
61// These classes are part of the WeakPtr implementation.
62// DO NOT USE THESE CLASSES DIRECTLY YOURSELF.
63
64class WeakReference {
65 public:
66 void EnsureInitialized() {
67 // Lazy initialization helps faciliate the NonThreadSafe debug checks.
68 if (!flag_) {
69 flag_ = new Flag();
70 flag_->data = true;
71 }
72 }
73
74 void Invalidate() {
[email protected]d52e97092009-09-17 00:31:0975 if (flag_) {
76 DCHECK(flag_->CalledOnValidThread());
[email protected]3125d6462009-09-01 20:50:1777 flag_->data = false;
[email protected]d52e97092009-09-17 00:31:0978 }
[email protected]3125d6462009-09-01 20:50:1779 }
80
[email protected]d52e97092009-09-17 00:31:0981 bool is_valid() const {
82 if (flag_) {
83 DCHECK(flag_->CalledOnValidThread());
84 return flag_->data;
85 }
86 return false;
87 }
[email protected]3125d6462009-09-01 20:50:1788
89 private:
90 // A reference counted boolean that is true when the weak reference is valid
91 // and false otherwise.
92 class Flag : public RefCountedData<bool>, public NonThreadSafe {
[email protected]d52e97092009-09-17 00:31:0993 public:
94 void AddRef() {
95 DCHECK(CalledOnValidThread());
96 RefCountedData<bool>::AddRef();
97 }
98
99 void Release() {
100 DCHECK(CalledOnValidThread());
101 RefCountedData<bool>::Release();
102 }
[email protected]3125d6462009-09-01 20:50:17103 };
104
105 scoped_refptr<Flag> flag_;
106};
107
108class WeakReferenceOwner {
109 public:
110 ~WeakReferenceOwner() {
111 ref_.Invalidate();
112 }
113
114 const WeakReference& GetRef() const {
115 ref_.EnsureInitialized();
116 return ref_;
117 }
118
119 void Invalidate() { ref_.Invalidate(); }
120
121 private:
122 mutable WeakReference ref_;
123};
124
125// This class simplifies the implementation of WeakPtr's type conversion
126// constructor by avoiding the need for a public accessor for ref_. A
127// WeakPtr<T> cannot access the private members of WeakPtr<U>, so this
128// base class gives us a way to access ref_ in a protected fashion.
129class WeakPtrBase {
130 public:
131 WeakPtrBase() {
132 }
133
134 protected:
135 WeakPtrBase(const WeakReference& ref) : ref_(ref) {
136 }
137
138 WeakReference ref_;
139};
140
141} // namespace internal
142
143template <typename T> class SupportsWeakPtr;
144template <typename T> class WeakPtrFactory;
145
146// The WeakPtr class holds a weak reference to |T*|.
147//
148// This class is designed to be used like a normal pointer. You should always
149// null-test an object of this class before using it or invoking a method that
150// may result in the underlying object being destroyed.
151//
152// EXAMPLE:
153//
154// class Foo { ... };
155// WeakPtr<Foo> foo;
156// if (foo)
157// foo->method();
158//
159template <typename T>
160class WeakPtr : public internal::WeakPtrBase {
161 public:
162 WeakPtr() : ptr_(NULL) {
163 }
164
165 // Allow conversion from U to T provided U "is a" T.
166 template <typename U>
167 WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.get()) {
168 }
169
170 T* get() const { return ref_.is_valid() ? ptr_ : NULL; }
171 operator T*() const { return get(); }
172
173 T* operator*() const {
174 DCHECK(get() != NULL);
175 return *get();
176 }
177 T* operator->() const {
178 DCHECK(get() != NULL);
179 return get();
180 }
181
[email protected]f103ab72009-09-02 17:10:59182 void reset() {
183 ref_ = internal::WeakReference();
184 ptr_ = NULL;
185 }
186
[email protected]3125d6462009-09-01 20:50:17187 private:
188 friend class SupportsWeakPtr<T>;
189 friend class WeakPtrFactory<T>;
190
191 WeakPtr(const internal::WeakReference& ref, T* ptr)
192 : WeakPtrBase(ref), ptr_(ptr) {
193 }
194
195 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its
196 // value is undefined (as opposed to NULL).
197 T* ptr_;
198};
199
200// A class may extend from SupportsWeakPtr to expose weak pointers to itself.
201// This is useful in cases where you want others to be able to get a weak
202// pointer to your class. It also has the property that you don't need to
203// initialize it from your constructor.
204template <class T>
205class SupportsWeakPtr {
206 public:
207 SupportsWeakPtr() {}
208
209 WeakPtr<T> AsWeakPtr() {
210 return WeakPtr<T>(weak_reference_owner_.GetRef(), static_cast<T*>(this));
211 }
212
213 private:
214 internal::WeakReferenceOwner weak_reference_owner_;
215 DISALLOW_COPY_AND_ASSIGN(SupportsWeakPtr);
216};
217
218// A class may alternatively be composed of a WeakPtrFactory and thereby
219// control how it exposes weak pointers to itself. This is helpful if you only
220// need weak pointers within the implementation of a class. This class is also
221// useful when working with primitive types. For example, you could have a
222// WeakPtrFactory<bool> that is used to pass around a weak reference to a bool.
223template <class T>
224class WeakPtrFactory {
225 public:
226 explicit WeakPtrFactory(T* ptr) : ptr_(ptr) {
227 }
228
229 WeakPtr<T> GetWeakPtr() {
230 return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_);
231 }
232
233 // Call this method to invalidate all existing weak pointers.
234 void InvalidateWeakPtrs() { weak_reference_owner_.Invalidate(); }
235
236 private:
237 internal::WeakReferenceOwner weak_reference_owner_;
238 T* ptr_;
239 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory);
240};
241
242} // namespace base
243
244#endif // BASE_WEAK_PTR_H_