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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user