blob: c0ba7f51c22691bda4c527b102ccfbc9fca35cb5 [file] [log] [blame]
[email protected]7f18b7c42012-02-24 09:13:091// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]3125d6462009-09-01 20:50:172// 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//
[email protected]1edefc42011-08-26 17:32:2910// Thread-safety notes:
11// When you get a WeakPtr (from a WeakPtrFactory or SupportsWeakPtr),
12// the WeakPtr becomes bound to the current thread. You may only
13// dereference the WeakPtr on that thread. However, it is safe to
14// destroy the WeakPtr object on another thread.
15// Since a WeakPtr object may be destroyed on a background thread,
16// querying WeakPtrFactory's HasWeakPtrs() method can be racy.
17//
18//
[email protected]3125d6462009-09-01 20:50:1719// A common alternative to weak pointers is to have the shared object hold a
20// list of all referrers, and then when the shared object is destroyed, it
21// calls a method on the referrers to tell them to drop their references. This
22// approach also requires the referrers to tell the shared object when they get
23// destroyed so that the shared object can remove the referrer from its list of
24// referrers. Such a solution works, but it is a bit complex.
25//
26// EXAMPLE:
27//
[email protected]5fb6e15d2009-12-15 20:48:0328// class Controller : public SupportsWeakPtr<Controller> {
[email protected]3125d6462009-09-01 20:50:1729// public:
[email protected]5fb6e15d2009-12-15 20:48:0330// void SpawnWorker() { Worker::StartNew(AsWeakPtr()); }
[email protected]3125d6462009-09-01 20:50:1731// void WorkComplete(const Result& result) { ... }
32// };
33//
34// class Worker {
35// public:
36// static void StartNew(const WeakPtr<Controller>& controller) {
37// Worker* worker = new Worker(controller);
38// // Kick off asynchronous processing...
39// }
40// private:
41// Worker(const WeakPtr<Controller>& controller)
42// : controller_(controller) {}
43// void DidCompleteAsynchronousProcessing(const Result& result) {
44// if (controller_)
45// controller_->WorkComplete(result);
46// }
47// WeakPtr<Controller> controller_;
48// };
49//
50// Given the above classes, a consumer may allocate a Controller object, call
51// SpawnWorker several times, and then destroy the Controller object before all
52// of the workers have completed. Because the Worker class only holds a weak
53// pointer to the Controller, we don't have to worry about the Worker
54// dereferencing the Controller back pointer after the Controller has been
55// destroyed.
56//
[email protected]3125d6462009-09-01 20:50:1757
[email protected]3b63f8f42011-03-28 01:54:1558#ifndef BASE_MEMORY_WEAK_PTR_H_
59#define BASE_MEMORY_WEAK_PTR_H_
[email protected]32b76ef2010-07-26 23:08:2460#pragma once
[email protected]3125d6462009-09-01 20:50:1761
[email protected]0bea7252011-08-05 15:34:0062#include "base/base_export.h"
[email protected]3125d6462009-09-01 20:50:1763#include "base/logging.h"
[email protected]3b63f8f42011-03-28 01:54:1564#include "base/memory/ref_counted.h"
[email protected]05b1cd612011-04-11 20:47:2565#include "base/threading/thread_checker.h"
[email protected]3125d6462009-09-01 20:50:1766
67namespace base {
68
69namespace internal {
70// These classes are part of the WeakPtr implementation.
71// DO NOT USE THESE CLASSES DIRECTLY YOURSELF.
72
[email protected]0bea7252011-08-05 15:34:0073class BASE_EXPORT WeakReference {
[email protected]3125d6462009-09-01 20:50:1774 public:
[email protected]05b1cd612011-04-11 20:47:2575 // While Flag is bound to a specific thread, it may be deleted from another
76 // via base::WeakPtr::~WeakPtr().
77 class Flag : public RefCountedThreadSafe<Flag> {
[email protected]d52e97092009-09-17 00:31:0978 public:
[email protected]1edefc42011-08-26 17:32:2979 Flag();
[email protected]59326aac2009-09-25 23:34:3480
[email protected]6aacd8d2011-03-10 19:56:5381 void Invalidate();
82 bool IsValid() const;
[email protected]59326aac2009-09-25 23:34:3483
[email protected]05b1cd612011-04-11 20:47:2584 void DetachFromThread() { thread_checker_.DetachFromThread(); }
[email protected]8ff672512010-10-07 20:17:3385
[email protected]59326aac2009-09-25 23:34:3486 private:
[email protected]05b1cd612011-04-11 20:47:2587 friend class base::RefCountedThreadSafe<Flag>;
88
89 ~Flag();
90
91 ThreadChecker thread_checker_;
[email protected]1edefc42011-08-26 17:32:2992 bool is_valid_;
[email protected]3125d6462009-09-01 20:50:1793 };
94
[email protected]3a3d47472010-07-15 21:03:5495 WeakReference();
[email protected]1edefc42011-08-26 17:32:2996 explicit WeakReference(const Flag* flag);
[email protected]201366472010-07-16 17:22:4997 ~WeakReference();
[email protected]59326aac2009-09-25 23:34:3498
[email protected]3a3d47472010-07-15 21:03:5499 bool is_valid() const;
[email protected]59326aac2009-09-25 23:34:34100
101 private:
[email protected]1edefc42011-08-26 17:32:29102 scoped_refptr<const Flag> flag_;
[email protected]3125d6462009-09-01 20:50:17103};
104
[email protected]0bea7252011-08-05 15:34:00105class BASE_EXPORT WeakReferenceOwner {
[email protected]3125d6462009-09-01 20:50:17106 public:
[email protected]3a3d47472010-07-15 21:03:54107 WeakReferenceOwner();
108 ~WeakReferenceOwner();
[email protected]59326aac2009-09-25 23:34:34109
[email protected]3a3d47472010-07-15 21:03:54110 WeakReference GetRef() const;
[email protected]3125d6462009-09-01 20:50:17111
[email protected]59326aac2009-09-25 23:34:34112 bool HasRefs() const {
[email protected]1edefc42011-08-26 17:32:29113 return flag_.get() && !flag_->HasOneRef();
[email protected]59326aac2009-09-25 23:34:34114 }
115
[email protected]3a3d47472010-07-15 21:03:54116 void Invalidate();
[email protected]3125d6462009-09-01 20:50:17117
[email protected]8ff672512010-10-07 20:17:33118 // Indicates that this object will be used on another thread from now on.
119 void DetachFromThread() {
120 if (flag_) flag_->DetachFromThread();
121 }
122
[email protected]3125d6462009-09-01 20:50:17123 private:
[email protected]1edefc42011-08-26 17:32:29124 mutable scoped_refptr<WeakReference::Flag> flag_;
[email protected]3125d6462009-09-01 20:50:17125};
126
127// This class simplifies the implementation of WeakPtr's type conversion
128// constructor by avoiding the need for a public accessor for ref_. A
129// WeakPtr<T> cannot access the private members of WeakPtr<U>, so this
130// base class gives us a way to access ref_ in a protected fashion.
[email protected]0bea7252011-08-05 15:34:00131class BASE_EXPORT WeakPtrBase {
[email protected]3125d6462009-09-01 20:50:17132 public:
[email protected]3a3d47472010-07-15 21:03:54133 WeakPtrBase();
[email protected]201366472010-07-16 17:22:49134 ~WeakPtrBase();
[email protected]3125d6462009-09-01 20:50:17135
136 protected:
[email protected]3a3d47472010-07-15 21:03:54137 WeakPtrBase(const WeakReference& ref);
[email protected]3125d6462009-09-01 20:50:17138
139 WeakReference ref_;
140};
141
142} // namespace internal
143
144template <typename T> class SupportsWeakPtr;
145template <typename T> class WeakPtrFactory;
146
147// The WeakPtr class holds a weak reference to |T*|.
148//
149// This class is designed to be used like a normal pointer. You should always
150// null-test an object of this class before using it or invoking a method that
151// may result in the underlying object being destroyed.
152//
153// EXAMPLE:
154//
155// class Foo { ... };
156// WeakPtr<Foo> foo;
157// if (foo)
158// foo->method();
159//
160template <typename T>
161class WeakPtr : public internal::WeakPtrBase {
162 public:
163 WeakPtr() : ptr_(NULL) {
164 }
165
166 // Allow conversion from U to T provided U "is a" T.
167 template <typename U>
168 WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.get()) {
169 }
170
171 T* get() const { return ref_.is_valid() ? ptr_ : NULL; }
172 operator T*() const { return get(); }
173
174 T* operator*() const {
175 DCHECK(get() != NULL);
[email protected]7f18b7c42012-02-24 09:13:09176 return get();
[email protected]3125d6462009-09-01 20:50:17177 }
178 T* operator->() const {
179 DCHECK(get() != NULL);
180 return get();
181 }
182
[email protected]f103ab72009-09-02 17:10:59183 void reset() {
184 ref_ = internal::WeakReference();
185 ptr_ = NULL;
186 }
187
[email protected]3125d6462009-09-01 20:50:17188 private:
189 friend class SupportsWeakPtr<T>;
190 friend class WeakPtrFactory<T>;
191
192 WeakPtr(const internal::WeakReference& ref, T* ptr)
193 : WeakPtrBase(ref), ptr_(ptr) {
194 }
195
196 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its
197 // value is undefined (as opposed to NULL).
198 T* ptr_;
199};
200
201// A class may extend from SupportsWeakPtr to expose weak pointers to itself.
202// This is useful in cases where you want others to be able to get a weak
203// pointer to your class. It also has the property that you don't need to
204// initialize it from your constructor.
205template <class T>
206class SupportsWeakPtr {
207 public:
208 SupportsWeakPtr() {}
209
210 WeakPtr<T> AsWeakPtr() {
211 return WeakPtr<T>(weak_reference_owner_.GetRef(), static_cast<T*>(this));
212 }
213
[email protected]8ff672512010-10-07 20:17:33214 // Indicates that this object will be used on another thread from now on.
215 void DetachFromThread() {
216 weak_reference_owner_.DetachFromThread();
217 }
218
[email protected]3125d6462009-09-01 20:50:17219 private:
220 internal::WeakReferenceOwner weak_reference_owner_;
221 DISALLOW_COPY_AND_ASSIGN(SupportsWeakPtr);
222};
223
224// A class may alternatively be composed of a WeakPtrFactory and thereby
225// control how it exposes weak pointers to itself. This is helpful if you only
226// need weak pointers within the implementation of a class. This class is also
227// useful when working with primitive types. For example, you could have a
228// WeakPtrFactory<bool> that is used to pass around a weak reference to a bool.
229template <class T>
230class WeakPtrFactory {
231 public:
232 explicit WeakPtrFactory(T* ptr) : ptr_(ptr) {
233 }
234
235 WeakPtr<T> GetWeakPtr() {
236 return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_);
237 }
238
239 // Call this method to invalidate all existing weak pointers.
[email protected]59326aac2009-09-25 23:34:34240 void InvalidateWeakPtrs() {
241 weak_reference_owner_.Invalidate();
242 }
243
244 // Call this method to determine if any weak pointers exist.
245 bool HasWeakPtrs() const {
246 return weak_reference_owner_.HasRefs();
247 }
[email protected]3125d6462009-09-01 20:50:17248
[email protected]05b1cd612011-04-11 20:47:25249 // Indicates that this object will be used on another thread from now on.
250 void DetachFromThread() {
251 weak_reference_owner_.DetachFromThread();
252 }
253
[email protected]3125d6462009-09-01 20:50:17254 private:
255 internal::WeakReferenceOwner weak_reference_owner_;
256 T* ptr_;
257 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory);
258};
259
260} // namespace base
261
[email protected]3b63f8f42011-03-28 01:54:15262#endif // BASE_MEMORY_WEAK_PTR_H_