Fix wait_until(infinity) for condition_variable

libcxx implements wait_until using wait_for, which in
its turn has to call a syscall that's basically wait_until,
causing a double conversion of the waiting time parameter.
Because of this, infinity detection code in those conversions
sometimes fail if the delat between the conversions is long
enough - causing a syscall error for 'invalid time'

This CL explicitly calls non-timed wait() instead.

Bug: 293223125
Bug: 292138960
Test: build + unit tests + presubmits
Change-Id: Id30fdfbe374b63fcaed627fcdf374f1e501a7807
diff --git a/services/incremental/ServiceWrappers.cpp b/services/incremental/ServiceWrappers.cpp
index ce3d514..2a2fa7a 100644
--- a/services/incremental/ServiceWrappers.cpp
+++ b/services/incremental/ServiceWrappers.cpp
@@ -315,11 +315,22 @@
         std::unique_lock lock(mMutex);
         for (;;) {
             const TimePoint nextJobTs = mJobs.empty() ? kInfinityTs : mJobs.begin()->when;
-            mCondition.wait_until(lock, nextJobTs, [this, oldNextJobTs = nextJobTs]() {
+            auto conditionPredicate = [this, oldNextJobTs = nextJobTs]() {
                 const auto now = Clock::now();
                 const auto newFirstJobTs = !mJobs.empty() ? mJobs.begin()->when : kInfinityTs;
                 return newFirstJobTs <= now || newFirstJobTs < oldNextJobTs || !mRunning;
-            });
+            };
+            // libcxx's implementation of wait_until() recalculates the 'until' time into
+            // the wait duration and then goes back to the absolute timestamp when calling
+            // pthread_cond_timedwait(); this back-and-forth calculation sometimes loses
+            // the 'infinity' value because enough time passes in between, and instead
+            // passes incorrect timestamp into the syscall, causing a crash.
+            // Mitigating it by explicitly calling the non-timed wait here.
+            if (mJobs.empty()) {
+                mCondition.wait(lock, conditionPredicate);
+            } else {
+                mCondition.wait_until(lock, nextJobTs, conditionPredicate);
+            }
             if (!mRunning) {
                 return;
             }