зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
9aec4911f8
Коммит
7c98745089
|
@ -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)
|
|||
}
|
||||
}
|
||||
|
||||
// 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()) {
|
||||
// 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.
|
||||
!(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()
|
||||
|
|
Загрузка…
Ссылка в новой задаче