From caa83f5e10c8845c23beed252474b72afabc5e68 Mon Sep 17 00:00:00 2001 From: Marissa Wall Date: Wed, 29 May 2019 13:03:25 -0700 Subject: transactions: fix mutex deadlock on layer death We must drop the mMutex on the TransactionCompletedThread when potentially dropping the last sp to a layer. Bug: 133709028 Test: Transaction_tests Change-Id: I8bbfbf16c755aee7d010a0992f7328f50d521c8b --- services/surfaceflinger/TransactionCompletedThread.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'services/surfaceflinger/TransactionCompletedThread.cpp') diff --git a/services/surfaceflinger/TransactionCompletedThread.cpp b/services/surfaceflinger/TransactionCompletedThread.cpp index b1bf4e20d3..5cf8eb1a1d 100644 --- a/services/surfaceflinger/TransactionCompletedThread.cpp +++ b/services/surfaceflinger/TransactionCompletedThread.cpp @@ -219,6 +219,7 @@ void TransactionCompletedThread::threadMain() { while (mKeepRunning) { mConditionVariable.wait(mMutex); + std::vector completedListenerStats; // For each listener auto completedTransactionsItr = mCompletedTransactions.begin(); @@ -264,11 +265,27 @@ void TransactionCompletedThread::threadMain() { } else { completedTransactionsItr++; } + + completedListenerStats.push_back(std::move(listenerStats)); } if (mPresentFence) { mPresentFence.clear(); } + + // If everyone else has dropped their reference to a layer and its listener is dead, + // we are about to cause the layer to be deleted. If this happens at the wrong time and + // we are holding mMutex, we will cause a deadlock. + // + // The deadlock happens because this thread is holding on to mMutex and when we delete + // the layer, it grabs SF's mStateLock. A different SF binder thread grabs mStateLock, + // then call's TransactionCompletedThread::run() which tries to grab mMutex. + // + // To avoid this deadlock, we need to unlock mMutex when dropping our last reference to + // to the layer. + mMutex.unlock(); + completedListenerStats.clear(); + mMutex.lock(); } } -- cgit v1.2.3-59-g8ed1b