Skip to content

Commit

Permalink
fix a possible deadlock when removing a layer and destroying a client
Browse files Browse the repository at this point in the history
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
  • Loading branch information
pixelflinger authored and tdm committed Aug 15, 2013
1 parent 9eb6e44 commit e2cfa88
Showing 1 changed file with 6 additions and 0 deletions.
6 changes: 6 additions & 0 deletions services/surfaceflinger/SurfaceFlinger.cpp
Expand Up @@ -1066,6 +1066,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;
Expand Down

0 comments on commit e2cfa88

Please sign in to comment.