diff options
author | Eino-Ville Talvala <etalvala@google.com> | 2012-10-17 16:32:34 -0700 |
---|---|---|
committer | Eino-Ville Talvala <etalvala@google.com> | 2012-10-17 19:00:06 -0700 |
commit | f1945f0435e431fab2e6b83337a1ffe71a8df28c (patch) | |
tree | e1bbd34d295748d963d352ee0736fc6e37540094 /services | |
parent | ecfbc952d51c71832f739b7483dcc8cb5fe68038 (diff) | |
download | frameworks_av-f1945f0435e431fab2e6b83337a1ffe71a8df28c.zip frameworks_av-f1945f0435e431fab2e6b83337a1ffe71a8df28c.tar.gz frameworks_av-f1945f0435e431fab2e6b83337a1ffe71a8df28c.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
Diffstat (limited to 'services')
-rw-r--r-- | services/camera/libcameraservice/Camera2Client.cpp | 18 |
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); } |