summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEino-Ville Talvala <etalvala@google.com>2012-10-17 16:32:34 -0700
committerEino-Ville Talvala <etalvala@google.com>2012-10-17 19:00:06 -0700
commitc0fdb98b87bdd88c643a630e18838ddcdd5ab964 (patch)
tree2eaa9a079d75866f1dc771d7dbce67820c6159be
parent509c451f99dff4bda6d73e301df43a5b95c4ffcb (diff)
downloadframeworks_av-c0fdb98b87bdd88c643a630e18838ddcdd5ab964.zip
frameworks_av-c0fdb98b87bdd88c643a630e18838ddcdd5ab964.tar.gz
frameworks_av-c0fdb98b87bdd88c643a630e18838ddcdd5ab964.tar.bz2
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
-rw-r--r--services/camera/libcameraservice/Camera2Client.cpp18
1 files changed, 11 insertions, 7 deletions
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index 98332f9..0675400 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -529,15 +529,19 @@ status_t Camera2Client::setPreviewWindowL(const sp<IBinder>& 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<IBinder>& 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<IBinder>& 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);
}