MediaShutdownManager.h 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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/. */
  6. #if !defined(MediaShutdownManager_h_)
  7. #define MediaShutdownManager_h_
  8. #include "mozilla/Monitor.h"
  9. #include "mozilla/RefPtr.h"
  10. #include "mozilla/StaticPtr.h"
  11. #include "nsCOMPtr.h"
  12. #include "nsIAsyncShutdown.h"
  13. #include "nsIThread.h"
  14. #include "nsHashKeys.h"
  15. #include "nsTHashtable.h"
  16. namespace mozilla {
  17. class MediaDecoder;
  18. // The MediaShutdownManager manages shutting down the MediaDecoder
  19. // infrastructure in response to an xpcom-shutdown notification.
  20. // This happens when Gecko is shutting down in the middle of operation.
  21. // This is tricky, as there are a number of moving parts that must
  22. // be shutdown in a particular order. The MediaShutdownManager
  23. // encapsulates all these dependencies to ensure that no shutdown
  24. // order dependencies leak out of the MediaDecoder stack.
  25. // The MediaShutdownManager is a singleton.
  26. //
  27. // The MediaShutdownManager ensures that the MediaDecoder stack
  28. // is shutdown before exiting xpcom-shutdown stage by registering
  29. // itself with nsIAsyncShutdownService to receive notification
  30. // when the stage of shutdown has started and then calls Shutdown()
  31. // on every MediaDecoder. Shutdown will not proceed until all
  32. // MediaDecoders finish shutdown and MediaShutdownManager unregisters
  33. // itself from the async shutdown service.
  34. //
  35. // Note that calling the Unregister() functions may result in the singleton
  36. // being deleted, so don't store references to the singleton, always use the
  37. // singleton by derefing the referenced returned by
  38. // MediaShutdownManager::Instance(), which ensures that the singleton is
  39. // created when needed.
  40. // i.e. like this:
  41. // MediaShutdownManager::Instance()::Unregister(someDecoder);
  42. // MediaShutdownManager::Instance()::Register(someOtherDecoder);
  43. // Not like this:
  44. // MediaShutdownManager& instance = MediaShutdownManager::Instance();
  45. // instance.Unregister(someDecoder); // Warning! May delete instance!
  46. // instance.Register(someOtherDecoder); // BAD! instance may be dangling!
  47. class MediaShutdownManager : public nsIAsyncShutdownBlocker {
  48. public:
  49. NS_DECL_ISUPPORTS
  50. NS_DECL_NSIASYNCSHUTDOWNBLOCKER
  51. static void InitStatics();
  52. // The MediaShutdownManager is a singleton, access its instance with
  53. // this accessor.
  54. static MediaShutdownManager& Instance();
  55. // Notifies the MediaShutdownManager that it needs to track the shutdown
  56. // of this MediaDecoder.
  57. nsresult Register(MediaDecoder* aDecoder);
  58. // Notifies the MediaShutdownManager that a MediaDecoder that it was
  59. // tracking has shutdown, and it no longer needs to be shutdown in the
  60. // xpcom-shutdown listener.
  61. void Unregister(MediaDecoder* aDecoder);
  62. private:
  63. MediaShutdownManager();
  64. virtual ~MediaShutdownManager();
  65. void RemoveBlocker();
  66. static StaticRefPtr<MediaShutdownManager> sInstance;
  67. // References to the MediaDecoder. The decoders unregister themselves
  68. // in their Shutdown() method, so we'll drop the reference naturally when
  69. // we're shutting down (in the non xpcom-shutdown case).
  70. nsTHashtable<nsRefPtrHashKey<MediaDecoder>> mDecoders;
  71. bool mIsDoingXPCOMShutDown = false;
  72. };
  73. } // namespace mozilla
  74. #endif