diff options
author | Eino-Ville Talvala <etalvala@google.com> | 2013-08-29 12:46:18 -0700 |
---|---|---|
committer | Eino-Ville Talvala <etalvala@google.com> | 2013-08-29 12:51:00 -0700 |
commit | 26fe6c7c56477ef227205c68f17df07ca3501d65 (patch) | |
tree | 562a44a207970f573342636a345b43e101c3d1cf /services/camera | |
parent | c063c1756cbffdc273fe50b208426f59439f1298 (diff) | |
download | frameworks_av-26fe6c7c56477ef227205c68f17df07ca3501d65.zip frameworks_av-26fe6c7c56477ef227205c68f17df07ca3501d65.tar.gz frameworks_av-26fe6c7c56477ef227205c68f17df07ca3501d65.tar.bz2 |
Camera3: Be busy as soon as work arrives.
RequestThread's internal busy flag (mPaused) was not being immediately
set when new work was submitted to it. This allowed for a race
condition where a capture() followed by an immediate
waitUntilDrained() would immediately return from the wait.
Set the mPaused flag to false immediately in capture() and
setStreamingRequest() to avoid this, instead of waiting until the end
of the next RequestThread iteration.
Bug: 10531739
Change-Id: I54a79fe5361d527ec717f41ad805e9b319a48cd8
Diffstat (limited to 'services/camera')
-rw-r--r-- | services/camera/libcameraservice/device3/Camera3Device.cpp | 19 | ||||
-rw-r--r-- | services/camera/libcameraservice/device3/Camera3Device.h | 1 |
2 files changed, 19 insertions, 1 deletions
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 7f2ec7a..47321e0 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -1424,6 +1424,8 @@ status_t Camera3Device::RequestThread::queueRequest( Mutex::Autolock l(mRequestLock); mRequestQueue.push_back(request); + unpauseForNewRequests(); + return OK; } @@ -1489,6 +1491,9 @@ status_t Camera3Device::RequestThread::setRepeatingRequests( mRepeatingRequests.clear(); mRepeatingRequests.insert(mRepeatingRequests.begin(), requests.begin(), requests.end()); + + unpauseForNewRequests(); + return OK; } @@ -1791,7 +1796,9 @@ sp<Camera3Device::CaptureRequest> mRequestQueue.erase(firstRequest); } - // Not paused + // In case we've been unpaused by setPaused clearing mDoPause, need to + // update internal pause state (capture/setRepeatingRequest unpause + // directly). Mutex::Autolock pl(mPauseLock); mPaused = false; @@ -1824,6 +1831,16 @@ bool Camera3Device::RequestThread::waitIfPaused() { return false; } +void Camera3Device::RequestThread::unpauseForNewRequests() { + // With work to do, mark thread as unpaused. + // If paused by request (setPaused), don't resume, to avoid + // extra signaling/waiting overhead to waitUntilPaused + Mutex::Autolock p(mPauseLock); + if (!mDoPause) { + mPaused = false; + } +} + void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) { sp<Camera3Device> parent = mParent.promote(); if (parent != NULL) { diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index 99e1cc8..6565048 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -314,6 +314,7 @@ class Camera3Device : // Pause handling bool waitIfPaused(); + void unpauseForNewRequests(); // Relay error to parent device object setErrorState void setErrorState(const char *fmt, ...); |