Bug 1684352 - Don't assume that there's a vsync dispatcher handy when observing. r=rmader

My guess is that if Observe() gets called too early, we can receive the
message before updating the vsync source the first time, which would
trigger this crash.

With this patch, we handle it nicely and UpdateVsyncSource will
re-observe as needed.

It's not 100% clear to me if this is actually the issue (and thus
whether this patch is the right solution), since I haven't been able to
repro locally, though. There might be a more subtle race.

Differential Revision: https://phabricator.services.mozilla.com/D100501
This commit is contained in:
Emilio Cobos Álvarez 2020-12-28 14:34:30 +00:00
Родитель 03cad6a22e
Коммит ebb8fa1e75
1 изменённых файлов: 8 добавлений и 4 удалений

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

@ -27,7 +27,7 @@ void VsyncParent::UpdateVsyncSource(
mVsyncSource = gfxPlatform::GetPlatform()->GetHardwareVsync();
}
if (mObservingVsync) {
if (mObservingVsync && mVsyncDispatcher) {
mVsyncDispatcher->RemoveChildRefreshTimer(this);
}
mVsyncDispatcher = mVsyncSource->GetRefreshTimerVsyncDispatcher();
@ -67,7 +67,9 @@ void VsyncParent::DispatchVsyncEvent(const VsyncEvent& aVsync) {
mozilla::ipc::IPCResult VsyncParent::RecvObserve() {
AssertIsOnInitialThread();
if (!mObservingVsync) {
mVsyncDispatcher->AddChildRefreshTimer(this);
if (mVsyncDispatcher) {
mVsyncDispatcher->AddChildRefreshTimer(this);
}
mObservingVsync = true;
return IPC_OK();
}
@ -77,7 +79,9 @@ mozilla::ipc::IPCResult VsyncParent::RecvObserve() {
mozilla::ipc::IPCResult VsyncParent::RecvUnobserve() {
AssertIsOnInitialThread();
if (mObservingVsync) {
mVsyncDispatcher->RemoveChildRefreshTimer(this);
if (mVsyncDispatcher) {
mVsyncDispatcher->RemoveChildRefreshTimer(this);
}
mObservingVsync = false;
return IPC_OK();
}
@ -87,7 +91,7 @@ mozilla::ipc::IPCResult VsyncParent::RecvUnobserve() {
void VsyncParent::ActorDestroy(ActorDestroyReason aActorDestroyReason) {
MOZ_ASSERT(!mDestroyed);
AssertIsOnInitialThread();
if (mObservingVsync) {
if (mObservingVsync && mVsyncDispatcher) {
mVsyncDispatcher->RemoveChildRefreshTimer(this);
}
mVsyncDispatcher = nullptr;