LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/base - weak_ptr.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 22 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #ifndef WEBRTC_BASE_WEAK_PTR_H_
      12             : #define WEBRTC_BASE_WEAK_PTR_H_
      13             : 
      14             : #include <memory>
      15             : 
      16             : #include <utility>
      17             : 
      18             : #include "webrtc/base/refcount.h"
      19             : #include "webrtc/base/scoped_ref_ptr.h"
      20             : #include "webrtc/base/sequenced_task_checker.h"
      21             : 
      22             : // The implementation is borrowed from chromium except that it does not
      23             : // implement SupportsWeakPtr.
      24             : 
      25             : // Weak pointers are pointers to an object that do not affect its lifetime,
      26             : // and which may be invalidated (i.e. reset to nullptr) by the object, or its
      27             : // owner, at any time, most commonly when the object is about to be deleted.
      28             : 
      29             : // Weak pointers are useful when an object needs to be accessed safely by one
      30             : // or more objects other than its owner, and those callers can cope with the
      31             : // object vanishing and e.g. tasks posted to it being silently dropped.
      32             : // Reference-counting such an object would complicate the ownership graph and
      33             : // make it harder to reason about the object's lifetime.
      34             : 
      35             : // EXAMPLE:
      36             : //
      37             : //  class Controller {
      38             : //   public:
      39             : //    Controller() : weak_factory_(this) {}
      40             : //    void SpawnWorker() { Worker::StartNew(weak_factory_.GetWeakPtr()); }
      41             : //    void WorkComplete(const Result& result) { ... }
      42             : //   private:
      43             : //    // Member variables should appear before the WeakPtrFactory, to ensure
      44             : //    // that any WeakPtrs to Controller are invalidated before its members
      45             : //    // variable's destructors are executed, rendering them invalid.
      46             : //    WeakPtrFactory<Controller> weak_factory_;
      47             : //  };
      48             : //
      49             : //  class Worker {
      50             : //   public:
      51             : //    static void StartNew(const WeakPtr<Controller>& controller) {
      52             : //      Worker* worker = new Worker(controller);
      53             : //      // Kick off asynchronous processing...
      54             : //    }
      55             : //   private:
      56             : //    Worker(const WeakPtr<Controller>& controller)
      57             : //        : controller_(controller) {}
      58             : //    void DidCompleteAsynchronousProcessing(const Result& result) {
      59             : //      if (controller_)
      60             : //        controller_->WorkComplete(result);
      61             : //    }
      62             : //    WeakPtr<Controller> controller_;
      63             : //  };
      64             : //
      65             : // With this implementation a caller may use SpawnWorker() to dispatch multiple
      66             : // Workers and subsequently delete the Controller, without waiting for all
      67             : // Workers to have completed.
      68             : 
      69             : // ------------------------- IMPORTANT: Thread-safety -------------------------
      70             : 
      71             : // Weak pointers may be passed safely between threads, but must always be
      72             : // dereferenced and invalidated on the same TaskQueue or thread, otherwise
      73             : // checking the pointer would be racey.
      74             : //
      75             : // To ensure correct use, the first time a WeakPtr issued by a WeakPtrFactory
      76             : // is dereferenced, the factory and its WeakPtrs become bound to the calling
      77             : // TaskQueue/thread, and cannot be dereferenced or
      78             : // invalidated on any other TaskQueue/thread. Bound WeakPtrs can still be handed
      79             : // off to other TaskQueues, e.g. to use to post tasks back to object on the
      80             : // bound sequence.
      81             : //
      82             : // Thus, at least one WeakPtr object must exist and have been dereferenced on
      83             : // the correct thread to enforce that other WeakPtr objects will enforce they
      84             : // are used on the desired thread.
      85             : 
      86             : namespace rtc {
      87             : 
      88             : namespace internal {
      89             : 
      90           0 : class WeakReference {
      91             :  public:
      92             :   // Although Flag is bound to a specific sequence, it may be
      93             :   // deleted from another via base::WeakPtr::~WeakPtr().
      94             :   class Flag : public RefCountInterface {
      95             :    public:
      96             :     Flag();
      97             : 
      98             :     void Invalidate();
      99             :     bool IsValid() const;
     100             : 
     101             :    private:
     102             :     friend class RefCountedObject<Flag>;
     103             : 
     104             :     ~Flag() override;
     105             : 
     106             :     SequencedTaskChecker checker_;
     107             :     bool is_valid_;
     108             :   };
     109             : 
     110             :   WeakReference();
     111             :   explicit WeakReference(const Flag* flag);
     112             :   ~WeakReference();
     113             : 
     114             :   WeakReference(WeakReference&& other);
     115             :   WeakReference(const WeakReference& other);
     116             :   WeakReference& operator=(WeakReference&& other) = default;
     117             :   WeakReference& operator=(const WeakReference& other) = default;
     118             : 
     119             :   bool is_valid() const;
     120             : 
     121             :  private:
     122             :   scoped_refptr<const Flag> flag_;
     123             : };
     124             : 
     125             : class WeakReferenceOwner {
     126             :  public:
     127             :   WeakReferenceOwner();
     128             :   ~WeakReferenceOwner();
     129             : 
     130             :   WeakReference GetRef() const;
     131             : 
     132           0 :   bool HasRefs() const { return flag_.get() && !flag_->HasOneRef(); }
     133             : 
     134             :   void Invalidate();
     135             : 
     136             :  private:
     137             :   SequencedTaskChecker checker_;
     138             :   mutable scoped_refptr<RefCountedObject<WeakReference::Flag>> flag_;
     139             : };
     140             : 
     141             : // This class simplifies the implementation of WeakPtr's type conversion
     142             : // constructor by avoiding the need for a public accessor for ref_.  A
     143             : // WeakPtr<T> cannot access the private members of WeakPtr<U>, so this
     144             : // base class gives us a way to access ref_ in a protected fashion.
     145           0 : class WeakPtrBase {
     146             :  public:
     147             :   WeakPtrBase();
     148             :   ~WeakPtrBase();
     149             : 
     150           0 :   WeakPtrBase(const WeakPtrBase& other) = default;
     151             :   WeakPtrBase(WeakPtrBase&& other) = default;
     152             :   WeakPtrBase& operator=(const WeakPtrBase& other) = default;
     153             :   WeakPtrBase& operator=(WeakPtrBase&& other) = default;
     154             : 
     155             :  protected:
     156             :   explicit WeakPtrBase(const WeakReference& ref);
     157             : 
     158             :   WeakReference ref_;
     159             : };
     160             : 
     161             : }  // namespace internal
     162             : 
     163             : template <typename T>
     164             : class WeakPtrFactory;
     165             : 
     166             : template <typename T>
     167           0 : class WeakPtr : public internal::WeakPtrBase {
     168             :  public:
     169           0 :   WeakPtr() : ptr_(nullptr) {}
     170             : 
     171             :   // Allow conversion from U to T provided U "is a" T. Note that this
     172             :   // is separate from the (implicit) copy and move constructors.
     173             :   template <typename U>
     174             :   WeakPtr(const WeakPtr<U>& other)
     175             :       : internal::WeakPtrBase(other), ptr_(other.ptr_) {}
     176             :   template <typename U>
     177             :   WeakPtr(WeakPtr<U>&& other)
     178             :       : internal::WeakPtrBase(std::move(other)), ptr_(other.ptr_) {}
     179             : 
     180           0 :   T* get() const { return ref_.is_valid() ? ptr_ : nullptr; }
     181             : 
     182             :   T& operator*() const {
     183             :     RTC_DCHECK(get() != nullptr);
     184             :     return *get();
     185             :   }
     186           0 :   T* operator->() const {
     187           0 :     RTC_DCHECK(get() != nullptr);
     188           0 :     return get();
     189             :   }
     190             : 
     191           0 :   void reset() {
     192           0 :     ref_ = internal::WeakReference();
     193           0 :     ptr_ = nullptr;
     194           0 :   }
     195             : 
     196             :   // Allow conditionals to test validity, e.g. if (weak_ptr) {...};
     197           0 :   explicit operator bool() const { return get() != nullptr; }
     198             : 
     199             :  private:
     200             :   template <typename U>
     201             :   friend class WeakPtr;
     202             :   friend class WeakPtrFactory<T>;
     203             : 
     204           0 :   WeakPtr(const internal::WeakReference& ref, T* ptr)
     205           0 :       : internal::WeakPtrBase(ref), ptr_(ptr) {}
     206             : 
     207             :   // This pointer is only valid when ref_.is_valid() is true.  Otherwise, its
     208             :   // value is undefined (as opposed to nullptr).
     209             :   T* ptr_;
     210             : };
     211             : 
     212             : // Allow callers to compare WeakPtrs against nullptr to test validity.
     213             : template <class T>
     214             : bool operator!=(const WeakPtr<T>& weak_ptr, std::nullptr_t) {
     215             :   return !(weak_ptr == nullptr);
     216             : }
     217             : template <class T>
     218             : bool operator!=(std::nullptr_t, const WeakPtr<T>& weak_ptr) {
     219             :   return weak_ptr != nullptr;
     220             : }
     221             : template <class T>
     222             : bool operator==(const WeakPtr<T>& weak_ptr, std::nullptr_t) {
     223             :   return weak_ptr.get() == nullptr;
     224             : }
     225             : template <class T>
     226             : bool operator==(std::nullptr_t, const WeakPtr<T>& weak_ptr) {
     227             :   return weak_ptr == nullptr;
     228             : }
     229             : 
     230             : // A class may be composed of a WeakPtrFactory and thereby
     231             : // control how it exposes weak pointers to itself.  This is helpful if you only
     232             : // need weak pointers within the implementation of a class.  This class is also
     233             : // useful when working with primitive types.  For example, you could have a
     234             : // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool.
     235             : 
     236             : // Note that GetWeakPtr must be called on one and only one TaskQueue or thread
     237             : // and the WeakPtr must only be dereferenced and invalidated on that same
     238             : // TaskQueue/thread. A WeakPtr instance can be copied and posted to other
     239             : // sequences though as long as it is not dereferenced (WeakPtr<T>::get()).
     240             : template <class T>
     241             : class WeakPtrFactory {
     242             :  public:
     243           0 :   explicit WeakPtrFactory(T* ptr) : ptr_(ptr) {}
     244             : 
     245           0 :   ~WeakPtrFactory() { ptr_ = nullptr; }
     246             : 
     247           0 :   WeakPtr<T> GetWeakPtr() {
     248           0 :     RTC_DCHECK(ptr_);
     249           0 :     return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_);
     250             :   }
     251             : 
     252             :   // Call this method to invalidate all existing weak pointers.
     253             :   void InvalidateWeakPtrs() {
     254             :     RTC_DCHECK(ptr_);
     255             :     weak_reference_owner_.Invalidate();
     256             :   }
     257             : 
     258             :   // Call this method to determine if any weak pointers exist.
     259             :   bool HasWeakPtrs() const {
     260             :     RTC_DCHECK(ptr_);
     261             :     return weak_reference_owner_.HasRefs();
     262             :   }
     263             : 
     264             :  private:
     265             :   internal::WeakReferenceOwner weak_reference_owner_;
     266             :   T* ptr_;
     267             :   RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory);
     268             : };
     269             : 
     270             : }  // namespace rtc
     271             : 
     272             : #endif  // WEBRTC_BASE_WEAK_PTR_H_

Generated by: LCOV version 1.13