Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
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 #if !defined(MediaShutdownManager_h_)
8 #define MediaShutdownManager_h_
10 #include "nsIObserver.h"
11 #include "mozilla/Monitor.h"
12 #include "mozilla/RefPtr.h"
13 #include "mozilla/StaticPtr.h"
14 #include "nsIThread.h"
15 #include "nsCOMPtr.h"
16 #include "nsTHashtable.h"
17 #include "nsHashKeys.h"
19 namespace mozilla {
21 class MediaDecoder;
22 class StateMachineThread;
24 // The MediaShutdownManager manages shutting down the MediaDecoder
25 // infrastructure in response to an xpcom-shutdown notification. This happens
26 // when Gecko is shutting down in the middle of operation. This is tricky, as
27 // there are a number of moving parts that must be shutdown in a particular
28 // order. Additionally the xpcom-shutdown observer *must* block until all
29 // threads are shutdown, which is tricky since we have a number of threads
30 // here and their shutdown is asynchronous. We can't have each element of
31 // our pipeline listening for xpcom-shutdown, as if each observer blocks
32 // waiting for its threads to shutdown it will block other xpcom-shutdown
33 // notifications from firing, and shutdown of one part of the media pipeline
34 // (say the State Machine thread) may depend another part to be shutdown
35 // first (the MediaDecoder threads). The MediaShutdownManager encapsulates
36 // all these dependencies, and provides a single xpcom-shutdown listener
37 // for the MediaDecoder infrastructure, to ensure that no shutdown order
38 // dependencies leak out of the MediaDecoder stack. The MediaShutdownManager
39 // is a singleton.
40 //
41 // The MediaShutdownManager ensures that the MediaDecoder stack is shutdown
42 // before returning from its xpcom-shutdown observer by keeping track of all
43 // the active MediaDecoders, and upon xpcom-shutdown calling Shutdown() on
44 // every MediaDecoder and then spinning the main thread event loop until all
45 // SharedThreadPools have shutdown. Once the SharedThreadPools are shutdown,
46 // all the state machines and their threads have been shutdown, the
47 // xpcom-shutdown observer returns.
48 //
49 // Note that calling the Unregister() functions may result in the singleton
50 // being deleted, so don't store references to the singleton, always use the
51 // singleton by derefing the referenced returned by
52 // MediaShutdownManager::Instance(), which ensures that the singleton is
53 // created when needed.
54 // i.e. like this:
55 // MediaShutdownManager::Instance()::Unregister(someDecoder);
56 // MediaShutdownManager::Instance()::Register(someOtherDecoder);
57 // Not like this:
58 // MediaShutdownManager& instance = MediaShutdownManager::Instance();
59 // instance.Unregister(someDecoder); // Warning! May delete instance!
60 // instance.Register(someOtherDecoder); // BAD! instance may be dangling!
61 class MediaShutdownManager : public nsIObserver {
62 public:
63 NS_DECL_ISUPPORTS
64 NS_DECL_NSIOBSERVER
66 // The MediaShutdownManager is a singleton, access its instance with
67 // this accessor.
68 static MediaShutdownManager& Instance();
70 // Notifies the MediaShutdownManager that it needs to track the shutdown
71 // of this MediaDecoder.
72 void Register(MediaDecoder* aDecoder);
74 // Notifies the MediaShutdownManager that a MediaDecoder that it was
75 // tracking has shutdown, and it no longer needs to be shutdown in the
76 // xpcom-shutdown listener.
77 void Unregister(MediaDecoder* aDecoder);
79 private:
81 MediaShutdownManager();
82 virtual ~MediaShutdownManager();
84 void Shutdown();
86 // Ensures we have a shutdown listener if we need one, and removes the
87 // listener and destroys the singleton if we don't.
88 void EnsureCorrectShutdownObserverState();
90 static StaticRefPtr<MediaShutdownManager> sInstance;
92 // References to the MediaDecoder. The decoders unregister themselves
93 // in their Shutdown() method, so we'll drop the reference naturally when
94 // we're shutting down (in the non xpcom-shutdown case).
95 nsTHashtable<nsRefPtrHashKey<MediaDecoder>> mDecoders;
97 // True if we have an XPCOM shutdown observer.
98 bool mIsObservingShutdown;
100 bool mIsDoingXPCOMShutDown;
101 };
103 } // namespace mozilla
105 #endif