diff options
| author | 2017-04-04 21:51:01 +0000 | |
|---|---|---|
| committer | 2017-04-04 21:51:01 +0000 | |
| commit | 2d45cf2a4062992429f28b1c4fc1c8a224138321 (patch) | |
| tree | 979d054e224567e06471025d51aea31e19874385 /libs/gui/BufferQueueProducer.cpp | |
| parent | 8e5deb6b96ea40a5408ec723f69b0c8951cff47d (diff) | |
| parent | 4f6ce7c7b839da76c1542b41816764e05413af99 (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.cpp | 20 |
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); |