summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorUmang Jain <email@uajain.com>2020-06-16 19:45:37 +0000
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2020-06-17 00:27:54 +0300
commite9b47217b44cd775498e3fd676be50217d73ad41 (patch)
tree700d6cd04a8c79ab1255849e67a2b750769fecd2 /src
parentdd21ededd0fe9dede5942b0b68c45d43f1d671bd (diff)
libcamera: camera_manager: Introduce signals when a camera is added or removed
Emit 'cameraAdded' and 'cameraRemoved' from CameraManager to enable hotplug and hot-unplug support in application like QCam. To avoid use-after-free race between the CameraManager and the application, emit the 'cameraRemoved' with the shared_ptr version of <Camera *>. This requires to change the function signature of CameraManager::removeCamera() API. Also, until now, CameraManager::Private::addCamera() transfers the entire ownership of camera shared_ptr to CameraManager using std::move(). This patch changes the signature of Private::addCamera to accept pass-by-value camera parameter. It is done to make it clear from the caller point of view that the pointer within the caller will still be valid after this function returns. With this change in, we can emit the camera pointer via 'cameraAdded' signal without hitting a segfault. Signed-off-by: Umang Jain <email@uajain.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src')
-rw-r--r--src/libcamera/camera_manager.cpp38
-rw-r--r--src/libcamera/pipeline_handler.cpp2
2 files changed, 35 insertions, 5 deletions
diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp
index 30827976..f60491d2 100644
--- a/src/libcamera/camera_manager.cpp
+++ b/src/libcamera/camera_manager.cpp
@@ -36,7 +36,7 @@ public:
Private(CameraManager *cm);
int start();
- void addCamera(std::shared_ptr<Camera> &camera,
+ void addCamera(std::shared_ptr<Camera> camera,
const std::vector<dev_t> &devnums);
void removeCamera(Camera *camera);
@@ -171,7 +171,7 @@ void CameraManager::Private::cleanup()
enumerator_.reset(nullptr);
}
-void CameraManager::Private::addCamera(std::shared_ptr<Camera> &camera,
+void CameraManager::Private::addCamera(std::shared_ptr<Camera> camera,
const std::vector<dev_t> &devnums)
{
MutexLocker locker(mutex_);
@@ -375,6 +375,34 @@ std::shared_ptr<Camera> CameraManager::get(dev_t devnum)
}
/**
+ * \var CameraManager::cameraAdded
+ * \brief Notify of a new camera added to the system
+ *
+ * This signal is emitted when a new camera is detected and successfully handled
+ * by the camera manager. The notification occurs alike for cameras detected
+ * when the manager is started with start() or when new cameras are later
+ * connected to the system. When the signal is emitted the new camera is already
+ * available from the list of cameras().
+ *
+ * The signal is emitted from the CameraManager thread. Applications shall
+ * minimize the time spent in the signal handler and shall in particular not
+ * perform any blocking operation.
+ */
+
+/**
+ * \var CameraManager::cameraRemoved
+ * \brief Notify of a new camera removed from the system
+ *
+ * This signal is emitted when a camera is removed from the system. When the
+ * signal is emitted the camera is not available from the list of cameras()
+ * anymore.
+ *
+ * The signal is emitted from the CameraManager thread. Applications shall
+ * minimize the time spent in the signal handler and shall in particular not
+ * perform any blocking operation.
+ */
+
+/**
* \brief Add a camera to the camera manager
* \param[in] camera The camera to be added
* \param[in] devnums The device numbers to associate with \a camera
@@ -394,6 +422,7 @@ void CameraManager::addCamera(std::shared_ptr<Camera> camera,
ASSERT(Thread::current() == p_.get());
p_->addCamera(camera, devnums);
+ cameraAdded.emit(camera);
}
/**
@@ -406,11 +435,12 @@ void CameraManager::addCamera(std::shared_ptr<Camera> camera,
*
* \context This function shall be called from the CameraManager thread.
*/
-void CameraManager::removeCamera(Camera *camera)
+void CameraManager::removeCamera(std::shared_ptr<Camera> camera)
{
ASSERT(Thread::current() == p_.get());
- p_->removeCamera(camera);
+ p_->removeCamera(camera.get());
+ cameraRemoved.emit(camera);
}
/**
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index 38c85779..14dfba0b 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -579,7 +579,7 @@ void PipelineHandler::disconnect()
continue;
camera->disconnect();
- manager_->removeCamera(camera.get());
+ manager_->removeCamera(camera);
}
}