diff options
author | Mathias Agopian <mathias@google.com> | 2013-06-05 14:30:54 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2013-06-05 14:38:23 -0700 |
commit | 7cc6df59572582652078df5aeac9e6c67d7fa81e (patch) | |
tree | f3c70a7e392c8c5a9cb0d2762709c9d1cbe6db8e /services/surfaceflinger/SurfaceFlinger.cpp | |
parent | ae772278fe52335b730442f3d86307787dea807e (diff) | |
download | frameworks_native-7cc6df59572582652078df5aeac9e6c67d7fa81e.zip frameworks_native-7cc6df59572582652078df5aeac9e6c67d7fa81e.tar.gz frameworks_native-7cc6df59572582652078df5aeac9e6c67d7fa81e.tar.bz2 |
fix a possible deadlock when removing a layer and destroying a client
generally the last reference to a Layer is released in commitTransaction()
with mStateLock held. Layer itself only holds weak references to Client,
however, ~Layer() briefly promotes this weak reference -- during that time
the all other strong references to that Client go away, ~Layer is left with
the last one... then hell breaks loose as ~Client is called, which in turn
needs to acquire mStateLock.
We fix this by holding a temporary copy of the drawing state during
the transaction so that the side-effects of copying the current
state into the drawing state are seen only after mStateLock has
been released.
Bug: 9106453
Change-Id: Ic5348ac12283500ead87286a37565e8da35f1db2
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index fbd9f25..8291da0 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1056,6 +1056,12 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) { ATRACE_CALL(); + // here we keep a copy of the drawing state (that is the state that's + // going to be overwritten by handleTransactionLocked()) outside of + // mStateLock so that the side-effects of the State assignment + // don't happen with mStateLock held (which can cause deadlocks). + State drawingState(mDrawingState); + Mutex::Autolock _l(mStateLock); const nsecs_t now = systemTime(); mDebugInTransaction = now; |