content/media/MediaShutdownManager.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

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

mercurial