SF/CE: Fix startup race in HwcAsyncWorker
If a HwcAsyncWorker is created, and shortly after `HwcAsyncWorker::send` is called to queue up a task to run, there is a chance that the thread that is created to run the tasks hasn't gotten to waiting on the internal condition variable before the `notify_one` call is made to wake up any waiting threads. The result is that the HwcAsyncWorker thread doesn't get notified, and goes to sleep. Meanwhile the SurfaceFlinger main thread waits forever for the task to complete. Eventually the System Services start timing out as SurfaceFlinger isn't processing requests. The fix is simple -- switch to the two argument (predicate) form of `std::condition_variable::wait()`, with the predicate checking for a task (and the done flag). The predicate is checked before actually waiting on the condition variable. Additionally a unit test is added to verify this and a few other edge conditions. The test fails (times out) without the implementation fix when run with `atest`, and passes/completes with it. Note that this is normally an uncommon error particularly on most devices as HwcAsyncWorkers are only created when new outputs (virtual or physical displays) are created, and there is usually a big gap between when the HwcAsyncWorker is created and when it is actually used. It ended up being more of a problem on Chromebooks as we create outputs for every new app window, which happens much more frequently, and with a much shorter delay between creation and use. Flag: EXEMPT bugfix Bug: 333824019 Test: atest libcompositionengine_test Test: Smoke test of running DOTA Underlords on a Trogdor Chromebook (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:e0b2747abd28f4595a6f18f3f9fbe8aa15ae7000) Merged-In: If3ad46a1297a0448dbdb505957081329f4cd2aca Change-Id: If3ad46a1297a0448dbdb505957081329f4cd2aca
Loading
Please register or sign in to comment