libcamera: camera_manager: Do not emit signals while holding lock
Both `CameraManager::Private::{add,remove}Camera()` emit the `camera{Added,Removed}` signals, respectively, while holding the lock protecting the list of cameras. This is problematic because if a callback tries to call `cameras()`, then the same (non-recursive) lock would be locked again. Furthermore, there is no real need to hold the lock while user code is running, so release the lock as soon as possible. Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Harvey Yang <chenghaoyang@chromium.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
b3272f7827
commit
d505bd5360
1 changed files with 23 additions and 21 deletions
|
@ -202,24 +202,24 @@ void CameraManager::Private::addCamera(std::shared_ptr<Camera> camera)
|
||||||
{
|
{
|
||||||
ASSERT(Thread::current() == this);
|
ASSERT(Thread::current() == this);
|
||||||
|
|
||||||
MutexLocker locker(mutex_);
|
{
|
||||||
|
MutexLocker locker(mutex_);
|
||||||
|
|
||||||
for (const std::shared_ptr<Camera> &c : cameras_) {
|
for (const std::shared_ptr<Camera> &c : cameras_) {
|
||||||
if (c->id() == camera->id()) {
|
if (c->id() == camera->id()) {
|
||||||
LOG(Camera, Fatal)
|
LOG(Camera, Fatal)
|
||||||
<< "Trying to register a camera with a duplicated ID '"
|
<< "Trying to register a camera with a duplicated ID '"
|
||||||
<< camera->id() << "'";
|
<< camera->id() << "'";
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cameras_.push_back(camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
cameras_.push_back(std::move(camera));
|
|
||||||
|
|
||||||
unsigned int index = cameras_.size() - 1;
|
|
||||||
|
|
||||||
/* Report the addition to the public signal */
|
/* Report the addition to the public signal */
|
||||||
CameraManager *const o = LIBCAMERA_O_PTR();
|
CameraManager *const o = LIBCAMERA_O_PTR();
|
||||||
o->cameraAdded.emit(cameras_[index]);
|
o->cameraAdded.emit(camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -236,20 +236,22 @@ void CameraManager::Private::removeCamera(std::shared_ptr<Camera> camera)
|
||||||
{
|
{
|
||||||
ASSERT(Thread::current() == this);
|
ASSERT(Thread::current() == this);
|
||||||
|
|
||||||
MutexLocker locker(mutex_);
|
{
|
||||||
|
MutexLocker locker(mutex_);
|
||||||
|
|
||||||
auto iter = std::find_if(cameras_.begin(), cameras_.end(),
|
auto iter = std::find_if(cameras_.begin(), cameras_.end(),
|
||||||
[camera](std::shared_ptr<Camera> &c) {
|
[camera](std::shared_ptr<Camera> &c) {
|
||||||
return c.get() == camera.get();
|
return c.get() == camera.get();
|
||||||
});
|
});
|
||||||
if (iter == cameras_.end())
|
if (iter == cameras_.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
cameras_.erase(iter);
|
||||||
|
}
|
||||||
|
|
||||||
LOG(Camera, Debug)
|
LOG(Camera, Debug)
|
||||||
<< "Unregistering camera '" << camera->id() << "'";
|
<< "Unregistering camera '" << camera->id() << "'";
|
||||||
|
|
||||||
cameras_.erase(iter);
|
|
||||||
|
|
||||||
/* Report the removal to the public signal */
|
/* Report the removal to the public signal */
|
||||||
CameraManager *const o = LIBCAMERA_O_PTR();
|
CameraManager *const o = LIBCAMERA_O_PTR();
|
||||||
o->cameraRemoved.emit(camera);
|
o->cameraRemoved.emit(camera);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue