b=936317 prevent MediaBufferDecoder threads from waiting after AudioContext shutdown() r=ehsan
authorKarl Tomlinson <karlt+@karlt.net>
Sat, 09 Nov 2013 14:07:45 +1300
changeset 154228 da38522cb52b299e15509eff81681e0b2f62e55e
parent 154227 9768d081b7d8b74309b87c2c88e397bea5b52e98
child 154229 06d3a099e96be3acc0f08c27aec3aeaea2943ef3
push id36020
push userktomlinson@mozilla.com
push dateSat, 09 Nov 2013 01:10:48 +0000
treeherdermozilla-inbound@06d3a099e96b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs936317
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
b=936317 prevent MediaBufferDecoder threads from waiting after AudioContext shutdown() r=ehsan
content/media/webaudio/AudioContext.cpp
content/media/webaudio/MediaBufferDecoder.cpp
content/media/webaudio/MediaBufferDecoder.h
--- a/content/media/webaudio/AudioContext.cpp
+++ b/content/media/webaudio/AudioContext.cpp
@@ -530,16 +530,18 @@ AudioContext::CurrentTime() const
 
 void
 AudioContext::Shutdown()
 {
   mIsShutDown = true;
 
   Suspend();
 
+  mDecoder.Shutdown();
+
   // Release references to active nodes.
   // Active AudioNodes don't unregister in destructors, at which point the
   // Node is already unregistered.
   mActiveNodes.Clear();
 
   // For offline contexts, we can destroy the MediaStreamGraph at this point.
   if (mIsOffline && mDestination) {
     mDestination->OfflineShutdown();
--- a/content/media/webaudio/MediaBufferDecoder.cpp
+++ b/content/media/webaudio/MediaBufferDecoder.cpp
@@ -534,16 +534,27 @@ MediaBufferDecoder::EnsureThreadPoolInit
     if (!mThreadPool) {
       return false;
     }
     mThreadPool->SetName(NS_LITERAL_CSTRING("MediaBufferDecoder"));
   }
   return true;
 }
 
+void
+MediaBufferDecoder::Shutdown() {
+  if (mThreadPool) {
+    // Setting threadLimit to 0 causes threads to exit when all events have
+    // been run, like nsIThreadPool::Shutdown(), but doesn't run a nested event
+    // loop nor wait until this has happened.
+    mThreadPool->SetThreadLimit(0);
+    mThreadPool = nullptr;
+  }
+}
+
 WebAudioDecodeJob::WebAudioDecodeJob(const nsACString& aContentType,
                                      AudioContext* aContext,
                                      const ArrayBuffer& aBuffer,
                                      DecodeSuccessCallback* aSuccessCallback,
                                      DecodeErrorCallback* aFailureCallback)
   : mContentType(aContentType)
   , mWriteIndex(0)
   , mContext(aContext)
--- a/content/media/webaudio/MediaBufferDecoder.h
+++ b/content/media/webaudio/MediaBufferDecoder.h
@@ -75,16 +75,18 @@ class MediaBufferDecoder
 {
 public:
   void AsyncDecodeMedia(const char* aContentType, uint8_t* aBuffer,
                         uint32_t aLength, WebAudioDecodeJob& aDecodeJob);
 
   bool SyncDecodeMedia(const char* aContentType, uint8_t* aBuffer,
                        uint32_t aLength, WebAudioDecodeJob& aDecodeJob);
 
+  void Shutdown();
+
 private:
   bool EnsureThreadPoolInitialized();
 
 private:
   nsCOMPtr<nsIThreadPool> mThreadPool;
 };
 
 }