bug 1408276 move to LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP at end of iteration f=pehrsons r=padenot

MozReview-Commit-ID: GbfIOPZPuGu

--HG--
extra : rebase_source : 8a7abbe8a96a90f20dbb0465b6a5f69f05140d4f
extra : amend_source : 41079a2a825b53ed6d4e8cc31fc4c8de2f041e8b
extra : histedit_source : df5b962ac253df34ace8ebc22cdd98b608b6ddfb
This commit is contained in:
Karl Tomlinson 2017-10-17 18:14:43 +13:00
Родитель 9aec4911f8
Коммит 7c98745089
3 изменённых файлов: 49 добавлений и 23 удалений

Просмотреть файл

@ -284,8 +284,7 @@ SystemClockDriver::IsFallback()
void
ThreadedDriver::RunThread()
{
bool stillProcessing = true;
while (stillProcessing) {
while (true) {
mIterationStart = IterationEnd();
mIterationEnd += GetIntervalForIteration();
@ -324,10 +323,16 @@ ThreadedDriver::RunThread()
(long)stateComputedTime,
(long)nextStateComputedTime));
stillProcessing = mGraphImpl->OneIteration(nextStateComputedTime);
bool stillProcessing = mGraphImpl->OneIteration(nextStateComputedTime);
if (!stillProcessing) {
// Enter shutdown mode. The stable-state handler will detect this
// and complete shutdown if the graph does not get restarted.
mGraphImpl->SignalMainThreadCleanup();
return;
}
MonitorAutoLock lock(GraphImpl()->GetMonitor());
if (NextDriver() && stillProcessing) {
if (NextDriver()) {
LOG(LogLevel::Debug, ("Switching to AudioCallbackDriver"));
RemoveCallback();
NextDriver()->SetGraphTime(this, mIterationStart, mIterationEnd);
@ -1000,13 +1005,20 @@ AudioCallbackDriver::DataCallback(const AudioDataValue* aInputBuffer,
mGraphImpl->NotifyOutputData(aOutputBuffer, static_cast<size_t>(aFrames),
mSampleRate, mOutputChannels);
if (!stillProcessing) {
// Enter shutdown mode. The stable-state handler will detect this
// and complete shutdown if the graph does not get restarted.
mGraphImpl->SignalMainThreadCleanup();
return aFrames - 1;
}
bool switching = false;
{
MonitorAutoLock mon(mGraphImpl->GetMonitor());
switching = !!NextDriver();
}
if (switching && stillProcessing) {
if (switching) {
// If the audio stream has not been started by the previous driver or
// the graph itself, keep it alive.
MonitorAutoLock mon(mGraphImpl->GetMonitor());
@ -1023,11 +1035,6 @@ AudioCallbackDriver::DataCallback(const AudioDataValue* aInputBuffer,
return aFrames - 1;
}
if (!stillProcessing) {
LOG(LogLevel::Debug,
("Stopping audio thread for MediaStreamGraph %p", this));
return aFrames - 1;
}
return aFrames;
}

Просмотреть файл

@ -1217,11 +1217,13 @@ MediaStreamGraphImpl::PrepareUpdatesToMainThreadState(bool aFinalUpdate)
}
}
// If this is the final update, then a stable state event will soon be
// posted just before this thread finishes, and so there is no need to also
// post here.
if (!aFinalUpdate &&
// Don't send the message to the main thread if it's not going to have
// any work to do.
if (aFinalUpdate ||
!mUpdateRunnables.IsEmpty() ||
!mStreamUpdates.IsEmpty()) {
!(mUpdateRunnables.IsEmpty() && mStreamUpdates.IsEmpty())) {
EnsureStableStateEventPosted();
}
}
@ -1460,12 +1462,7 @@ MediaStreamGraphImpl::UpdateMainThreadState()
(IsEmpty() && mBackMessageQueue.IsEmpty());
PrepareUpdatesToMainThreadState(finalUpdate);
if (finalUpdate) {
// Enter shutdown mode. The stable-state handler will detect this
// and complete shutdown. Destroy any streams immediately.
LOG(LogLevel::Debug,
("MediaStreamGraph %p waiting for main thread cleanup", this));
// We'll shut down this graph object if it does not get restarted.
LifecycleStateRef() = LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP;
// Enter shutdown mode when this iteration is completed.
// No need to Destroy streams here. The main-thread owner of each
// stream is responsible for calling Destroy on them.
return false;
@ -1898,6 +1895,19 @@ MediaStreamGraphImpl::EnsureStableStateEventPosted()
mAbstractMainThread->Dispatch(event.forget());
}
void
MediaStreamGraphImpl::SignalMainThreadCleanup()
{
MOZ_ASSERT(mDriver->OnThread());
MonitorAutoLock lock(mMonitor);
LOG(LogLevel::Debug,
("MediaStreamGraph %p waiting for main thread cleanup", this));
LifecycleStateRef() =
MediaStreamGraphImpl::LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP;
EnsureStableStateEventPosted();
}
void
MediaStreamGraphImpl::AppendMessage(UniquePtr<ControlMessage> aMessage)
{

Просмотреть файл

@ -198,6 +198,14 @@ public:
*/
bool OneIteration(GraphTime aStateEnd);
/**
* Called from the driver, when the graph thread is about to stop, to tell
* the main thread to attempt to begin cleanup. The main thread may either
* shutdown or revive the graph depending on whether it receives new
* messages.
*/
void SignalMainThreadCleanup();
bool Running() const
{
return LifecycleStateRef() == LIFECYCLE_RUNNING;
@ -724,8 +732,9 @@ public:
};
/**
* Modified on the main and graph thread (in UpdateMainThreadState() when
* we're about to shutdown) in mMonitor. mMonitor must be held when accessed.
* Modified only in mMonitor. Transitions to
* LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP occur on the graph thread at
* the end of an iteration. All other transitions occur on the main thread.
*/
LifecycleState mLifecycleState;
LifecycleState& LifecycleStateRef()