From patchwork Thu May 21 13:54:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 3833 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 BA68960E08 for ; Thu, 21 May 2020 15:54:26 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=uajain.com header.i=@uajain.com header.b="oMHhjdfs"; 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=Df4ZvtW1VJ32k7ot9799b04IQDgezPZJIKxu8lNrNt0=; b=oMHhjdfszSDQJOBJ+v6OOqo2Onn0nupvBm3g2EO2eZads9pKnZRC60JhYm5SirM9MiAZ hWenV9Mm+QOo1eNByvng+rYXBjsdPXC+x90WqxVvFjIqxInCaqYQwpILGNtboCGTuh+Ti7 84mQub6dELx9qcVooHkW6PZ9vFvorskZQ= Received: by filterdrecv-p3iad2-8ddf98858-xm5rk with SMTP id filterdrecv-p3iad2-8ddf98858-xm5rk-18-5EC68811-11 2020-05-21 13:54:25.414650661 +0000 UTC m=+4807854.394384064 Received: from mail.uajain.com (unknown) by ismtpd0008p1maa1.sendgrid.net (SG) with ESMTP id NWP7hY6pRuS3tH6hTbiaGQ for ; Thu, 21 May 2020 13:54:24.614 +0000 (UTC) From: Umang Jain Date: Thu, 21 May 2020 13:54:25 +0000 (UTC) Message-Id: <20200521135416.13685-4-email@uajain.com> In-Reply-To: <20200521135416.13685-1-email@uajain.com> References: <20200521135416.13685-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcHIuSzkf5/M5SksOT1pntG7QXTTZK2cE1S7jwIaCKrb/mbbypVgSEEUHuO3QBMfxxVazHlquUhRPeV6ihAIwFbVMpYvTr2j+FAYbzl8NFIA3BUZ+j7RkJRsq7H8GO6fLsCVipybfAfgfgqpzG3Kiwlzd7FWFVmconZFxj/RWrP6G9NNqfy9lwXwqj7bAUj65Mp4aYuCEUz96n6qk5xb/nHA== To: libcamera-devel@lists.libcamera.org Subject: [libcamera-devel] [PATCH v3 3/5] libcamera: camera_manager: Introduce signals when a camera is added/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: Thu, 21 May 2020 13:54:27 -0000 Emit 'newCameraAdded' and 'cameraRemoved' from CameraManager to enable hotplug and hot-unplug support in appplication 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. Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart --- include/libcamera/camera_manager.h | 6 ++++- src/libcamera/camera_manager.cpp | 36 +++++++++++++++++++++++++++--- src/libcamera/pipeline_handler.cpp | 2 +- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/include/libcamera/camera_manager.h b/include/libcamera/camera_manager.h index 079f848..365e286 100644 --- a/include/libcamera/camera_manager.h +++ b/include/libcamera/camera_manager.h @@ -13,6 +13,7 @@ #include #include +#include namespace libcamera { @@ -35,13 +36,16 @@ public: std::shared_ptr get(dev_t devnum); void addCamera(std::shared_ptr camera, dev_t devnum); - 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> newCameraAdded; + 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 27064d2..bdd78f5 100644 --- a/src/libcamera/camera_manager.cpp +++ b/src/libcamera/camera_manager.cpp @@ -185,7 +185,7 @@ void CameraManager::Private::addCamera(std::shared_ptr &camera, } } - cameras_.push_back(std::move(camera)); + cameras_.push_back(camera); if (devnum) { unsigned int index = cameras_.size() - 1; @@ -375,6 +375,34 @@ std::shared_ptr CameraManager::get(dev_t devnum) return iter->second.lock(); } +/** + * \var CameraManager::newCameraAdded + * \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, dev_t devnum) ASSERT(Thread::current() == p_.get()); p_->addCamera(camera, devnum); + newCameraAdded.emit(camera); } /** @@ -406,11 +435,12 @@ void CameraManager::addCamera(std::shared_ptr camera, dev_t devnum) * * \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 53aeebd..9a1e6ff 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -555,7 +555,7 @@ void PipelineHandler::disconnect() continue; camera->disconnect(); - manager_->removeCamera(camera.get()); + manager_->removeCamera(camera); } cameras_.clear();