summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Thomas <steventhomas@google.com>2017-09-28 15:30:23 -0700
committerSteven Thomas <steventhomas@google.com>2017-09-29 11:03:15 -0700
commitbe6cbae3b61a55ab87c131e79dba03d159961aa3 (patch)
tree8f5eca867ce05ec0fb0aca7950b556aa870d2b47
parent7e70ec2c0d38aeaf7bd06519e6bd12f4528eb23d (diff)
downloadnative-be6cbae3b61a55ab87c131e79dba03d159961aa3.tar.gz
Fix deadlock when transitioning to vr flinger
If we were unlucky with the timing when switching to vr flinger we would sometimes deadlock. The vr dispatch thread would request the display from surface flinger, locking mStateLock in the process. mStateLock was being held by the surface flinger main thread, which was processing a previous request to switch to vr flinger. The main thread was trying to connect to the vr hardware composer service, which sent a request to the vr dispatch thread as part of its initialization, leading to the deadlock. The deadlock is easily fixed by posting a message to request the vr flinger switch to the surface flinger main thread, instead of doing it on the vr dispatch thread. Bug: 66916578 Test: Confirmed I can still get into/out of vr flinger on Marlin. There's no longer code to acquire mStateLock in the vr dispatch thread, so the deadlock is no longer possible. Change-Id: I3de5476f698ed798f6b9afe927cc733f0f38c56e
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp17
1 files changed, 12 insertions, 5 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 12205af919..c05ac8aaac 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -604,11 +604,18 @@ void SurfaceFlinger::init() {
if (useVrFlinger) {
auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {
- ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);
- mVrFlingerRequestsDisplay = requestDisplay;
- ConditionalLock _l(mStateLock,
- std::this_thread::get_id() != mMainThreadId);
- signalTransaction();
+ // This callback is called from the vr flinger dispatch thread. We
+ // need to call signalTransaction(), which requires holding
+ // mStateLock when we're not on the main thread. Acquiring
+ // mStateLock from the vr flinger dispatch thread might trigger a
+ // deadlock in surface flinger (see b/66916578), so post a message
+ // to be handled on the main thread instead.
+ sp<LambdaMessage> message = new LambdaMessage([=]() {
+ ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);
+ mVrFlingerRequestsDisplay = requestDisplay;
+ signalTransaction();
+ });
+ postMessageAsync(message);
};
mVrFlinger = dvr::VrFlinger::Create(mHwc->getComposer(),
vrFlingerRequestDisplayCallback);