1// Copyright (c) 2011 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<Controller> { 20// public: 21// void SpawnWorker() { Worker::StartNew(AsWeakPtr()); } 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_MEMORY_WEAK_PTR_H_ 52#define BASE_MEMORY_WEAK_PTR_H_ 53#pragma once 54 55#include "base/base_api.h" 56#include "base/logging.h" 57#include "base/memory/ref_counted.h" 58#include "base/threading/thread_checker.h" 59 60namespace base { 61 62namespace internal { 63// These classes are part of the WeakPtr implementation. 64// DO NOT USE THESE CLASSES DIRECTLY YOURSELF. 65 66class BASE_API WeakReference { 67 public: 68 // While Flag is bound to a specific thread, it may be deleted from another 69 // via base::WeakPtr::~WeakPtr(). 70 class Flag : public RefCountedThreadSafe<Flag> { 71 public: 72 explicit Flag(Flag** handle); 73 74 void Invalidate(); 75 bool IsValid() const; 76 77 void DetachFromThread() { thread_checker_.DetachFromThread(); } 78 79 private: 80 friend class base::RefCountedThreadSafe<Flag>; 81 82 ~Flag(); 83 84 ThreadChecker thread_checker_; 85 Flag** handle_; 86 }; 87 88 WeakReference(); 89 WeakReference(Flag* flag); 90 ~WeakReference(); 91 92 bool is_valid() const; 93 94 private: 95 scoped_refptr<Flag> flag_; 96}; 97 98class BASE_API WeakReferenceOwner { 99 public: 100 WeakReferenceOwner(); 101 ~WeakReferenceOwner(); 102 103 WeakReference GetRef() const; 104 105 bool HasRefs() const { 106 return flag_ != NULL; 107 } 108 109 void Invalidate(); 110 111 // Indicates that this object will be used on another thread from now on. 112 void DetachFromThread() { 113 if (flag_) flag_->DetachFromThread(); 114 } 115 116 private: 117 mutable WeakReference::Flag* flag_; 118}; 119 120// This class simplifies the implementation of WeakPtr's type conversion 121// constructor by avoiding the need for a public accessor for ref_. A 122// WeakPtr<T> cannot access the private members of WeakPtr<U>, so this 123// base class gives us a way to access ref_ in a protected fashion. 124class BASE_API WeakPtrBase { 125 public: 126 WeakPtrBase(); 127 ~WeakPtrBase(); 128 129 protected: 130 WeakPtrBase(const WeakReference& ref); 131 132 WeakReference ref_; 133}; 134 135} // namespace internal 136 137template <typename T> class SupportsWeakPtr; 138template <typename T> class WeakPtrFactory; 139 140// The WeakPtr class holds a weak reference to |T*|. 141// 142// This class is designed to be used like a normal pointer. You should always 143// null-test an object of this class before using it or invoking a method that 144// may result in the underlying object being destroyed. 145// 146// EXAMPLE: 147// 148// class Foo { ... }; 149// WeakPtr<Foo> foo; 150// if (foo) 151// foo->method(); 152// 153template <typename T> 154class WeakPtr : public internal::WeakPtrBase { 155 public: 156 WeakPtr() : ptr_(NULL) { 157 } 158 159 // Allow conversion from U to T provided U "is a" T. 160 template <typename U> 161 WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.get()) { 162 } 163 164 T* get() const { return ref_.is_valid() ? ptr_ : NULL; } 165 operator T*() const { return get(); } 166 167 T* operator*() const { 168 DCHECK(get() != NULL); 169 return *get(); 170 } 171 T* operator->() const { 172 DCHECK(get() != NULL); 173 return get(); 174 } 175 176 void reset() { 177 ref_ = internal::WeakReference(); 178 ptr_ = NULL; 179 } 180 181 private: 182 friend class SupportsWeakPtr<T>; 183 friend class WeakPtrFactory<T>; 184 185 WeakPtr(const internal::WeakReference& ref, T* ptr) 186 : WeakPtrBase(ref), ptr_(ptr) { 187 } 188 189 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its 190 // value is undefined (as opposed to NULL). 191 T* ptr_; 192}; 193 194// A class may extend from SupportsWeakPtr to expose weak pointers to itself. 195// This is useful in cases where you want others to be able to get a weak 196// pointer to your class. It also has the property that you don't need to 197// initialize it from your constructor. 198template <class T> 199class SupportsWeakPtr { 200 public: 201 SupportsWeakPtr() {} 202 203 WeakPtr<T> AsWeakPtr() { 204 return WeakPtr<T>(weak_reference_owner_.GetRef(), static_cast<T*>(this)); 205 } 206 207 // Indicates that this object will be used on another thread from now on. 208 void DetachFromThread() { 209 weak_reference_owner_.DetachFromThread(); 210 } 211 212 private: 213 internal::WeakReferenceOwner weak_reference_owner_; 214 DISALLOW_COPY_AND_ASSIGN(SupportsWeakPtr); 215}; 216 217// A class may alternatively be composed of a WeakPtrFactory and thereby 218// control how it exposes weak pointers to itself. This is helpful if you only 219// need weak pointers within the implementation of a class. This class is also 220// useful when working with primitive types. For example, you could have a 221// WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. 222template <class T> 223class WeakPtrFactory { 224 public: 225 explicit WeakPtrFactory(T* ptr) : ptr_(ptr) { 226 } 227 228 WeakPtr<T> GetWeakPtr() { 229 return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_); 230 } 231 232 // Call this method to invalidate all existing weak pointers. 233 void InvalidateWeakPtrs() { 234 weak_reference_owner_.Invalidate(); 235 } 236 237 // Call this method to determine if any weak pointers exist. 238 bool HasWeakPtrs() const { 239 return weak_reference_owner_.HasRefs(); 240 } 241 242 // Indicates that this object will be used on another thread from now on. 243 void DetachFromThread() { 244 weak_reference_owner_.DetachFromThread(); 245 } 246 247 private: 248 internal::WeakReferenceOwner weak_reference_owner_; 249 T* ptr_; 250 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); 251}; 252 253} // namespace base 254 255#endif // BASE_MEMORY_WEAK_PTR_H_ 256