DispSync: Actually wait forever
When computeNextEventTimeLocked returns INT64_MAX (because there are
currently no listeners), wait until the condition variable is
signaled instead of waiting for a long timeout. Since the condition
variable timeout is specified using CLOCK_REALTIME behind the scenes,
we can receive false wakeups in the presence of large system clock
changes.
Bug: 28152577
Change-Id: I88dbab5d5d0776cb25dea76a4574db055b308fd1
diff --git a/services/surfaceflinger/DispSync.cpp b/services/surfaceflinger/DispSync.cpp
index 4cf9370..37b6420 100644
--- a/services/surfaceflinger/DispSync.cpp
+++ b/services/surfaceflinger/DispSync.cpp
@@ -97,7 +97,6 @@
virtual bool threadLoop() {
status_t err;
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- nsecs_t nextEventTime = 0;
while (true) {
Vector<CallbackInvocation> callbackInvocations;
@@ -127,16 +126,21 @@
continue;
}
- nextEventTime = computeNextEventTimeLocked(now);
- targetTime = nextEventTime;
+ targetTime = computeNextEventTimeLocked(now);
bool isWakeup = false;
if (now < targetTime) {
- ALOGV("[%s] Waiting until %" PRId64, mName,
- ns2us(targetTime));
if (kTraceDetailedInfo) ATRACE_NAME("DispSync waiting");
- err = mCond.waitRelative(mMutex, targetTime - now);
+
+ if (targetTime == INT64_MAX) {
+ ALOGV("[%s] Waiting forever", mName);
+ err = mCond.wait(mMutex);
+ } else {
+ ALOGV("[%s] Waiting until %" PRId64, mName,
+ ns2us(targetTime));
+ err = mCond.waitRelative(mMutex, targetTime - now);
+ }
if (err == TIMED_OUT) {
isWakeup = true;