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
This commit is contained in:
parent
ae772278fe
commit
7cc6df5957
@ -1056,6 +1056,12 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
|
|||||||
{
|
{
|
||||||
ATRACE_CALL();
|
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);
|
Mutex::Autolock _l(mStateLock);
|
||||||
const nsecs_t now = systemTime();
|
const nsecs_t now = systemTime();
|
||||||
mDebugInTransaction = now;
|
mDebugInTransaction = now;
|
||||||
|
Loading…
Reference in New Issue
Block a user