summaryrefslogtreecommitdiff
path: root/libs/gui/SurfaceComposerClient.cpp
diff options
context:
space:
mode:
author Jorim Jaggi <jjaggi@google.com> 2021-06-04 17:25:25 +0200
committer Jorim Jaggi <jjaggi@google.com> 2021-06-15 21:19:50 +0200
commit1283885c6478edabb3bcdf26a971818a9f510d40 (patch)
tree9429d755ab5b4f4805fba7fea6cd48df464efde8 /libs/gui/SurfaceComposerClient.cpp
parent266ca8e17bdff757c3b76c0cb990a1af0ec550be (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.cpp13
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);
}