Bug 882718 - Do not dispatch task to main thread when shutdown. r=rillian draft
authorbechen <bechen@mozilla.com>
Wed, 01 Jun 2016 15:13:45 +0800
changeset 373772 75d748f68cb92af1b394bfa1e47ccd609fafa618
parent 373771 47f9d6d574bab28e3acb5f3b887cacb3661b0fb7
child 522469 205b5b94b9d1fb070a197a93097a5892c52953a4
push id19839
push userbechen@mozilla.com
push dateWed, 01 Jun 2016 07:14:12 +0000
reviewersrillian
bugs882718
milestone49.0a1
Bug 882718 - Do not dispatch task to main thread when shutdown. r=rillian MozReview-Commit-ID: 5Y79Fbhyoc3
dom/html/TextTrackManager.cpp
dom/html/TextTrackManager.h
--- a/dom/html/TextTrackManager.cpp
+++ b/dom/html/TextTrackManager.cpp
@@ -17,16 +17,18 @@
 #include "nsVideoFrame.h"
 #include "nsIFrame.h"
 #include "nsTArrayHelpers.h"
 #include "nsIWebVTTParserWrapper.h"
 
 namespace mozilla {
 namespace dom {
 
+NS_IMPL_ISUPPORTS(TextTrackManager::ShutdownObserverProxy, nsIObserver);
+
 CompareTextTracks::CompareTextTracks(HTMLMediaElement* aMediaElement)
 {
   mMediaElement = aMediaElement;
 }
 
 int32_t
 CompareTextTracks::TrackChildPosition(TextTrack* aTextTrack) const {
   HTMLTrackElement* trackElement = aTextTrack->GetTrackElement();
@@ -89,16 +91,17 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(TextTra
 StaticRefPtr<nsIWebVTTParserWrapper> TextTrackManager::sParserWrapper;
 
 TextTrackManager::TextTrackManager(HTMLMediaElement *aMediaElement)
   : mMediaElement(aMediaElement)
   , mHasSeeked(false)
   , mLastTimeMarchesOnCalled(0.0)
   , mTimeMarchesOnDispatched(false)
   , performedTrackSelection(false)
+  , mShutdown(false)
 {
   nsISupports* parentObject =
     mMediaElement->OwnerDoc()->GetParentObject();
 
   NS_ENSURE_TRUE_VOID(parentObject);
 
   nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(parentObject);
   mNewCues = new TextTrackCueList(window);
@@ -107,20 +110,22 @@ TextTrackManager::TextTrackManager(HTMLM
   mPendingTextTracks = new TextTrackList(window, this);
 
   if (!sParserWrapper) {
     nsCOMPtr<nsIWebVTTParserWrapper> parserWrapper =
       do_CreateInstance(NS_WEBVTTPARSERWRAPPER_CONTRACTID);
     sParserWrapper = parserWrapper;
     ClearOnShutdown(&sParserWrapper);
   }
+  mShutdownProxy = new ShutdownObserverProxy(this);
 }
 
 TextTrackManager::~TextTrackManager()
 {
+  nsContentUtils::UnregisterShutdownObserver(mShutdownProxy);
 }
 
 TextTrackList*
 TextTrackManager::GetTextTracks() const
 {
   return mTextTracks;
 }
 
@@ -507,17 +512,17 @@ private:
 
 void
 TextTrackManager::DispatchTimeMarchesOn()
 {
   // Run the algorithm if no previous instance is still running, otherwise
   // enqueue the current playback position and whether only that changed
   // through its usual monotonic increase during normal playback; current
   // executing call upon completion will check queue for further 'work'.
-  if (!mTimeMarchesOnDispatched) {
+  if (!mTimeMarchesOnDispatched && !mShutdown) {
     NS_DispatchToMainThread(NewRunnableMethod(this, &TextTrackManager::TimeMarchesOn));
     mTimeMarchesOnDispatched = true;
   }
 }
 
 // https://html.spec.whatwg.org/multipage/embedded-content.html#time-marches-on
 void
 TextTrackManager::TimeMarchesOn()
--- a/dom/html/TextTrackManager.h
+++ b/dom/html/TextTrackManager.h
@@ -6,16 +6,17 @@
 
 #ifndef mozilla_dom_TextTrackManager_h
 #define mozilla_dom_TextTrackManager_h
 
 #include "mozilla/dom/TextTrack.h"
 #include "mozilla/dom/TextTrackList.h"
 #include "mozilla/dom/TextTrackCueList.h"
 #include "mozilla/StaticPtr.h"
+#include "nsContentUtils.h"
 
 class nsIWebVTTParserWrapper;
 
 namespace mozilla {
 namespace dom {
 
 class HTMLMediaElement;
 
@@ -92,16 +93,21 @@ public:
 
   void AddListeners();
 
   // The HTMLMediaElement that this TextTrackManager manages the TextTracks of.
   RefPtr<HTMLMediaElement> mMediaElement;
 
   void DispatchTimeMarchesOn();
 
+  void NotifyShutdown()
+  {
+    mShutdown = true;
+  }
+
 private:
   void TimeMarchesOn();
 
   // List of the TextTrackManager's owning HTMLMediaElement's TextTracks.
   RefPtr<TextTrackList> mTextTracks;
   // List of text track objects awaiting loading.
   RefPtr<TextTrackList> mPendingTextTracks;
   // List of newly introduced Text Track cues.
@@ -130,14 +136,43 @@ private:
   //Performs track selection for a set of TextTrackKinds, for example,
   // 'subtitles' and 'captions' should be selected together.
   void PerformTrackSelection(TextTrackKind aTextTrackKinds[], uint32_t size);
   void GetTextTracksOfKinds(TextTrackKind aTextTrackKinds[], uint32_t size,
                             nsTArray<TextTrack*>& aTextTracks);
   void GetTextTracksOfKind(TextTrackKind aTextTrackKind,
                            nsTArray<TextTrack*>& aTextTracks);
   bool TrackIsDefault(TextTrack* aTextTrack);
+
+  class ShutdownObserverProxy final : public nsIObserver
+  {
+    NS_DECL_ISUPPORTS
+
+  public:
+    explicit ShutdownObserverProxy(TextTrackManager* aManager)
+      : mManager(aManager)
+    {
+      nsContentUtils::RegisterShutdownObserver(this);
+    }
+
+    NS_IMETHODIMP Observe(nsISupports *aSubject, const char *aTopic, const char16_t *aData) override
+    {
+      MOZ_ASSERT(NS_IsMainThread());
+      if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
+        nsContentUtils::UnregisterShutdownObserver(this);
+        mManager->NotifyShutdown();
+      }
+      return NS_OK;
+    }
+
+  private:
+    ~ShutdownObserverProxy() {};
+    TextTrackManager* mManager;
+  };
+
+  RefPtr<ShutdownObserverProxy> mShutdownProxy;
+  bool mShutdown;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_TextTrackManager_h