diff options
author | 2021-06-04 17:25:25 +0200 | |
---|---|---|
committer | 2021-06-15 21:19:50 +0200 | |
commit | 1283885c6478edabb3bcdf26a971818a9f510d40 (patch) | |
tree | 9429d755ab5b4f4805fba7fea6cd48df464efde8 /libs/gui/SurfaceComposerClient.cpp | |
parent | 266ca8e17bdff757c3b76c0cb990a1af0ec550be (diff) |
Ensure reportFrameMetrics not being called on deleted instance
Since onSurfaceStatsAvailable gets called on binder-thread, we
need to ensure that instance doesn't get released while
onSurfaceStatsAvailable is calling reportFrameMetrics.
We do this by introducing a lock for register/unregister/callback,
such than when unregister completes, there won't be any "hanging"
callback anymore such that the callback can't be called anymore
on deleted instances.
Test: Boots
Bug: 188934435
Change-Id: I73e2d4b04cc74a152054cf7620a5c541683cb5e6
Diffstat (limited to 'libs/gui/SurfaceComposerClient.cpp')
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 371454a3de..768f5720ca 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -182,12 +182,12 @@ CallbackId TransactionCompletedListener::addCallbackFunction( void TransactionCompletedListener::addJankListener(const sp<JankDataListener>& listener, sp<SurfaceControl> surfaceControl) { - std::lock_guard<std::mutex> lock(mMutex); + std::scoped_lock<std::recursive_mutex> lock(mJankListenerMutex); mJankListeners.insert({surfaceControl->getHandle(), listener}); } void TransactionCompletedListener::removeJankListener(const sp<JankDataListener>& listener) { - std::lock_guard<std::mutex> lock(mMutex); + std::scoped_lock<std::recursive_mutex> lock(mJankListenerMutex); for (auto it = mJankListeners.begin(); it != mJankListeners.end();) { if (it->second == listener) { it = mJankListeners.erase(it); @@ -242,7 +242,6 @@ void TransactionCompletedListener::addSurfaceControlToCallbacks( void TransactionCompletedListener::onTransactionCompleted(ListenerStats listenerStats) { std::unordered_map<CallbackId, CallbackTranslation, CallbackIdHash> callbacksMap; - std::multimap<sp<IBinder>, sp<JankDataListener>> jankListenersMap; std::multimap<sp<IBinder>, SurfaceStatsCallbackEntry> surfaceListeners; { std::lock_guard<std::mutex> lock(mMutex); @@ -259,7 +258,6 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener * sp<SurfaceControl> that could possibly exist for the callbacks. */ callbacksMap = mCallbacks; - jankListenersMap = mJankListeners; surfaceListeners = mSurfaceStatsListeners; for (const auto& transactionStats : listenerStats.transactionStats) { for (auto& callbackId : transactionStats.callbackIds) { @@ -348,7 +346,12 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener } if (surfaceStats.jankData.empty()) continue; - auto jankRange = jankListenersMap.equal_range(surfaceStats.surfaceControl); + + // Acquire jank listener lock such that we guarantee that after calling unregister, + // there won't be any further callback. + std::scoped_lock<std::recursive_mutex> lock(mJankListenerMutex); + auto copy = mJankListeners; + auto jankRange = copy.equal_range(surfaceStats.surfaceControl); for (auto it = jankRange.first; it != jankRange.second; it++) { it->second->onJankDataAvailable(surfaceStats.jankData); } |