diff options
| author | 2021-05-04 07:13:36 +0000 | |
|---|---|---|
| committer | 2021-05-04 07:13:36 +0000 | |
| commit | 807ae39c936ddbc410207e852ecc25803f2b17a2 (patch) | |
| tree | 9a9c091ab30b58960e330c7832301ad612510a8c | |
| parent | 316bdbd6524e5c03c2aeb86499bda6c13b5124ae (diff) | |
| parent | 2274a3146953176b72f2cf2cc578945d8a95f2ff (diff) | |
Merge "Fix potential synchronized race between SF and InputFlinger" into sc-dev
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 12 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 27 |
2 files changed, 24 insertions, 15 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 6497919c13..df98eb6b74 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3105,7 +3105,7 @@ void SurfaceFlinger::setVsyncConfig(const VsyncModulator::VsyncConfig& config, void SurfaceFlinger::commitTransaction() { commitTransactionLocked(); - signalSynchronousTransactions(); + signalSynchronousTransactions(CountDownLatch::eSyncTransaction); mAnimTransactionPending = false; } @@ -3527,7 +3527,9 @@ void SurfaceFlinger::queueTransaction(TransactionState& state) { // Generate a CountDownLatch pending state if this is a synchronous transaction. if ((state.flags & eSynchronous) || state.inputWindowCommands.syncInputWindows) { state.transactionCommittedSignal = std::make_shared<CountDownLatch>( - (state.inputWindowCommands.syncInputWindows ? 2 : 1)); + (state.inputWindowCommands.syncInputWindows + ? (CountDownLatch::eSyncInputWindows | CountDownLatch::eSyncTransaction) + : CountDownLatch::eSyncTransaction)); } mTransactionQueue.emplace(state); @@ -3552,10 +3554,10 @@ void SurfaceFlinger::waitForSynchronousTransaction( } } -void SurfaceFlinger::signalSynchronousTransactions() { +void SurfaceFlinger::signalSynchronousTransactions(const uint32_t flag) { for (auto it = mTransactionCommittedSignals.begin(); it != mTransactionCommittedSignals.end();) { - if ((*it)->countDown() == 0) { + if ((*it)->countDown(flag)) { it = mTransactionCommittedSignals.erase(it); } else { it++; @@ -6175,7 +6177,7 @@ status_t SurfaceFlinger::renderScreenImplLocked( void SurfaceFlinger::setInputWindowsFinished() { Mutex::Autolock _l(mStateLock); - signalSynchronousTransactions(); + signalSynchronousTransactions(CountDownLatch::eSyncInputWindows); } // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index cf1a545342..4bbdd48035 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -467,24 +467,31 @@ private: class CountDownLatch { public: - explicit CountDownLatch(int32_t count) : mCount(count) {} - - int32_t countDown() { + enum { + eSyncTransaction = 1 << 0, + eSyncInputWindows = 1 << 1, + }; + explicit CountDownLatch(uint32_t flags) : mFlags(flags) {} + + // True if there is no waiting condition after count down. + bool countDown(uint32_t flag) { std::unique_lock<std::mutex> lock(mMutex); - if (mCount == 0) { - return 0; + if (mFlags == 0) { + return true; } - if (--mCount == 0) { + mFlags &= ~flag; + if (mFlags == 0) { mCountDownComplete.notify_all(); + return true; } - return mCount; + return false; } // Return true if triggered. bool wait_until(const std::chrono::seconds& timeout) const { std::unique_lock<std::mutex> lock(mMutex); const auto untilTime = std::chrono::system_clock::now() + timeout; - while (mCount != 0) { + while (mFlags != 0) { // Conditional variables can be woken up sporadically, so we check count // to verify the wakeup was triggered by |countDown|. if (std::cv_status::timeout == mCountDownComplete.wait_until(lock, untilTime)) { @@ -495,7 +502,7 @@ private: } private: - int32_t mCount; + uint32_t mFlags; mutable std::condition_variable mCountDownComplete; mutable std::mutex mMutex; }; @@ -1124,7 +1131,7 @@ private: // Add transaction to the Transaction Queue void queueTransaction(TransactionState& state) EXCLUDES(mQueueLock); void waitForSynchronousTransaction(const CountDownLatch& transactionCommittedSignal); - void signalSynchronousTransactions(); + void signalSynchronousTransactions(const uint32_t flag); /* * Generic Layer Metadata |