LCOV - code coverage report
Current view: top level - xpcom/base - ClearOnShutdown.h (source / functions) Hit Total Coverage
Test: output.info Lines: 11 20 55.0 %
Date: 2017-07-14 16:53:18 Functions: 89 418 21.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef mozilla_ClearOnShutdown_h
       8             : #define mozilla_ClearOnShutdown_h
       9             : 
      10             : #include "mozilla/LinkedList.h"
      11             : #include "mozilla/StaticPtr.h"
      12             : #include "mozilla/Array.h"
      13             : #include "MainThreadUtils.h"
      14             : 
      15             : /*
      16             :  * This header exports one public method in the mozilla namespace:
      17             :  *
      18             :  *   template<class SmartPtr>
      19             :  *   void ClearOnShutdown(SmartPtr *aPtr, aPhase=ShutdownPhase::ShutdownFinal)
      20             :  *
      21             :  * This function takes a pointer to a smart pointer and nulls the smart pointer
      22             :  * on shutdown (and a particular phase of shutdown as needed).  If a phase
      23             :  * is specified, the ptr will be cleared at the start of that phase.  Also,
      24             :  * if a phase has already occurred when ClearOnShutdown() is called it will
      25             :  * cause a MOZ_ASSERT.  In case a phase is not explicitly cleared we will
      26             :  * clear it on the next phase that occurs.
      27             :  *
      28             :  * This is useful if you have a global smart pointer object which you don't
      29             :  * want to "leak" on shutdown.
      30             :  *
      31             :  * Although ClearOnShutdown will work with any smart pointer (i.e., nsCOMPtr,
      32             :  * nsRefPtr, nsAutoPtr, StaticRefPtr, and StaticAutoPtr), you probably want to
      33             :  * use it only with StaticRefPtr and StaticAutoPtr.  There is no way to undo a
      34             :  * call to ClearOnShutdown, so you can call it only on smart pointers which you
      35             :  * know will live until the program shuts down.  In practice, these are likely
      36             :  * global variables, which should be Static{Ref,Auto}Ptr.
      37             :  *
      38             :  * ClearOnShutdown is currently main-thread only because we don't want to
      39             :  * accidentally free an object from a different thread than the one it was
      40             :  * created on.
      41             :  */
      42             : 
      43             : namespace mozilla {
      44             : 
      45             : // Must be contiguous starting at 0
      46             : enum class ShutdownPhase {
      47             :   NotInShutdown = 0,
      48             :   WillShutdown,
      49             :   Shutdown,
      50             :   ShutdownThreads,
      51             :   ShutdownLoaders,
      52             :   ShutdownFinal,
      53             :   ShutdownPhase_Length, // never pass this value
      54             :   First = WillShutdown, // for iteration
      55             :   Last = ShutdownFinal
      56             : };
      57             : 
      58             : namespace ClearOnShutdown_Internal {
      59             : 
      60          99 : class ShutdownObserver : public LinkedListElement<ShutdownObserver>
      61             : {
      62             : public:
      63             :   virtual void Shutdown() = 0;
      64           0 :   virtual ~ShutdownObserver()
      65           0 :   {
      66           0 :   }
      67             : };
      68             : 
      69             : template<class SmartPtr>
      70           0 : class PointerClearer : public ShutdownObserver
      71             : {
      72             : public:
      73          99 :   explicit PointerClearer(SmartPtr* aPtr)
      74          99 :     : mPtr(aPtr)
      75             :   {
      76          99 :   }
      77             : 
      78           0 :   virtual void Shutdown() override
      79             :   {
      80           0 :     if (mPtr) {
      81           0 :       *mPtr = nullptr;
      82             :     }
      83           0 :   }
      84             : 
      85             : private:
      86             :   SmartPtr* mPtr;
      87             : };
      88             : 
      89             : typedef LinkedList<ShutdownObserver> ShutdownList;
      90             : extern Array<StaticAutoPtr<ShutdownList>,
      91             :              static_cast<size_t>(ShutdownPhase::ShutdownPhase_Length)> sShutdownObservers;
      92             : extern ShutdownPhase sCurrentShutdownPhase;
      93             : 
      94             : } // namespace ClearOnShutdown_Internal
      95             : 
      96             : template<class SmartPtr>
      97             : inline void
      98          99 : ClearOnShutdown(SmartPtr* aPtr, ShutdownPhase aPhase = ShutdownPhase::ShutdownFinal)
      99             : {
     100             :   using namespace ClearOnShutdown_Internal;
     101             : 
     102          99 :   MOZ_ASSERT(NS_IsMainThread());
     103          99 :   MOZ_ASSERT(aPhase != ShutdownPhase::ShutdownPhase_Length);
     104             : 
     105             :   // Adding a ClearOnShutdown for a "past" phase is an error.
     106          99 :   if (!(static_cast<size_t>(sCurrentShutdownPhase) < static_cast<size_t>(aPhase))) {
     107           0 :     MOZ_ASSERT(false, "ClearOnShutdown for phase that already was cleared");
     108             :     *aPtr = nullptr;
     109             :     return;
     110             :   }
     111             : 
     112          99 :   if (!(sShutdownObservers[static_cast<size_t>(aPhase)])) {
     113           4 :     sShutdownObservers[static_cast<size_t>(aPhase)] = new ShutdownList();
     114             :   }
     115          99 :   sShutdownObservers[static_cast<size_t>(aPhase)]->insertBack(new PointerClearer<SmartPtr>(aPtr));
     116             : }
     117             : 
     118             : // Called when XPCOM is shutting down, after all shutdown notifications have
     119             : // been sent and after all threads' event loops have been purged.
     120             : void KillClearOnShutdown(ShutdownPhase aPhase);
     121             : 
     122             : } // namespace mozilla
     123             : 
     124             : #endif

Generated by: LCOV version 1.13