summaryrefslogtreecommitdiffstats
path: root/services/camera/libcameraservice/CameraService.cpp
diff options
context:
space:
mode:
authorRuben Brunk <rubenbrunk@google.com>2015-04-10 17:26:56 -0700
committerRuben Brunk <rubenbrunk@google.com>2015-04-13 16:55:41 -0700
commit4f9576bf48c5909782c12490e8a9faa974ae68d6 (patch)
tree9392dc3ff4216fd7bfa4e41ea7838ec6570bfcf7 /services/camera/libcameraservice/CameraService.cpp
parenta8ca9157d21510fbd474bd31748f4fe0d4635dd7 (diff)
downloadframeworks_av-4f9576bf48c5909782c12490e8a9faa974ae68d6.zip
frameworks_av-4f9576bf48c5909782c12490e8a9faa974ae68d6.tar.gz
frameworks_av-4f9576bf48c5909782c12490e8a9faa974ae68d6.tar.bz2
camera: Fix client eviction/disconnect race.
- Add blocking wait in camera service connect call to prevent race when client has called disconnect while eviction of that client is taking place, resulting in early call of device initialization before all HAL resources are available. Bug: 20038135 Change-Id: I7afc5bfa23612ba7f83293fa542ff983a5991230
Diffstat (limited to 'services/camera/libcameraservice/CameraService.cpp')
-rw-r--r--services/camera/libcameraservice/CameraService.cpp27
1 files changed, 23 insertions, 4 deletions
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index dabfafa..414d563 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -866,7 +866,7 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien
std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
status_t ret = NO_ERROR;
- std::vector<sp<BasicClient>> evictedClients;
+ std::vector<DescriptorPtr> evictedClients;
DescriptorPtr clientDescriptor;
{
if (effectiveApiLevel == API_1) {
@@ -974,7 +974,7 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien
ALOGE("CameraService::connect evicting conflicting client for camera ID %s",
i->getKey().string());
- evictedClients.push_back(clientSp);
+ evictedClients.push_back(i);
// Log the clients evicted
logEvent(String8::format("EVICT device %s client held by package %s (PID"
@@ -1001,12 +1001,31 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien
// Destroy evicted clients
for (auto& i : evictedClients) {
// Disconnect is blocking, and should only have returned when HAL has cleaned up
- i->disconnect(); // Clients will remove themselves from the active client list here
+ i->getValue()->disconnect(); // Clients will remove themselves from the active client list
}
- evictedClients.clear();
IPCThreadState::self()->restoreCallingIdentity(token);
+ for (const auto& i : evictedClients) {
+ ALOGV("%s: Waiting for disconnect to complete for client for device %s (PID %" PRId32 ")",
+ __FUNCTION__, i->getKey().string(), i->getOwnerId());
+ ret = mActiveClientManager.waitUntilRemoved(i, DEFAULT_DISCONNECT_TIMEOUT_NS);
+ if (ret == TIMED_OUT) {
+ ALOGE("%s: Timed out waiting for client for device %s to disconnect, "
+ "current clients:\n%s", __FUNCTION__, i->getKey().string(),
+ mActiveClientManager.toString().string());
+ return -EBUSY;
+ }
+ if (ret != NO_ERROR) {
+ ALOGE("%s: Received error waiting for client for device %s to disconnect: %s (%d), "
+ "current clients:\n%s", __FUNCTION__, i->getKey().string(), strerror(-ret),
+ ret, mActiveClientManager.toString().string());
+ return ret;
+ }
+ }
+
+ evictedClients.clear();
+
// Once clients have been disconnected, relock
mServiceLock.lock();