{"id":9122,"url":"https://patchwork.libcamera.org/api/1.1/patches/9122/?format=json","web_url":"https://patchwork.libcamera.org/patch/9122/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/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":"<20200731181410.99892-5-email@uajain.com>","date":"2020-07-31T18:14:20","name":"[libcamera-devel,v4,4/4] libcamera: camera: Ensure deletion via deleteLater()","commit_ref":"f2df5abe5db9da36d4f07192a037acbcda2dee02","pull_url":null,"state":"accepted","archived":false,"hash":"76adf0b1fc2a340921cc567c9b541d639d1abdc5","submitter":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/people/1/?format=json","name":"Umang Jain","email":"email@uajain.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/9122/mbox/","series":[{"id":1172,"url":"https://patchwork.libcamera.org/api/1.1/series/1172/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=1172","date":"2020-07-31T18:14:13","name":"libcamera: object: Add deleteLater() support","version":4,"mbox":"https://patchwork.libcamera.org/series/1172/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/9122/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/9122/checks/","tags":{},"headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 8F5B7BD879\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 31 Jul 2020 18:14:23 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4BDF161F1B;\n\tFri, 31 Jul 2020 20:14:23 +0200 (CEST)","from o1.f.az.sendgrid.net (o1.f.az.sendgrid.net [208.117.55.132])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 991A7611A2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 31 Jul 2020 20:14:21 +0200 (CEST)","by filterdrecv-p3mdw1-7ff865655c-svvjh with SMTP id\n\tfilterdrecv-p3mdw1-7ff865655c-svvjh-19-5F245F7C-4D\n\t2020-07-31 18:14:20.612016378 +0000 UTC m=+172687.713613617","from mail.uajain.com (unknown)\n\tby ismtpd0005p1hnd1.sendgrid.net (SG) with ESMTP\n\tid grWcS78XREGRNAHZ4crFTQ Fri, 31 Jul 2020 18:14:20.177 +0000 (UTC)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=uajain.com header.i=@uajain.com\n\theader.b=\"hdIwWGIg\"; dkim-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=G8aUrpC88hKULTyVG1vQulK2b6B6VEjsFwMbdsHK/YY=;\n\tb=hdIwWGIgkAaT1ISjyCWRbRI9LGb8pNxkXUanp/HHiYMi8sHeEpA7OyreDITTJjX0NArP\n\tZvMNzmdLFUjD/QDzmapZ+OkAkkxIJJG6giCd+6NcitkkFe7QUZQNMJjG2VBjwBLxSUWNw2\n\tVufj8WW8O6x1jcHN5Kf7tmbnsFaC/u0WY=","From":"Umang Jain <email@uajain.com>","Date":"Fri, 31 Jul 2020 18:14:20 +0000 (UTC)","Message-Id":"<20200731181410.99892-5-email@uajain.com>","In-Reply-To":"<20200731181410.99892-1-email@uajain.com>","References":"<20200731181410.99892-1-email@uajain.com>","Mime-Version":"1.0","X-SG-EID":"1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcj9TjcWbOI2k4lJ0fKJaeeyGQUzl0aZlU4nehjRj03/+6xzpI2FEkb70FYM1DwSIZgISXCR0j8IJXDzCROJ0Ix5AxU5khER5WZoxJ47OpOcEyJg7MS3cLo469M1zAho7xfkhluQzEytX8/lB8Wt/RD+LmASzQiSVt7T7+L3ujfLNdw3vxHDVUohfXyJ4BfFV1yMoxFhV0ZesepVGbmmlueA==","To":"libcamera-devel@lists.libcamera.org","Subject":"[libcamera-devel] [PATCH v4 4/4] libcamera: camera: Ensure deletion\n\tvia deleteLater()","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>","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"Object::deleteLater() ensures that the deletion of the Object\ntakes place in a thread it is bound to. Deleting the Object\nin a different thread is a violation according to the libcamera\nthreading model.\n\nOn hot-unplug of a currently streaming camera, the last reference\nof Camera when dropped from the application thread (for e.g. QCam's\nthread), the destructor is then called from this thread. This is not\nallowed by the libcamera threading model. Camera is meant to be deleted\nin the thread it is bound to - in this case the CameraManager's thread.\n\nSigned-off-by: Umang Jain <email@uajain.com>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n include/libcamera/camera.h       | 3 ++-\n src/libcamera/camera.cpp         | 2 +-\n src/libcamera/camera_manager.cpp | 6 +++++-\n 3 files changed, 8 insertions(+), 3 deletions(-)","diff":"diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\nindex 4d1a4a9..7dd23d7 100644\n--- a/include/libcamera/camera.h\n+++ b/include/libcamera/camera.h\n@@ -13,6 +13,7 @@\n #include <string>\n \n #include <libcamera/controls.h>\n+#include <libcamera/object.h>\n #include <libcamera/request.h>\n #include <libcamera/signal.h>\n #include <libcamera/stream.h>\n@@ -66,7 +67,7 @@ protected:\n \tstd::vector<StreamConfiguration> config_;\n };\n \n-class Camera final : public std::enable_shared_from_this<Camera>\n+class Camera final : public Object, public std::enable_shared_from_this<Camera>\n {\n public:\n \tstatic std::shared_ptr<Camera> create(PipelineHandler *pipe,\ndiff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\nindex 69a1b44..034f341 100644\n--- a/src/libcamera/camera.cpp\n+++ b/src/libcamera/camera.cpp\n@@ -464,7 +464,7 @@ std::shared_ptr<Camera> Camera::create(PipelineHandler *pipe,\n \tstruct Deleter : std::default_delete<Camera> {\n \t\tvoid operator()(Camera *camera)\n \t\t{\n-\t\t\tdelete camera;\n+\t\t\tcamera->deleteLater();\n \t\t}\n \t};\n \ndiff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp\nindex f60491d..c45bf33 100644\n--- a/src/libcamera/camera_manager.cpp\n+++ b/src/libcamera/camera_manager.cpp\n@@ -164,9 +164,13 @@ void CameraManager::Private::cleanup()\n \n \t/*\n \t * Release all references to cameras to ensure they all get destroyed\n-\t * before the device enumerator deletes the media devices.\n+\t * before the device enumerator deletes the media devices. Cameras are\n+\t * destroyed via Object::deleteLater() API, hence we need to explicitly\n+\t * process deletion requests from the thread's message queue as the event\n+\t * loop is not in action here.\n \t */\n \tcameras_.clear();\n+\tdispatchMessages(Message::Type::DeferredDelete);\n \n \tenumerator_.reset(nullptr);\n }\n","prefixes":["libcamera-devel","v4","4/4"]}