Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5da64c91 authored by Mathias Agopian's avatar Mathias Agopian Committed by android-build-merger
Browse files

fix race condition that can cause a use after free

am: 59485525

Change-Id: I42d7ee49dc3dcbd9d5d4a86fc9d018ff6c29534d
parents 8b99decc 59485525
Loading
Loading
Loading
Loading
+14 −6
Original line number Diff line number Diff line
@@ -920,7 +920,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);
@@ -932,20 +936,24 @@ status_t BufferQueueProducer::queueBuffer(int slot,
            frameReplacedListener->onFrameReplaced(item);
        }

        connectedApi = mCore->mConnectedApi;
        lastQueuedFence = std::move(mLastQueueBufferFence);

        mLastQueueBufferFence = std::move(fence);
        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 = fence;
    mLastQueuedCrop = item.mCrop;
    mLastQueuedTransform = item.mTransform;

    return NO_ERROR;
}