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

Commit 369d1f5d authored by Marissa Wall's avatar Marissa Wall Committed by android-build-team Robot
Browse files

blast: fix leak on BufferStateLayer death

SurfaceFlinger can occasionally leak graphic buffers.

The leak happens when:
1) a transaction comes in and is placed in a queue
2) Chrome crashes
3) the parent layer is cleaned up
4) the child layer is told to release its buffer because it is
        no longer on screen
5) the transaction is applied with sets a callback handle on the
        layer which has a sp<> to the layer

To fix this, the callback handle should not have a sp<> to layer.
It is safe for the callback handle can have wp<> to the layer.
The client side has a sp<> so during normal operation, SurfaceFlinger
can promote the wp<>. The only time the promote will fail is if the
client side is dead. If the client side is dead, there is no one
to send a callback to so it doesn't matter if the promote fails.

Bug: 135951943
Test: https://buganizer.corp.google.com/issues/135951943#comment34
Change-Id: I756ace14c90b03a6499a3187d235b42d91cdd05a
(cherry picked from commit 0e24a838)
parent ba0112f5
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -197,8 +197,14 @@ status_t TransactionCompletedThread::addCallbackHandle(const sp<CallbackHandle>&
    }

    transactionStats->latchTime = handle->latchTime;
    transactionStats->surfaceStats.emplace_back(handle->surfaceControl, handle->acquireTime,
    // If the layer has already been destroyed, don't add the SurfaceControl to the callback.
    // The client side keeps a sp<> to the SurfaceControl so if the SurfaceControl has been
    // destroyed the client side is dead and there won't be anyone to send the callback to.
    sp<IBinder> surfaceControl = handle->surfaceControl.promote();
    if (surfaceControl) {
        transactionStats->surfaceStats.emplace_back(surfaceControl, handle->acquireTime,
                                                    handle->previousReleaseFence);
    }
    return NO_ERROR;
}

+1 −1
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ public:

    sp<ITransactionCompletedListener> listener;
    std::vector<CallbackId> callbackIds;
    sp<IBinder> surfaceControl;
    wp<IBinder> surfaceControl;

    bool releasePreviousBuffer = false;
    sp<Fence> previousReleaseFence;