{"id":4068,"url":"https://patchwork.libcamera.org/api/patches/4068/?format=json","web_url":"https://patchwork.libcamera.org/patch/4068/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20200616194523.23268-5-email@uajain.com>","date":"2020-06-16T19:45:37","name":"[libcamera-devel,v5,4/6] libcamera: camera_manager: Introduce signals when a camera is added or removed","commit_ref":"e9b47217b44cd775498e3fd676be50217d73ad41","pull_url":null,"state":"accepted","archived":false,"hash":"2281604bc7f20d5c0a96db4a88b84dc5e23352fc","submitter":{"id":1,"url":"https://patchwork.libcamera.org/api/people/1/?format=json","name":"Umang Jain","email":"email@uajain.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/4068/mbox/","series":[{"id":1009,"url":"https://patchwork.libcamera.org/api/series/1009/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=1009","date":"2020-06-16T19:45:33","name":"Introduce UVC hotplugging support","version":5,"mbox":"https://patchwork.libcamera.org/series/1009/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/4068/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/4068/checks/","tags":{},"headers":{"Return-Path":"<bounces+15657259-5c31-libcamera-devel=lists.libcamera.org@em7280.uajain.com>","Received":["from o1.f.az.sendgrid.net (o1.f.az.sendgrid.net [208.117.55.132])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8D20761FD1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 16 Jun 2020 21:45:38 +0200 (CEST)","by filter0072p3las1.sendgrid.net with SMTP id\n\tfilter0072p3las1-4518-5EE92160-12C\n\t2020-06-16 19:45:37.016591458 +0000 UTC m=+696974.774711833","from mail.uajain.com (unknown)\n\tby ismtpd0001p1maa1.sendgrid.net (SG) with ESMTP\n\tid tZfbyfNcSXSoVVk-cYFJtA Tue, 16 Jun 2020 19:45:36.593 +0000 (UTC)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=uajain.com\n\theader.i=@uajain.com header.b=\"SyAqNdY9\"; \n\tdkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=uajain.com;\n\th=from:subject:in-reply-to:references:mime-version:to:cc:\n\tcontent-transfer-encoding:content-type;\n\ts=s1; bh=5fZuCOlOjehHfZWcTYNUUbIdzczRLNu4hqtWf5b/40I=;\n\tb=SyAqNdY9OY32QEiTB2nGK/c1x6drnHt1PAXw6mEz6cj4Q5Tr13Hxrb/HNT4Mfhj8U9tI\n\tPYjuOeoJEjZHflyUeCW1HiKsP4UMccAUP5swzDI52rQEFbc4YLw0QXo+PNWJjdK1ohaQJw\n\tEz9WdccvJ8vknpURcm/CrFQWT9CDA+FB4=","From":"Umang Jain <email@uajain.com>","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,\n\tlibcamera-devel@lists.libcamera.org","Content-Transfer-Encoding":"7bit","Content-Type":"text/plain; charset=us-ascii","Subject":"[libcamera-devel] [PATCH v5 4/6] libcamera: camera_manager:\n\tIntroduce 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":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Tue, 16 Jun 2020 19:45:39 -0000"},"content":"Emit 'cameraAdded' and 'cameraRemoved' from CameraManager to enable\nhotplug and hot-unplug support in application like QCam.\n\nTo avoid use-after-free race between the CameraManager and the\napplication, emit the 'cameraRemoved' with the shared_ptr version\nof <Camera *>. This requires to change the function signature of\nCameraManager::removeCamera() API.\n\nAlso, until now, CameraManager::Private::addCamera() transfers the\nentire ownership of camera shared_ptr to CameraManager using\nstd::move(). This patch changes the signature of Private::addCamera to\naccept pass-by-value camera parameter. It is done to make it clear from\nthe caller point of view that the pointer within the caller will still\nbe valid after this function returns. With this change in, we can emit\nthe camera pointer via 'cameraAdded' signal without hitting a segfault.\n\nSigned-off-by: Umang Jain <email@uajain.com>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n include/libcamera/camera_manager.h |  6 ++++-\n src/libcamera/camera_manager.cpp   | 38 ++++++++++++++++++++++++++----\n src/libcamera/pipeline_handler.cpp |  2 +-\n 3 files changed, 40 insertions(+), 6 deletions(-)","diff":"diff --git a/include/libcamera/camera_manager.h b/include/libcamera/camera_manager.h\nindex 95dc636..9eb2b6f 100644\n--- a/include/libcamera/camera_manager.h\n+++ b/include/libcamera/camera_manager.h\n@@ -13,6 +13,7 @@\n #include <vector>\n \n #include <libcamera/object.h>\n+#include <libcamera/signal.h>\n \n namespace libcamera {\n \n@@ -36,13 +37,16 @@ public:\n \n \tvoid addCamera(std::shared_ptr<Camera> camera,\n \t\t       const std::vector<dev_t> &devnums);\n-\tvoid removeCamera(Camera *camera);\n+\tvoid removeCamera(std::shared_ptr<Camera> camera);\n \n \tstatic const std::string &version() { return version_; }\n \n \tvoid setEventDispatcher(std::unique_ptr<EventDispatcher> dispatcher);\n \tEventDispatcher *eventDispatcher();\n \n+\tSignal<std::shared_ptr<Camera>> cameraAdded;\n+\tSignal<std::shared_ptr<Camera>> cameraRemoved;\n+\n private:\n \tstatic const std::string version_;\n \tstatic CameraManager *self_;\ndiff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp\nindex 3082797..f60491d 100644\n--- a/src/libcamera/camera_manager.cpp\n+++ b/src/libcamera/camera_manager.cpp\n@@ -36,7 +36,7 @@ public:\n \tPrivate(CameraManager *cm);\n \n \tint start();\n-\tvoid addCamera(std::shared_ptr<Camera> &camera,\n+\tvoid addCamera(std::shared_ptr<Camera> camera,\n \t\t       const std::vector<dev_t> &devnums);\n \tvoid removeCamera(Camera *camera);\n \n@@ -171,7 +171,7 @@ void CameraManager::Private::cleanup()\n \tenumerator_.reset(nullptr);\n }\n \n-void CameraManager::Private::addCamera(std::shared_ptr<Camera> &camera,\n+void CameraManager::Private::addCamera(std::shared_ptr<Camera> camera,\n \t\t\t\t       const std::vector<dev_t> &devnums)\n {\n \tMutexLocker locker(mutex_);\n@@ -374,6 +374,34 @@ std::shared_ptr<Camera> CameraManager::get(dev_t devnum)\n \treturn iter->second.lock();\n }\n \n+/**\n+ * \\var CameraManager::cameraAdded\n+ * \\brief Notify of a new camera added to the system\n+ *\n+ * This signal is emitted when a new camera is detected and successfully handled\n+ * by the camera manager. The notification occurs alike for cameras detected\n+ * when the manager is started with start() or when new cameras are later\n+ * connected to the system. When the signal is emitted the new camera is already\n+ * available from the list of cameras().\n+ *\n+ * The signal is emitted from the CameraManager thread. Applications shall\n+ * minimize the time spent in the signal handler and shall in particular not\n+ * perform any blocking operation.\n+ */\n+\n+/**\n+ * \\var CameraManager::cameraRemoved\n+ * \\brief Notify of a new camera removed from the system\n+ *\n+ * This signal is emitted when a camera is removed from the system. When the\n+ * signal is emitted the camera is not available from the list of cameras()\n+ * anymore.\n+ *\n+ * The signal is emitted from the CameraManager thread. Applications shall\n+ * minimize the time spent in the signal handler and shall in particular not\n+ * perform any blocking operation.\n+ */\n+\n /**\n  * \\brief Add a camera to the camera manager\n  * \\param[in] camera The camera to be added\n@@ -394,6 +422,7 @@ void CameraManager::addCamera(std::shared_ptr<Camera> camera,\n \tASSERT(Thread::current() == p_.get());\n \n \tp_->addCamera(camera, devnums);\n+\tcameraAdded.emit(camera);\n }\n \n /**\n@@ -406,11 +435,12 @@ void CameraManager::addCamera(std::shared_ptr<Camera> camera,\n  *\n  * \\context This function shall be called from the CameraManager thread.\n  */\n-void CameraManager::removeCamera(Camera *camera)\n+void CameraManager::removeCamera(std::shared_ptr<Camera> camera)\n {\n \tASSERT(Thread::current() == p_.get());\n \n-\tp_->removeCamera(camera);\n+\tp_->removeCamera(camera.get());\n+\tcameraRemoved.emit(camera);\n }\n \n /**\ndiff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp\nindex c457be9..0e13790 100644\n--- a/src/libcamera/pipeline_handler.cpp\n+++ b/src/libcamera/pipeline_handler.cpp\n@@ -579,7 +579,7 @@ void PipelineHandler::disconnect()\n \t\t\tcontinue;\n \n \t\tcamera->disconnect();\n-\t\tmanager_->removeCamera(camera.get());\n+\t\tmanager_->removeCamera(camera);\n \t}\n }\n \n","prefixes":["libcamera-devel","v5","4/6"]}