Merge "Prevent onHandleDestroyed from being called w/ mStateLock" into qt-dev
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2ca5c02..fc0d5fc 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3520,33 +3520,41 @@
}
bool SurfaceFlinger::flushTransactionQueues() {
- Mutex::Autolock _l(mStateLock);
+ // to prevent onHandleDestroyed from being called while the lock is held,
+ // we must keep a copy of the transactions (specifically the composer
+ // states) around outside the scope of the lock
+ std::vector<const TransactionState> transactions;
bool flushedATransaction = false;
+ {
+ Mutex::Autolock _l(mStateLock);
- auto it = mTransactionQueues.begin();
- while (it != mTransactionQueues.end()) {
- auto& [applyToken, transactionQueue] = *it;
+ auto it = mTransactionQueues.begin();
+ while (it != mTransactionQueues.end()) {
+ auto& [applyToken, transactionQueue] = *it;
- while (!transactionQueue.empty()) {
- const auto&
- [states, displays, flags, desiredPresentTime, uncacheBuffer, listenerCallbacks,
- postTime, privileged] = transactionQueue.front();
- if (!transactionIsReadyToBeApplied(desiredPresentTime, states)) {
- setTransactionFlags(eTransactionFlushNeeded);
- break;
+ while (!transactionQueue.empty()) {
+ const auto& transaction = transactionQueue.front();
+ if (!transactionIsReadyToBeApplied(transaction.desiredPresentTime,
+ transaction.states)) {
+ setTransactionFlags(eTransactionFlushNeeded);
+ break;
+ }
+ transactions.push_back(transaction);
+ applyTransactionState(transaction.states, transaction.displays, transaction.flags,
+ mPendingInputWindowCommands, transaction.desiredPresentTime,
+ transaction.buffer, transaction.callback,
+ transaction.postTime, transaction.privileged,
+ /*isMainThread*/ true);
+ transactionQueue.pop();
+ flushedATransaction = true;
}
- applyTransactionState(states, displays, flags, mPendingInputWindowCommands,
- desiredPresentTime, uncacheBuffer, listenerCallbacks, postTime,
- privileged, /*isMainThread*/ true);
- transactionQueue.pop();
- flushedATransaction = true;
- }
- if (transactionQueue.empty()) {
- it = mTransactionQueues.erase(it);
- mTransactionCV.broadcast();
- } else {
- std::next(it, 1);
+ if (transactionQueue.empty()) {
+ it = mTransactionQueues.erase(it);
+ mTransactionCV.broadcast();
+ } else {
+ std::next(it, 1);
+ }
}
}
return flushedATransaction;