cameraserver: clear all requests and signal mRequestSignal from RequestThread during disconnect().
This helps reduce wait time on RequestThread::join() in the following situation:
T1 calls disconnect() -> Request
T2 is in RequestThread::threadLoop -> waitForNextRequest -> mRequestSignal.wait()
which has a timeout of 50ms
The 50ms timeout is cleared if we call clear() instead of
clearRepeatingRequest().
Also call repeatingRequestEnd() HAL call from clear() for correctness.
Bug: 246214490
Test: Camera CTS
Test: Vendor Testing
Change-Id: I4e8e7309b7ee7018840e078e7346ab97d549645b
Signed-off-by: Jayant Chowdhary <jchowdhary@google.com>
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 7c2f34f..fa83ee9 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -250,20 +250,28 @@
Mutex::Autolock l(mLock);
if (mStatus == STATUS_UNINITIALIZED) return res;
- if (mStatus == STATUS_ACTIVE ||
- (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
- res = mRequestThread->clearRepeatingRequests();
- if (res != OK) {
- SET_ERR_L("Can't stop streaming");
- // Continue to close device even in case of error
- } else {
- res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
+ if (mRequestThread != NULL) {
+ if (mStatus == STATUS_ACTIVE || mStatus == STATUS_ERROR) {
+ res = mRequestThread->clear();
if (res != OK) {
- SET_ERR_L("Timeout waiting for HAL to drain (% " PRIi64 " ns)",
- maxExpectedDuration);
+ SET_ERR_L("Can't stop streaming");
// Continue to close device even in case of error
+ } else {
+ res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
+ if (res != OK) {
+ SET_ERR_L("Timeout waiting for HAL to drain (% " PRIi64 " ns)",
+ maxExpectedDuration);
+ // Continue to close device even in case of error
+ }
}
}
+ // Signal to request thread that we're not expecting any
+ // more requests. This will be true since once we're in
+ // disconnect and we've cleared off the request queue, the
+ // request thread can't receive any new requests through
+ // binder calls - since disconnect holds
+ // mBinderSerialization lock.
+ mRequestThread->setRequestClearing();
}
if (mStatus == STATUS_ERROR) {
@@ -3047,7 +3055,8 @@
}
-status_t Camera3Device::RequestThread::clearRepeatingRequestsLocked(/*out*/int64_t *lastFrameNumber) {
+status_t Camera3Device::RequestThread::clearRepeatingRequestsLocked(
+ /*out*/int64_t *lastFrameNumber) {
std::vector<int32_t> streamIds;
for (const auto& request : mRepeatingRequests) {
for (const auto& stream : request->mOutputStreams) {
@@ -3072,8 +3081,6 @@
Mutex::Autolock l(mRequestLock);
ALOGV("RequestThread::%s:", __FUNCTION__);
- mRepeatingRequests.clear();
-
// Send errors for all requests pending in the request queue, including
// pending repeating requests
sp<NotificationListener> listener = mListener.promote();
@@ -3111,10 +3118,7 @@
Mutex::Autolock al(mTriggerMutex);
mTriggerMap.clear();
- if (lastFrameNumber != NULL) {
- *lastFrameNumber = mRepeatingLastFrameNumber;
- }
- mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;
+ clearRepeatingRequestsLocked(lastFrameNumber);
mRequestClearing = true;
mRequestSignal.signal();
return OK;
@@ -4209,6 +4213,11 @@
return;
}
+void Camera3Device::RequestThread::setRequestClearing() {
+ Mutex::Autolock l(mRequestLock);
+ mRequestClearing = true;
+}
+
sp<Camera3Device::CaptureRequest>
Camera3Device::RequestThread::waitForNextRequestLocked() {
status_t res;