weak_ptr.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Weak pointers help in cases where you have many objects referring back to a
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// shared object and you wish for the lifetime of the shared object to not be
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bound to the lifetime of the referrers.  In other words, this is useful when
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reference counting is not a good fit.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A common alternative to weak pointers is to have the shared object hold a
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// list of all referrers, and then when the shared object is destroyed, it
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// calls a method on the referrers to tell them to drop their references.  This
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// approach also requires the referrers to tell the shared object when they get
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroyed so that the shared object can remove the referrer from its list of
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// referrers.  Such a solution works, but it is a bit complex.
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// EXAMPLE:
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  class Controller : public SupportsWeakPtr<Controller> {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   public:
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    void SpawnWorker() { Worker::StartNew(AsWeakPtr()); }
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    void WorkComplete(const Result& result) { ... }
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  };
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  class Worker {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   public:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    static void StartNew(const WeakPtr<Controller>& controller) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      Worker* worker = new Worker(controller);
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      // Kick off asynchronous processing...
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    }
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   private:
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    Worker(const WeakPtr<Controller>& controller)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//        : controller_(controller) {}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    void DidCompleteAsynchronousProcessing(const Result& result) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      if (controller_)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//        controller_->WorkComplete(result);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    }
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    WeakPtr<Controller> controller_;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  };
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Given the above classes, a consumer may allocate a Controller object, call
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SpawnWorker several times, and then destroy the Controller object before all
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the workers have completed.  Because the Worker class only holds a weak
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pointer to the Controller, we don't have to worry about the Worker
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// dereferencing the Controller back pointer after the Controller has been
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroyed.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------------------ Thread-safety notes ------------------------
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When you get a WeakPtr (from a WeakPtrFactory or SupportsWeakPtr), if it's
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the only one pointing to the object, the object become bound to the
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// current thread, as well as this WeakPtr and all later ones get created.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// You may only dereference the WeakPtr on the thread it binds to. However, it
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is safe to destroy the WeakPtr object on another thread. Because of this,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// querying WeakPtrFactory's HasWeakPtrs() method can be racy.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On the other hand, the object that supports WeakPtr (extends SupportsWeakPtr)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can only be deleted from the thread it binds to, until all WeakPtrs are
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// deleted.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Calling SupportsWeakPtr::DetachFromThread() can work around the limitations
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// above and cancel the thread binding of the object and all WeakPtrs pointing
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to it, but it's not recommended and unsafe.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WeakPtrs may be copy-constructed or assigned on threads other than the thread
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// they are bound to. This does not change the thread binding. So these WeakPtrs
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// may only be dereferenced on the thread that the original WeakPtr was bound
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_MEMORY_WEAK_PTR_H_
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_MEMORY_WEAK_PTR_H_
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_export.h"
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/template_util.h"
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_checker.h"
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> class SupportsWeakPtr;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> class WeakPtr;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These classes are part of the WeakPtr implementation.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DO NOT USE THESE CLASSES DIRECTLY YOURSELF.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT WeakReference {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // While Flag is bound to a specific thread, it may be deleted from another
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // via base::WeakPtr::~WeakPtr().
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Flag : public RefCountedThreadSafe<Flag> {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Flag();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void Invalidate();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool IsValid() const;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void DetachFromThread() { thread_checker_.DetachFromThread(); }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    friend class base::RefCountedThreadSafe<Flag>;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~Flag();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ThreadChecker thread_checker_;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_valid_;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WeakReference();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit WeakReference(const Flag* flag);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~WeakReference();
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_valid() const;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<const Flag> flag_;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT WeakReferenceOwner {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WeakReferenceOwner();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~WeakReferenceOwner();
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WeakReference GetRef() const;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool HasRefs() const {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return flag_.get() && !flag_->HasOneRef();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Invalidate();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicates that this object will be used on another thread from now on.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DetachFromThread() {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (flag_) flag_->DetachFromThread();
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mutable scoped_refptr<WeakReference::Flag> flag_;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class simplifies the implementation of WeakPtr's type conversion
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// constructor by avoiding the need for a public accessor for ref_.  A
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WeakPtr<T> cannot access the private members of WeakPtr<U>, so this
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// base class gives us a way to access ref_ in a protected fashion.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT WeakPtrBase {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WeakPtrBase();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~WeakPtrBase();
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit WeakPtrBase(const WeakReference& ref);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WeakReference ref_;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class provides a common implementation of common functions that would
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// otherwise get instantiated separately for each distinct instantiation of
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SupportsWeakPtr<>.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SupportsWeakPtrBase {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A safe static downcast of a WeakPtr<Base> to WeakPtr<Derived>. This
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // conversion will only compile if there is exists a Base which inherits
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from SupportsWeakPtr<Base>. See base::AsWeakPtr() below for a helper
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // function that makes calling this easier.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename Derived>
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static WeakPtr<Derived> StaticAsWeakPtr(Derived* t) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        is_convertible<Derived, internal::SupportsWeakPtrBase&> convertible;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    COMPILE_ASSERT(convertible::value,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   AsWeakPtr_argument_inherits_from_SupportsWeakPtr);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return AsWeakPtrImpl<Derived>(t, *t);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This template function uses type inference to find a Base of Derived
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which is an instance of SupportsWeakPtr<Base>. We can then safely
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // static_cast the Base* to a Derived*.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename Derived, typename Base>
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static WeakPtr<Derived> AsWeakPtrImpl(
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Derived* t, const SupportsWeakPtr<Base>&) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WeakPtr<Base> ptr = t->Base::AsWeakPtr();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WeakPtr<Derived>(ptr.ref_, static_cast<Derived*>(ptr.ptr_));
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> class WeakPtrFactory;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The WeakPtr class holds a weak reference to |T*|.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class is designed to be used like a normal pointer.  You should always
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// null-test an object of this class before using it or invoking a method that
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// may result in the underlying object being destroyed.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// EXAMPLE:
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   class Foo { ... };
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   WeakPtr<Foo> foo;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   if (foo)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     foo->method();
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T>
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WeakPtr : public internal::WeakPtrBase {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WeakPtr() : ptr_(NULL) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allow conversion from U to T provided U "is a" T.
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename U>
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.get()) {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T* get() const { return ref_.is_valid() ? ptr_ : NULL; }
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  operator T*() const { return get(); }
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T& operator*() const {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(get() != NULL);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return *get();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T* operator->() const {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(get() != NULL);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return get();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void reset() {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ref_ = internal::WeakReference();
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr_ = NULL;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class internal::SupportsWeakPtrBase;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class SupportsWeakPtr<T>;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class WeakPtrFactory<T>;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WeakPtr(const internal::WeakReference& ref, T* ptr)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : WeakPtrBase(ref),
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ptr_(ptr) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This pointer is only valid when ref_.is_valid() is true.  Otherwise, its
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // value is undefined (as opposed to NULL).
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T* ptr_;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A class may extend from SupportsWeakPtr to expose weak pointers to itself.
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is useful in cases where you want others to be able to get a weak
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pointer to your class.  It also has the property that you don't need to
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// initialize it from your constructor.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T>
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SupportsWeakPtr : public internal::SupportsWeakPtrBase {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SupportsWeakPtr() {}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WeakPtr<T> AsWeakPtr() {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WeakPtr<T>(weak_reference_owner_.GetRef(), static_cast<T*>(this));
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicates that this object will be used on another thread from now on.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DetachFromThread() {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    weak_reference_owner_.DetachFromThread();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~SupportsWeakPtr() {}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::WeakReferenceOwner weak_reference_owner_;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SupportsWeakPtr);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper function that uses type deduction to safely return a WeakPtr<Derived>
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// when Derived doesn't directly extend SupportsWeakPtr<Derived>, instead it
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// extends a Base that extends SupportsWeakPtr<Base>.
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// EXAMPLE:
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   class Base : public base::SupportsWeakPtr<Producer> {};
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   class Derived : public Base {};
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   Derived derived;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   base::WeakPtr<Derived> ptr = base::AsWeakPtr(&derived);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that the following doesn't work (invalid type conversion) since
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Derived::AsWeakPtr() is WeakPtr<Base> SupportsWeakPtr<Base>::AsWeakPtr(),
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and there's no way to safely cast WeakPtr<Base> to WeakPtr<Derived> at
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the caller.
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   base::WeakPtr<Derived> ptr = derived.AsWeakPtr();  // Fails.
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Derived>
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WeakPtr<Derived> AsWeakPtr(Derived* t) {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A class may alternatively be composed of a WeakPtrFactory and thereby
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// control how it exposes weak pointers to itself.  This is helpful if you only
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// need weak pointers within the implementation of a class.  This class is also
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// useful when working with primitive types.  For example, you could have a
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WeakPtrFactory<bool> that is used to pass around a weak reference to a bool.
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T>
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WeakPtrFactory {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit WeakPtrFactory(T* ptr) : ptr_(ptr) {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~WeakPtrFactory() {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ptr_ = NULL;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WeakPtr<T> GetWeakPtr() {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(ptr_);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call this method to invalidate all existing weak pointers.
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InvalidateWeakPtrs() {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(ptr_);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    weak_reference_owner_.Invalidate();
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call this method to determine if any weak pointers exist.
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool HasWeakPtrs() const {
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(ptr_);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return weak_reference_owner_.HasRefs();
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicates that this object will be used on another thread from now on.
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DetachFromThread() {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(ptr_);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    weak_reference_owner_.DetachFromThread();
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::WeakReferenceOwner weak_reference_owner_;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T* ptr_;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_MEMORY_WEAK_PTR_H_
344