summaryrefslogtreecommitdiff
path: root/libs/gui/BufferQueueProducer.cpp
diff options
context:
space:
mode:
author Mathias Agopian <mathias@google.com> 2017-04-04 21:51:01 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2017-04-04 21:51:01 +0000
commit2d45cf2a4062992429f28b1c4fc1c8a224138321 (patch)
tree979d054e224567e06471025d51aea31e19874385 /libs/gui/BufferQueueProducer.cpp
parent8e5deb6b96ea40a5408ec723f69b0c8951cff47d (diff)
parent4f6ce7c7b839da76c1542b41816764e05413af99 (diff)
Merge "fix race condition that can cause a use after free" into oc-dev
Diffstat (limited to 'libs/gui/BufferQueueProducer.cpp')
-rw-r--r--libs/gui/BufferQueueProducer.cpp20
1 files changed, 14 insertions, 6 deletions
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 27ced6180b..aef231a252 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -951,7 +951,11 @@ status_t BufferQueueProducer::queueBuffer(int slot,
// Call back without the main BufferQueue lock held, but with the callback
// lock held so we can ensure that callbacks occur in order
- {
+
+ int connectedApi;
+ sp<Fence> lastQueuedFence;
+
+ { // scope for the lock
Mutex::Autolock lock(mCallbackMutex);
while (callbackTicket != mCurrentCallbackTicket) {
mCallbackCondition.wait(mCallbackMutex);
@@ -963,20 +967,24 @@ status_t BufferQueueProducer::queueBuffer(int slot,
frameReplacedListener->onFrameReplaced(item);
}
+ connectedApi = mCore->mConnectedApi;
+ lastQueuedFence = std::move(mLastQueueBufferFence);
+
+ mLastQueueBufferFence = std::move(acquireFence);
+ mLastQueuedCrop = item.mCrop;
+ mLastQueuedTransform = item.mTransform;
+
++mCurrentCallbackTicket;
mCallbackCondition.broadcast();
}
// Wait without lock held
- if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
+ if (connectedApi == NATIVE_WINDOW_API_EGL) {
// Waiting here allows for two full buffers to be queued but not a
// third. In the event that frames take varying time, this makes a
// small trade-off in favor of latency rather than throughput.
- mLastQueueBufferFence->waitForever("Throttling EGL Production");
+ lastQueuedFence->waitForever("Throttling EGL Production");
}
- mLastQueueBufferFence = std::move(acquireFence);
- mLastQueuedCrop = item.mCrop;
- mLastQueuedTransform = item.mTransform;
// Update and get FrameEventHistory.
nsecs_t postedTime = systemTime(SYSTEM_TIME_MONOTONIC);