1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Weak pointers help in cases where you have many objects referring back to a 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// shared object and you wish for the lifetime of the shared object to not be 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// bound to the lifetime of the referrers. In other words, this is useful when 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// reference counting is not a good fit. 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A common alternative to weak pointers is to have the shared object hold a 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// list of all referrers, and then when the shared object is destroyed, it 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// calls a method on the referrers to tell them to drop their references. This 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// approach also requires the referrers to tell the shared object when they get 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// destroyed so that the shared object can remove the referrer from its list of 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// referrers. Such a solution works, but it is a bit complex. 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// EXAMPLE: 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// class Controller : public SupportsWeakPtr<Controller> { 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// public: 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// void SpawnWorker() { Worker::StartNew(AsWeakPtr()); } 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// void WorkComplete(const Result& result) { ... } 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// }; 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// class Worker { 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// public: 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static void StartNew(const WeakPtr<Controller>& controller) { 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Worker* worker = new Worker(controller); 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// // Kick off asynchronous processing... 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// } 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// private: 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Worker(const WeakPtr<Controller>& controller) 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// : controller_(controller) {} 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// void DidCompleteAsynchronousProcessing(const Result& result) { 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// if (controller_) 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// controller_->WorkComplete(result); 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// } 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// WeakPtr<Controller> controller_; 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// }; 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Given the above classes, a consumer may allocate a Controller object, call 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// SpawnWorker several times, and then destroy the Controller object before all 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// of the workers have completed. Because the Worker class only holds a weak 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// pointer to the Controller, we don't have to worry about the Worker 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// dereferencing the Controller back pointer after the Controller has been 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// destroyed. 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// WARNING: weak pointers are not threadsafe!!! You must only use a WeakPtr 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// instance on thread where it was created. 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifndef BASE_MEMORY_WEAK_PTR_H_ 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define BASE_MEMORY_WEAK_PTR_H_ 533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/base_api.h" 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h" 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/threading/thread_checker.h" 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace base { 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace internal { 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// These classes are part of the WeakPtr implementation. 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// DO NOT USE THESE CLASSES DIRECTLY YOURSELF. 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API WeakReference { 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // While Flag is bound to a specific thread, it may be deleted from another 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // via base::WeakPtr::~WeakPtr(). 70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen class Flag : public RefCountedThreadSafe<Flag> { 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen explicit Flag(Flag** handle); 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void Invalidate(); 75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool IsValid() const; 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void DetachFromThread() { thread_checker_.DetachFromThread(); } 78731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen friend class base::RefCountedThreadSafe<Flag>; 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ~Flag(); 83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ThreadChecker thread_checker_; 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Flag** handle_; 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WeakReference(); 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WeakReference(Flag* flag); 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~WeakReference(); 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool is_valid() const; 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<Flag> flag_; 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API WeakReferenceOwner { 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WeakReferenceOwner(); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~WeakReferenceOwner(); 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WeakReference GetRef() const; 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool HasRefs() const { 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return flag_ != NULL; 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Invalidate(); 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Indicates that this object will be used on another thread from now on. 112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void DetachFromThread() { 113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (flag_) flag_->DetachFromThread(); 114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mutable WeakReference::Flag* flag_; 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This class simplifies the implementation of WeakPtr's type conversion 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// constructor by avoiding the need for a public accessor for ref_. A 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// WeakPtr<T> cannot access the private members of WeakPtr<U>, so this 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// base class gives us a way to access ref_ in a protected fashion. 124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API WeakPtrBase { 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WeakPtrBase(); 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~WeakPtrBase(); 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WeakPtrBase(const WeakReference& ref); 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakReference ref_; 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace internal 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <typename T> class SupportsWeakPtr; 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <typename T> class WeakPtrFactory; 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The WeakPtr class holds a weak reference to |T*|. 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This class is designed to be used like a normal pointer. You should always 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// null-test an object of this class before using it or invoking a method that 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// may result in the underlying object being destroyed. 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// EXAMPLE: 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// class Foo { ... }; 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// WeakPtr<Foo> foo; 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// if (foo) 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// foo->method(); 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <typename T> 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass WeakPtr : public internal::WeakPtrBase { 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtr() : ptr_(NULL) { 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Allow conversion from U to T provided U "is a" T. 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott template <typename U> 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.get()) { 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* get() const { return ref_.is_valid() ? ptr_ : NULL; } 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott operator T*() const { return get(); } 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* operator*() const { 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(get() != NULL); 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return *get(); 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* operator->() const { 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(get() != NULL); 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return get(); 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void reset() { 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ref_ = internal::WeakReference(); 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ptr_ = NULL; 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott friend class SupportsWeakPtr<T>; 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott friend class WeakPtrFactory<T>; 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtr(const internal::WeakReference& ref, T* ptr) 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : WeakPtrBase(ref), ptr_(ptr) { 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This pointer is only valid when ref_.is_valid() is true. Otherwise, its 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // value is undefined (as opposed to NULL). 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* ptr_; 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A class may extend from SupportsWeakPtr to expose weak pointers to itself. 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This is useful in cases where you want others to be able to get a weak 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// pointer to your class. It also has the property that you don't need to 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// initialize it from your constructor. 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T> 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass SupportsWeakPtr { 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SupportsWeakPtr() {} 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtr<T> AsWeakPtr() { 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return WeakPtr<T>(weak_reference_owner_.GetRef(), static_cast<T*>(this)); 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 207731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Indicates that this object will be used on another thread from now on. 208731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void DetachFromThread() { 209731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick weak_reference_owner_.DetachFromThread(); 210731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 211731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott internal::WeakReferenceOwner weak_reference_owner_; 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(SupportsWeakPtr); 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A class may alternatively be composed of a WeakPtrFactory and thereby 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// control how it exposes weak pointers to itself. This is helpful if you only 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// need weak pointers within the implementation of a class. This class is also 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// useful when working with primitive types. For example, you could have a 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T> 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass WeakPtrFactory { 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit WeakPtrFactory(T* ptr) : ptr_(ptr) { 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtr<T> GetWeakPtr() { 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_); 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Call this method to invalidate all existing weak pointers. 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void InvalidateWeakPtrs() { 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott weak_reference_owner_.Invalidate(); 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Call this method to determine if any weak pointers exist. 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool HasWeakPtrs() const { 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return weak_reference_owner_.HasRefs(); 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Indicates that this object will be used on another thread from now on. 243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void DetachFromThread() { 244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen weak_reference_owner_.DetachFromThread(); 245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott internal::WeakReferenceOwner weak_reference_owner_; 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* ptr_; 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace base 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif // BASE_MEMORY_WEAK_PTR_H_ 256