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:
Karl Tomlinson 2020-06-12 02:38:35 +00:00
Родитель 96bbd9e7ae
Коммит f426576017
2 изменённых файлов: 3 добавлений и 35 удалений

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

@ -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;