diff options
| author | 2020-06-26 11:31:19 -0700 | |
|---|---|---|
| committer | 2020-06-26 18:47:28 +0000 | |
| commit | 9a808a2ee29e72d1b39e4af94e5e45aaa209f459 (patch) | |
| tree | 6891fc2ede2b4098897cc58017148da649e83199 | |
| parent | 2ba2ce12823b736a5b7088a8fa7401dc8ee0d21b (diff) | |
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
| -rw-r--r-- | core/java/android/view/SurfaceView.java | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 0d21eb5cf920..87b102b5e4d5 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -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); } |