summaryrefslogtreecommitdiffstats
path: root/services/camera
diff options
context:
space:
mode:
authorEino-Ville Talvala <etalvala@google.com>2013-08-29 12:46:18 -0700
committerEino-Ville Talvala <etalvala@google.com>2013-08-29 12:51:00 -0700
commit26fe6c7c56477ef227205c68f17df07ca3501d65 (patch)
tree562a44a207970f573342636a345b43e101c3d1cf /services/camera
parentc063c1756cbffdc273fe50b208426f59439f1298 (diff)
downloadframeworks_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.cpp19
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.h1
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, ...);