From patchwork Tue Jun 16 19:45:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 4068 Return-Path: Received: from o1.f.az.sendgrid.net (o1.f.az.sendgrid.net [208.117.55.132]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8D20761FD1 for ; Tue, 16 Jun 2020 21:45:38 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=uajain.com header.i=@uajain.com header.b="SyAqNdY9"; dkim-atps=neutral DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uajain.com; h=from:subject:in-reply-to:references:mime-version:to:cc: content-transfer-encoding:content-type; s=s1; bh=5fZuCOlOjehHfZWcTYNUUbIdzczRLNu4hqtWf5b/40I=; b=SyAqNdY9OY32QEiTB2nGK/c1x6drnHt1PAXw6mEz6cj4Q5Tr13Hxrb/HNT4Mfhj8U9tI PYjuOeoJEjZHflyUeCW1HiKsP4UMccAUP5swzDI52rQEFbc4YLw0QXo+PNWJjdK1ohaQJw Ez9WdccvJ8vknpURcm/CrFQWT9CDA+FB4= Received: by filter0072p3las1.sendgrid.net with SMTP id filter0072p3las1-4518-5EE92160-12C 2020-06-16 19:45:37.016591458 +0000 UTC m=+696974.774711833 Received: from mail.uajain.com (unknown) by ismtpd0001p1maa1.sendgrid.net (SG) with ESMTP id tZfbyfNcSXSoVVk-cYFJtA Tue, 16 Jun 2020 19:45:36.593 +0000 (UTC) From: Umang Jain Date: Tue, 16 Jun 2020 19:45:37 +0000 (UTC) Message-Id: <20200616194523.23268-5-email@uajain.com> In-Reply-To: <20200616194523.23268-1-email@uajain.com> References: <20200616194523.23268-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPc+BcW/nTZaHvUFD9w8u96rn6USOorH4S8WjFE0sjV2vKQO7b8kniI5IXhu4VpoOlqj8gzD9PuY9u3jLT3eFNtYfcCulN+55dMj3C9Mklmc0hz7NDK7iA0hvNOmj2g1DCZG5BL2HJ2ny4ypNUj81ruSarfc5as1h1ppZBuf+PfMh+VNyo5f5YFizKpT723kOjp To: laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, libcamera-devel@lists.libcamera.org Subject: [libcamera-devel] [PATCH v5 4/6] libcamera: camera_manager: Introduce signals when a camera is added or removed X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Jun 2020 19:45:39 -0000 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 . 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 Reviewed-by: Laurent Pinchart --- include/libcamera/camera_manager.h | 6 ++++- src/libcamera/camera_manager.cpp | 38 ++++++++++++++++++++++++++---- src/libcamera/pipeline_handler.cpp | 2 +- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/include/libcamera/camera_manager.h b/include/libcamera/camera_manager.h index 95dc636..9eb2b6f 100644 --- a/include/libcamera/camera_manager.h +++ b/include/libcamera/camera_manager.h @@ -13,6 +13,7 @@ #include #include +#include namespace libcamera { @@ -36,13 +37,16 @@ public: void addCamera(std::shared_ptr camera, const std::vector &devnums); - void removeCamera(Camera *camera); + void removeCamera(std::shared_ptr camera); static const std::string &version() { return version_; } void setEventDispatcher(std::unique_ptr dispatcher); EventDispatcher *eventDispatcher(); + Signal> cameraAdded; + Signal> cameraRemoved; + private: static const std::string version_; static CameraManager *self_; diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp index 3082797..f60491d 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, + void addCamera(std::shared_ptr camera, const std::vector &devnums); void removeCamera(Camera *camera); @@ -171,7 +171,7 @@ void CameraManager::Private::cleanup() enumerator_.reset(nullptr); } -void CameraManager::Private::addCamera(std::shared_ptr &camera, +void CameraManager::Private::addCamera(std::shared_ptr camera, const std::vector &devnums) { MutexLocker locker(mutex_); @@ -374,6 +374,34 @@ std::shared_ptr CameraManager::get(dev_t devnum) return iter->second.lock(); } +/** + * \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 @@ -394,6 +422,7 @@ void CameraManager::addCamera(std::shared_ptr camera, ASSERT(Thread::current() == p_.get()); p_->addCamera(camera, devnums); + cameraAdded.emit(camera); } /** @@ -406,11 +435,12 @@ void CameraManager::addCamera(std::shared_ptr camera, * * \context This function shall be called from the CameraManager thread. */ -void CameraManager::removeCamera(Camera *camera) +void CameraManager::removeCamera(std::shared_ptr 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 c457be9..0e13790 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); } }