SurfaceView: Clean up deferred-destroy-surface from UI thread

We utilize mTmpTransaction without locking from the main thread. The
callback info inside the transaction stores an sp to the SurfaceControl.
If we apply the Transaction from two threads independently we may
implicitly call reset() on the same sp instance twice in an overlapping
fashion. While the reference count is itself atomic, that wont stop us
from decrementing it twice here, when we only had one reference.
This leads to an early free and a crash later.

Bug: 159333209
Test: Existing tests pass
Change-Id: I898bef0b6b8c1cf34891410bbadf63fe2f840697
This commit is contained in:
Robert Carr
2020-06-26 11:31:19 -07:00
committed by Rob Carr
parent 2ba2ce1282
commit 9a808a2ee2

View File

@@ -471,6 +471,13 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
private void performDrawFinished() {
if (mDeferredDestroySurfaceControl != null) {
synchronized (mSurfaceControlLock) {
mTmpTransaction.remove(mDeferredDestroySurfaceControl).apply();
mDeferredDestroySurfaceControl = null;
}
}
if (mPendingReportDraws > 0) {
mDrawFinished = true;
if (mAttachedToWindow) {
@@ -1192,13 +1199,6 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
+ "finishedDrawing");
}
if (mDeferredDestroySurfaceControl != null) {
synchronized (mSurfaceControlLock) {
mTmpTransaction.remove(mDeferredDestroySurfaceControl).apply();
mDeferredDestroySurfaceControl = null;
}
}
runOnUiThread(this::performDrawFinished);
}