summaryrefslogtreecommitdiff
path: root/libs/gui
diff options
context:
space:
mode:
author Vishnu Nair <vishnun@google.com> 2022-12-09 20:48:00 +0000
committer Vishnu Nair <vishnun@google.com> 2022-12-09 20:48:13 +0000
commit4e04c3a31253304dbb92a25a8d0c9e3ad5b1fe31 (patch)
tree37f23069c2f60d0d022b4fe9394478dd0c14db1b /libs/gui
parent52363196454b0bfca4c395bb711d806c9b33ea44 (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.cpp27
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;