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/. */
7 #ifndef mozilla_ClearOnShutdown_h
8 #define mozilla_ClearOnShutdown_h
10 #include "mozilla/LinkedList.h"
11 #include "mozilla/StaticPtr.h"
12 #include "MainThreadUtils.h"
15 * This header exports one public method in the mozilla namespace:
17 * template<class SmartPtr>
18 * void ClearOnShutdown(SmartPtr *aPtr)
20 * This function takes a pointer to a smart pointer and nulls the smart pointer
23 * This is useful if you have a global smart pointer object which you don't
24 * want to "leak" on shutdown.
26 * Although ClearOnShutdown will work with any smart pointer (i.e., nsCOMPtr,
27 * nsRefPtr, nsAutoPtr, StaticRefPtr, and StaticAutoPtr), you probably want to
28 * use it only with StaticRefPtr and StaticAutoPtr. There is no way to undo a
29 * call to ClearOnShutdown, so you can call it only on smart pointers which you
30 * know will live until the program shuts down. In practice, these are likely
31 * global variables, which should be Static{Ref,Auto}Ptr.
33 * ClearOnShutdown is currently main-thread only because we don't want to
34 * accidentally free an object from a different thread than the one it was
39 namespace ClearOnShutdown_Internal
{
41 class ShutdownObserver
: public LinkedListElement
<ShutdownObserver
>
44 virtual void Shutdown() = 0;
45 virtual ~ShutdownObserver()
50 template<class SmartPtr
>
51 class PointerClearer
: public ShutdownObserver
54 explicit PointerClearer(SmartPtr
* aPtr
)
59 virtual void Shutdown()
70 extern bool sHasShutDown
;
71 extern StaticAutoPtr
<LinkedList
<ShutdownObserver
>> sShutdownObservers
;
73 } // namespace ClearOnShutdown_Internal
75 template<class SmartPtr
>
77 ClearOnShutdown(SmartPtr
* aPtr
)
79 using namespace ClearOnShutdown_Internal
;
81 MOZ_ASSERT(NS_IsMainThread());
82 MOZ_ASSERT(!sHasShutDown
);
84 if (!sShutdownObservers
) {
85 sShutdownObservers
= new LinkedList
<ShutdownObserver
>();
87 sShutdownObservers
->insertBack(new PointerClearer
<SmartPtr
>(aPtr
));
90 // Called when XPCOM is shutting down, after all shutdown notifications have
91 // been sent and after all threads' event loops have been purged.
95 using namespace ClearOnShutdown_Internal
;
97 MOZ_ASSERT(NS_IsMainThread());
99 if (sShutdownObservers
) {
100 while (ShutdownObserver
* observer
= sShutdownObservers
->popFirst()) {
101 observer
->Shutdown();
106 sShutdownObservers
= nullptr;
110 } // namespace mozilla