LCOV - code coverage report
Current view: top level - toolkit/components/places - nsMaybeWeakPtr.h (source / functions) Hit Total Coverage
Test: output.info Lines: 22 49 44.9 %
Date: 2017-07-14 16:53:18 Functions: 11 30 36.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #ifndef nsMaybeWeakPtr_h_
       7             : #define nsMaybeWeakPtr_h_
       8             : 
       9             : #include "mozilla/Attributes.h"
      10             : #include "nsCOMPtr.h"
      11             : #include "nsWeakReference.h"
      12             : #include "nsTArray.h"
      13             : #include "nsCycleCollectionNoteChild.h"
      14             : 
      15             : // nsMaybeWeakPtr is a helper object to hold a strong-or-weak reference
      16             : // to the template class.  It's pretty minimal, but sufficient.
      17             : 
      18             : template<class T>
      19           4 : class nsMaybeWeakPtr
      20             : {
      21             : public:
      22           9 :   MOZ_IMPLICIT nsMaybeWeakPtr(nsISupports* aRef) : mPtr(aRef) {}
      23           0 :   MOZ_IMPLICIT nsMaybeWeakPtr(const nsCOMPtr<nsIWeakReference>& aRef) : mPtr(aRef) {}
      24             :   MOZ_IMPLICIT nsMaybeWeakPtr(const nsCOMPtr<T>& aRef) : mPtr(aRef) {}
      25             : 
      26           4 :   bool operator==(const nsMaybeWeakPtr<T> &other) const {
      27           4 :     return mPtr == other.mPtr;
      28             :   }
      29             : 
      30           0 :   nsISupports* GetRawValue() const { return mPtr.get(); }
      31             : 
      32             :   const nsCOMPtr<T> GetValue() const;
      33             : 
      34             : private:
      35             :   nsCOMPtr<nsISupports> mPtr;
      36             : };
      37             : 
      38             : // nsMaybeWeakPtrArray is an array of MaybeWeakPtr objects, that knows how to
      39             : // grab a weak reference to a given object if requested.  It only allows a
      40             : // given object to appear in the array once.
      41             : 
      42             : template<class T>
      43           2 : class nsMaybeWeakPtrArray : public nsTArray<nsMaybeWeakPtr<T>>
      44             : {
      45             :   typedef nsTArray<nsMaybeWeakPtr<T>> MaybeWeakArray;
      46             : 
      47             : public:
      48           5 :   nsresult AppendWeakElement(T* aElement, bool aOwnsWeak)
      49             :   {
      50          10 :     nsCOMPtr<nsISupports> ref;
      51           5 :     if (aOwnsWeak) {
      52           3 :       ref = do_GetWeakReference(aElement);
      53             :     } else {
      54           2 :       ref = aElement;
      55             :     }
      56             : 
      57           5 :     if (MaybeWeakArray::Contains(ref.get())) {
      58           0 :       return NS_ERROR_INVALID_ARG;
      59             :     }
      60           5 :     if (!MaybeWeakArray::AppendElement(ref)) {
      61           0 :       return NS_ERROR_OUT_OF_MEMORY;
      62             :     }
      63           5 :     return NS_OK;
      64             :   }
      65             : 
      66           0 :   nsresult RemoveWeakElement(T* aElement)
      67             :   {
      68           0 :     if (MaybeWeakArray::RemoveElement(aElement)) {
      69           0 :       return NS_OK;
      70             :     }
      71             : 
      72             :     // Don't use do_GetWeakReference; it should only be called if we know
      73             :     // the object supports weak references.
      74           0 :     nsCOMPtr<nsISupportsWeakReference> supWeakRef = do_QueryInterface(aElement);
      75           0 :     NS_ENSURE_TRUE(supWeakRef, NS_ERROR_INVALID_ARG);
      76             : 
      77           0 :     nsCOMPtr<nsIWeakReference> weakRef;
      78           0 :     nsresult rv = supWeakRef->GetWeakReference(getter_AddRefs(weakRef));
      79           0 :     NS_ENSURE_SUCCESS(rv, rv);
      80             : 
      81           0 :     if (MaybeWeakArray::RemoveElement(weakRef)) {
      82           0 :       return NS_OK;
      83             :     }
      84             : 
      85           0 :     return NS_ERROR_INVALID_ARG;
      86             :   }
      87             : };
      88             : 
      89             : template<class T>
      90             : const nsCOMPtr<T>
      91           9 : nsMaybeWeakPtr<T>::GetValue() const
      92             : {
      93           9 :   if (!mPtr) {
      94           0 :     return nullptr;
      95             :   }
      96             : 
      97             :   nsresult rv;
      98          18 :   nsCOMPtr<T> ref = do_QueryInterface(mPtr, &rv);
      99           9 :   if (NS_SUCCEEDED(rv)) {
     100           0 :     return ref;
     101             :   }
     102             : 
     103          18 :   nsCOMPtr<nsIWeakReference> weakRef = do_QueryInterface(mPtr);
     104           9 :   if (weakRef) {
     105           9 :     ref = do_QueryReferent(weakRef, &rv);
     106           9 :     if (NS_SUCCEEDED(rv)) {
     107           9 :       return ref;
     108             :     }
     109             :   }
     110             : 
     111           0 :   return nullptr;
     112             : }
     113             : 
     114             : template <typename T>
     115             : inline void
     116           0 : ImplCycleCollectionUnlink(nsMaybeWeakPtrArray<T>& aField)
     117             : {
     118           0 :   aField.Clear();
     119           0 : }
     120             : 
     121             : template <typename E>
     122             : inline void
     123           0 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
     124             :                             nsMaybeWeakPtrArray<E>& aField,
     125             :                             const char* aName,
     126             :                             uint32_t aFlags = 0)
     127             : {
     128           0 :   aFlags |= CycleCollectionEdgeNameArrayFlag;
     129           0 :   size_t length = aField.Length();
     130           0 :   for (size_t i = 0; i < length; ++i) {
     131           0 :     CycleCollectionNoteChild(aCallback, aField[i].GetRawValue(), aName, aFlags);
     132             :   }
     133           0 : }
     134             : 
     135             : // Call a method on each element in the array, but only if the element is
     136             : // non-null.
     137             : 
     138             : #define ENUMERATE_WEAKARRAY(array, type, method)                           \
     139             :   for (uint32_t array_idx = 0; array_idx < array.Length(); ++array_idx) {  \
     140             :     const nsCOMPtr<type> &e = array.ElementAt(array_idx).GetValue();       \
     141             :     if (e)                                                                 \
     142             :       e->method;                                                           \
     143             :   }
     144             : 
     145             : #endif

Generated by: LCOV version 1.13