From 682e33494d4058f651e1ecc80f01982e7f04817f Mon Sep 17 00:00:00 2001 From: Randell Jesup Date: Sun, 28 Sep 2014 12:07:24 -0400 Subject: [PATCH] bug 1072780: patch 3 - Fix up Revive() to not trigger assertions, and also to avoid Init() (blocking) on MainThread r=roc --- content/media/GraphDriver.cpp | 20 ++++++++++++++++---- content/media/MediaStreamGraphImpl.h | 9 ++++++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/content/media/GraphDriver.cpp b/content/media/GraphDriver.cpp index 5fddd5fdbc7a..3469c1850ff2 100644 --- a/content/media/GraphDriver.cpp +++ b/content/media/GraphDriver.cpp @@ -225,7 +225,11 @@ ThreadedDriver::Start() { LIFECYCLE_LOG("Starting thread for a SystemClockDriver %p\n", mGraphImpl); nsCOMPtr event = new MediaStreamGraphInitThreadRunnable(this); - NS_NewNamedThread("MediaStreamGrph", getter_AddRefs(mThread), event); + // Note: mThread may be null during event->Run() if we pass to NewNamedThread! See AudioInitTask + nsresult rv = NS_NewNamedThread("MediaStreamGrph", getter_AddRefs(mThread)); + if (NS_SUCCEEDED(rv)) { + mThread->Dispatch(event, NS_DISPATCH_NORMAL); + } } void @@ -237,9 +241,12 @@ ThreadedDriver::Resume() void ThreadedDriver::Revive() { + // Note: only called on MainThread, without monitor + // We know were weren't in a running state STREAM_LOG(PR_LOG_DEBUG, ("AudioCallbackDriver reviving.")); // If we were switching, switch now. Otherwise, tell thread to run the main // loop again. + MonitorAutoLock mon(mGraphImpl->GetMonitor()); if (mNextDriver) { mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd, mStateComputedTime, mNextStateComputedTime); @@ -667,16 +674,21 @@ AudioCallbackDriver::Stop() void AudioCallbackDriver::Revive() { + // Note: only called on MainThread, without monitor + // We know were weren't in a running state STREAM_LOG(PR_LOG_DEBUG, ("AudioCallbackDriver reviving.")); // If we were switching, switch now. Otherwise, start the audio thread again. + MonitorAutoLock mon(mGraphImpl->GetMonitor()); if (mNextDriver) { mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd, - mStateComputedTime, mNextStateComputedTime); + mStateComputedTime, mNextStateComputedTime); mGraphImpl->SetCurrentDriver(mNextDriver); mNextDriver->Start(); } else { - Init(); - Start(); + STREAM_LOG(PR_LOG_DEBUG, ("Starting audio threads for MediaStreamGraph %p from a new thread.", mGraphImpl)); + nsRefPtr initEvent = + new AsyncCubebTask(this, AsyncCubebTask::INIT); + initEvent->Dispatch(); } } diff --git a/content/media/MediaStreamGraphImpl.h b/content/media/MediaStreamGraphImpl.h index f1b6a0690026..507ef2e0a6ae 100644 --- a/content/media/MediaStreamGraphImpl.h +++ b/content/media/MediaStreamGraphImpl.h @@ -438,9 +438,16 @@ public: * It is only safe to call this at the very end of an iteration, when there * has been a SwitchAtNextIteration call during the iteration. The driver * should return and pass the control to the new driver shortly after. + * We can also switch from Revive() (on MainThread), in which case the + * monitor is held */ void SetCurrentDriver(GraphDriver* aDriver) { - MOZ_ASSERT(mDriver->OnThread()); +#ifdef DEBUG + // #ifdef since we're not wrapping it all in MOZ_ASSERT() + if (!mDriver->OnThread()) { + mMonitor.AssertCurrentThreadOwns(); + } +#endif mDriver = aDriver; }