зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1644647 reject promises for Close AudioContextOperations run after forced graph shutdown r=padenot
and re-enable OnStateChanged() transition assertions. Rejecting the promise avoids having AudioContextOperation promises resolve out of order when AudioContextOperationControlMessage::RunDuringShutdown() resolves a Close operation shortly after Run() for a previous operation has queued its update via mUpdateRunnables. mUpdateRunnables are run after controlMessagesToRunDuringShutdown. https://searchfox.org/mozilla-central/rev/ea7f70dac1c5fd18400f6d2a92679777d4b21492/dom/media/MediaTrackGraph.cpp#1793,1803 AudioContext::Shutdown() takes care of rejecting JS Promises when the window is being destroyed. Differential Revision: https://phabricator.services.mozilla.com/D79055
This commit is contained in:
Родитель
96bbd9e7ae
Коммит
f426576017
|
@ -3433,7 +3433,7 @@ class AudioContextOperationControlMessage : public ControlMessage {
|
|||
void RunDuringShutdown() override {
|
||||
MOZ_ASSERT(mAudioContextOperation == AudioContextOperation::Close,
|
||||
"We should be reviving the graph?");
|
||||
mHolder.Resolve(AudioContextState::Closed, __func__);
|
||||
mHolder.Reject(false, __func__);
|
||||
}
|
||||
|
||||
nsTArray<RefPtr<MediaTrack>> mTracks;
|
||||
|
|
|
@ -826,45 +826,13 @@ void AudioContext::Dispatch(already_AddRefed<nsIRunnable>&& aRunnable) {
|
|||
void AudioContext::OnStateChanged(void* aPromise, AudioContextState aNewState) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// This can happen if close() was called right after creating the
|
||||
// AudioContext, before the context has switched to "running".
|
||||
if (mAudioContextState == AudioContextState::Closed &&
|
||||
aNewState == AudioContextState::Running && !aPromise) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This can happen if this is called in reaction to a
|
||||
// MediaTrackGraph shutdown, and a AudioContext was being
|
||||
// suspended at the same time, for example if a page was being
|
||||
// closed.
|
||||
if (mAudioContextState == AudioContextState::Closed &&
|
||||
aNewState == AudioContextState::Suspended) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef WIN32 // Bug 1170547
|
||||
# ifndef XP_MACOSX
|
||||
# ifdef DEBUG
|
||||
|
||||
if (!((mAudioContextState == AudioContextState::Suspended &&
|
||||
aNewState == AudioContextState::Running) ||
|
||||
(mAudioContextState == AudioContextState::Running &&
|
||||
aNewState == AudioContextState::Suspended) ||
|
||||
(mAudioContextState == AudioContextState::Running &&
|
||||
aNewState == AudioContextState::Closed) ||
|
||||
(mAudioContextState == AudioContextState::Suspended &&
|
||||
aNewState == AudioContextState::Closed) ||
|
||||
(mAudioContextState == aNewState))) {
|
||||
if (mAudioContextState == AudioContextState::Closed) {
|
||||
fprintf(stderr,
|
||||
"Invalid transition: mAudioContextState: %d -> aNewState %d\n",
|
||||
static_cast<int>(mAudioContextState), static_cast<int>(aNewState));
|
||||
MOZ_ASSERT(false);
|
||||
}
|
||||
|
||||
# endif // DEBUG
|
||||
# endif // XP_MACOSX
|
||||
#endif // WIN32
|
||||
|
||||
if (aPromise) {
|
||||
Promise* promise = reinterpret_cast<Promise*>(aPromise);
|
||||
// It is possible for the promise to have been removed from
|
||||
|
@ -1181,7 +1149,7 @@ void AudioContext::CloseInternal(void* aPromise,
|
|||
aPromise](AudioContextState aNewState) {
|
||||
self->OnStateChanged(aPromise, aNewState);
|
||||
},
|
||||
[] { MOZ_CRASH("Unexpected rejection"); });
|
||||
[] {}); // Promise may be rejected after graph shutdown.
|
||||
}
|
||||
}
|
||||
mCloseCalled = true;
|
||||
|
|
Загрузка…
Ссылка в новой задаче