diff options
| author | 2022-12-09 20:48:00 +0000 | |
|---|---|---|
| committer | 2022-12-09 20:48:13 +0000 | |
| commit | 4e04c3a31253304dbb92a25a8d0c9e3ad5b1fe31 (patch) | |
| tree | 37f23069c2f60d0d022b4fe9394478dd0c14db1b /libs/gui | |
| parent | 52363196454b0bfca4c395bb711d806c9b33ea44 (diff) | |
SurfaceComposerClient: Handle transaction apply sync timeouts
We switched to using transaction complete callbacks to handle
transaction#apply(/*sync*/=true). The callback object was
destroyed after waiting for the callback. In the event of a
timeout, the callback would access an invalid object.
Fix this by using ref counted object to ensure the context
remains valid.
Fixes: 261679196
Test: atest SurfaceFlinger_test
Change-Id: I4f840214672dd4051cb57b9551bf20802cc90890
Diffstat (limited to 'libs/gui')
| -rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 1e43700d06..6fe1fb2b35 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -971,14 +971,16 @@ void SurfaceComposerClient::Transaction::cacheBuffers() { class SyncCallback { public: - static void function(void* callbackContext, nsecs_t /* latchTime */, - const sp<Fence>& /* presentFence */, - const std::vector<SurfaceControlStats>& /* stats */) { - if (!callbackContext) { - ALOGE("failed to get callback context for SyncCallback"); - } - SyncCallback* helper = static_cast<SyncCallback*>(callbackContext); - LOG_ALWAYS_FATAL_IF(sem_post(&helper->mSemaphore), "sem_post failed"); + static auto getCallback(std::shared_ptr<SyncCallback>& callbackContext) { + return [callbackContext](void* /* unused context */, nsecs_t /* latchTime */, + const sp<Fence>& /* presentFence */, + const std::vector<SurfaceControlStats>& /* stats */) { + if (!callbackContext) { + ALOGE("failed to get callback context for SyncCallback"); + return; + } + LOG_ALWAYS_FATAL_IF(sem_post(&callbackContext->mSemaphore), "sem_post failed"); + }; } ~SyncCallback() { if (mInitialized) { @@ -1013,10 +1015,11 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay return mStatus; } - SyncCallback syncCallback; + std::shared_ptr<SyncCallback> syncCallback = std::make_shared<SyncCallback>(); if (synchronous) { - syncCallback.init(); - addTransactionCommittedCallback(syncCallback.function, syncCallback.getContext()); + syncCallback->init(); + addTransactionCommittedCallback(SyncCallback::getCallback(syncCallback), + /*callbackContext=*/nullptr); } bool hasListenerCallbacks = !mListenerCallbacks.empty(); @@ -1092,7 +1095,7 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay clear(); if (synchronous) { - syncCallback.wait(); + syncCallback->wait(); } mStatus = NO_ERROR; |