author Marian-Vasile Laza <>
Tue, 30 Nov 2021 23:30:59 +0200
changeset 600683 15c1262d6e8f4524fa63dcc9cc2572038ffb3a92
parent 572589 7c81249f9d9ad234e034e031bcbacdc729ed4438
permissions -rw-r--r--
Backed out 6 changesets (bug 1715892, bug 1719735) for causing bc test failures. CLOSED TREE Backed out changeset 196952bd8c9c (bug 1715892) Backed out changeset 9105fe01c025 (bug 1715892) Backed out changeset 4c15d1a24ccd (bug 1715892) Backed out changeset 2c328b84285f (bug 1715892) Backed out changeset 8fcdcdf44b62 (bug 1719735) Backed out changeset c48f398e301f (bug 1719735)

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at */

#if !defined(MediaShutdownManager_h_)
#  define MediaShutdownManager_h_

#  include "mozilla/Monitor.h"
#  include "mozilla/RefPtr.h"
#  include "mozilla/StaticPtr.h"
#  include "nsCOMPtr.h"
#  include "nsIAsyncShutdown.h"
#  include "nsIThread.h"
#  include "nsTHashSet.h"

namespace mozilla {

class MediaDecoder;

// The MediaShutdownManager manages shutting down the MediaDecoder
// infrastructure in response to an xpcom-shutdown notification.
// This happens when Gecko is shutting down in the middle of operation.
// This is tricky, as there are a number of moving parts that must
// be shutdown in a particular order. The MediaShutdownManager
// encapsulates all these dependencies to ensure that no shutdown
// order dependencies leak out of the MediaDecoder stack.
// The MediaShutdownManager is a singleton.
// The MediaShutdownManager ensures that the MediaDecoder stack
// is shutdown before exiting xpcom-shutdown stage by registering
// itself with nsIAsyncShutdownService to receive notification
// when the stage of shutdown has started and then calls Shutdown()
// on every MediaDecoder. Shutdown will not proceed until all
// MediaDecoders finish shutdown and MediaShutdownManager unregisters
// itself from the async shutdown service.
// Note that calling the Unregister() functions may result in the singleton
// being deleted, so don't store references to the singleton, always use the
// singleton by derefing the referenced returned by
// MediaShutdownManager::Instance(), which ensures that the singleton is
// created when needed.
// i.e. like this:
//    MediaShutdownManager::Instance()::Unregister(someDecoder);
//    MediaShutdownManager::Instance()::Register(someOtherDecoder);
// Not like this:
//  MediaShutdownManager& instance = MediaShutdownManager::Instance();
//  instance.Unregister(someDecoder); // Warning! May delete instance!
//  instance.Register(someOtherDecoder); // BAD! instance may be dangling!
class MediaShutdownManager : public nsIAsyncShutdownBlocker {

  static void InitStatics();

  // The MediaShutdownManager is a singleton, access its instance with
  // this accessor.
  static MediaShutdownManager& Instance();

  // Notifies the MediaShutdownManager that it needs to track the shutdown
  // of this MediaDecoder.
  nsresult Register(MediaDecoder* aDecoder);

  // Notifies the MediaShutdownManager that a MediaDecoder that it was
  // tracking has shutdown, and it no longer needs to be shutdown in the
  // xpcom-shutdown listener.
  void Unregister(MediaDecoder* aDecoder);

  enum InitPhase {

  static InitPhase sInitPhase;

  virtual ~MediaShutdownManager();
  void RemoveBlocker();

  static StaticRefPtr<MediaShutdownManager> sInstance;

  // References to the MediaDecoder. The decoders unregister themselves
  // in their Shutdown() method, so we'll drop the reference naturally when
  // we're shutting down (in the non xpcom-shutdown case).
  nsTHashSet<RefPtr<MediaDecoder>> mDecoders;

}  // namespace mozilla