From f1945f0435e431fab2e6b83337a1ffe71a8df28c Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Wed, 17 Oct 2012 16:32:34 -0700 Subject: Camera2: Fix potential deadlock setPreviewWindow was holding a lock during long-lasting HAL calls which may cause deadlock if the HAL calls back into the service during the call. Stop holding the lock during these calls, since it's not essential to do so. Bug: 7320517 Change-Id: I4a35703d751e22ac32979b5a1288e291610576e7 --- services/camera/libcameraservice/Camera2Client.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp index 98332f90..06754005 100644 --- a/services/camera/libcameraservice/Camera2Client.cpp +++ b/services/camera/libcameraservice/Camera2Client.cpp @@ -529,15 +529,19 @@ status_t Camera2Client::setPreviewWindowL(const sp& binder, return NO_ERROR; } - SharedParameters::Lock l(mParameters); - switch (l.mParameters.state) { + Parameters::State state; + { + SharedParameters::Lock l(mParameters); + state = l.mParameters.state; + } + switch (state) { case Parameters::DISCONNECTED: case Parameters::RECORD: case Parameters::STILL_CAPTURE: case Parameters::VIDEO_SNAPSHOT: ALOGE("%s: Camera %d: Cannot set preview display while in state %s", __FUNCTION__, mCameraId, - Parameters::getStateName(l.mParameters.state)); + Parameters::getStateName(state)); return INVALID_OPERATION; case Parameters::STOPPED: case Parameters::WAITING_FOR_PREVIEW_WINDOW: @@ -545,10 +549,8 @@ status_t Camera2Client::setPreviewWindowL(const sp& binder, break; case Parameters::PREVIEW: // Already running preview - need to stop and create a new stream - // TODO: Optimize this so that we don't wait for old stream to drain - // before spinning up new stream mStreamingProcessor->stopStream(); - l.mParameters.state = Parameters::WAITING_FOR_PREVIEW_WINDOW; + state = Parameters::WAITING_FOR_PREVIEW_WINDOW; break; } @@ -560,7 +562,9 @@ status_t Camera2Client::setPreviewWindowL(const sp& binder, return res; } - if (l.mParameters.state == Parameters::WAITING_FOR_PREVIEW_WINDOW) { + if (state == Parameters::WAITING_FOR_PREVIEW_WINDOW) { + SharedParameters::Lock l(mParameters); + l.mParameters.state = state; return startPreviewL(l.mParameters, false); } -- cgit v1.2.3