content/media/MediaShutdownManager.h

Fri, 16 Jan 2015 04:50:19 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 04:50:19 +0100
branch
TOR_BUG_9701
changeset 13
44a2da4a2ab2
permissions
-rw-r--r--

Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32

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

mercurial