OSDN Git Service

fix a possible deadlock when removing a layer and destroying a client
authorMathias Agopian <mathias@google.com>
Wed, 5 Jun 2013 21:30:54 +0000 (14:30 -0700)
committerJean-Baptiste Queru <jbq@google.com>
Mon, 5 Aug 2013 21:28:46 +0000 (14:28 -0700)
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

services/surfaceflinger/SurfaceFlinger.cpp

index ef0d521..e4d3c5f 100644 (file)
@@ -1037,6 +1037,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;