SF: avoid rearming Timer during cancel
Averts a rare race condition by which a callback would be moved back a
vsync period inappropriately by rearming the callback-dispatching timer
only when the next-up callback was the one that was cancelled.
This was an analagous problem (but through the cancel() path) to
I0e7e2e3698ed6d1765082db20d9cf25f6e6c2db2
Test: 2 new unit tests
Test: boot to home, inspect for problems
Test: dogfood patch on device
Test: A/B uibench sanity check
Fixes: 154303580
Change-Id: I02b2ba12623ac683d9b1c592fdc35e7c7494261a
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
index abeacfe..a596bce 100644
--- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
@@ -338,10 +338,14 @@
}
auto& callback = it->second;
- if (callback->wakeupTime()) {
+ auto const wakeupTime = callback->wakeupTime();
+ if (wakeupTime) {
callback->disarm();
- mIntendedWakeupTime = kInvalidTime;
- rearmTimer(mTimeKeeper->now());
+
+ if (*wakeupTime == mIntendedWakeupTime) {
+ mIntendedWakeupTime = kInvalidTime;
+ rearmTimer(mTimeKeeper->now());
+ }
return CancelResult::Cancelled;
}
return CancelResult::TooLate;