content/media/MediaShutdownManager.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/media/MediaShutdownManager.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,105 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim:set ts=2 sw=2 sts=2 et cindent: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#if !defined(MediaShutdownManager_h_)
    1.11 +#define MediaShutdownManager_h_
    1.12 +
    1.13 +#include "nsIObserver.h"
    1.14 +#include "mozilla/Monitor.h"
    1.15 +#include "mozilla/RefPtr.h"
    1.16 +#include "mozilla/StaticPtr.h"
    1.17 +#include "nsIThread.h"
    1.18 +#include "nsCOMPtr.h"
    1.19 +#include "nsTHashtable.h"
    1.20 +#include "nsHashKeys.h"
    1.21 +
    1.22 +namespace mozilla {
    1.23 +
    1.24 +class MediaDecoder;
    1.25 +class StateMachineThread;
    1.26 +
    1.27 +// The MediaShutdownManager manages shutting down the MediaDecoder
    1.28 +// infrastructure in response to an xpcom-shutdown notification. This happens
    1.29 +// when Gecko is shutting down in the middle of operation. This is tricky, as
    1.30 +// there are a number of moving parts that must be shutdown in a particular
    1.31 +// order. Additionally the xpcom-shutdown observer *must* block until all
    1.32 +// threads are shutdown, which is tricky since we have a number of threads
    1.33 +// here and their shutdown is asynchronous. We can't have each element of
    1.34 +// our pipeline listening for xpcom-shutdown, as if each observer blocks
    1.35 +// waiting for its threads to shutdown it will block other xpcom-shutdown
    1.36 +// notifications from firing, and shutdown of one part of the media pipeline
    1.37 +// (say the State Machine thread) may depend another part to be shutdown
    1.38 +// first (the MediaDecoder threads). The MediaShutdownManager encapsulates
    1.39 +// all these dependencies, and provides a single xpcom-shutdown listener
    1.40 +// for the MediaDecoder infrastructure, to ensure that no shutdown order
    1.41 +// dependencies leak out of the MediaDecoder stack. The MediaShutdownManager
    1.42 +// is a singleton.
    1.43 +//
    1.44 +// The MediaShutdownManager ensures that the MediaDecoder stack is shutdown
    1.45 +// before returning from its xpcom-shutdown observer by keeping track of all
    1.46 +// the active MediaDecoders, and upon xpcom-shutdown calling Shutdown() on
    1.47 +// every MediaDecoder and then spinning the main thread event loop until all
    1.48 +// SharedThreadPools have shutdown. Once the SharedThreadPools are shutdown,
    1.49 +// all the state machines and their threads have been shutdown, the
    1.50 +// xpcom-shutdown observer returns.
    1.51 +//
    1.52 +// Note that calling the Unregister() functions may result in the singleton
    1.53 +// being deleted, so don't store references to the singleton, always use the
    1.54 +// singleton by derefing the referenced returned by
    1.55 +// MediaShutdownManager::Instance(), which ensures that the singleton is
    1.56 +// created when needed.
    1.57 +// i.e. like this:
    1.58 +//    MediaShutdownManager::Instance()::Unregister(someDecoder);
    1.59 +//    MediaShutdownManager::Instance()::Register(someOtherDecoder);
    1.60 +// Not like this:
    1.61 +//  MediaShutdownManager& instance = MediaShutdownManager::Instance();
    1.62 +//  instance.Unregister(someDecoder); // Warning! May delete instance!
    1.63 +//  instance.Register(someOtherDecoder); // BAD! instance may be dangling!
    1.64 +class MediaShutdownManager : public nsIObserver {
    1.65 +public:
    1.66 +  NS_DECL_ISUPPORTS
    1.67 +  NS_DECL_NSIOBSERVER
    1.68 +
    1.69 +  // The MediaShutdownManager is a singleton, access its instance with
    1.70 +  // this accessor.
    1.71 +  static MediaShutdownManager& Instance();
    1.72 +
    1.73 +  // Notifies the MediaShutdownManager that it needs to track the shutdown
    1.74 +  // of this MediaDecoder.
    1.75 +  void Register(MediaDecoder* aDecoder);
    1.76 +
    1.77 +  // Notifies the MediaShutdownManager that a MediaDecoder that it was
    1.78 +  // tracking has shutdown, and it no longer needs to be shutdown in the
    1.79 +  // xpcom-shutdown listener.
    1.80 +  void Unregister(MediaDecoder* aDecoder);
    1.81 +
    1.82 +private:
    1.83 +
    1.84 +  MediaShutdownManager();
    1.85 +  virtual ~MediaShutdownManager();
    1.86 +
    1.87 +  void Shutdown();
    1.88 +
    1.89 +  // Ensures we have a shutdown listener if we need one, and removes the
    1.90 +  // listener and destroys the singleton if we don't.
    1.91 +  void EnsureCorrectShutdownObserverState();
    1.92 +
    1.93 +  static StaticRefPtr<MediaShutdownManager> sInstance;
    1.94 +
    1.95 +  // References to the MediaDecoder. The decoders unregister themselves
    1.96 +  // in their Shutdown() method, so we'll drop the reference naturally when
    1.97 +  // we're shutting down (in the non xpcom-shutdown case).
    1.98 +  nsTHashtable<nsRefPtrHashKey<MediaDecoder>> mDecoders;
    1.99 +
   1.100 +  // True if we have an XPCOM shutdown observer.
   1.101 +  bool mIsObservingShutdown;
   1.102 +
   1.103 +  bool mIsDoingXPCOMShutDown;
   1.104 +};
   1.105 +
   1.106 +} // namespace mozilla
   1.107 +
   1.108 +#endif

mercurial