[{"id":23632,"web_url":"https://patchwork.libcamera.org/comment/23632/","msgid":"<98e1f2d7-c63d-e237-3a5f-e048688ba7f2@ideasonboard.com>","date":"2022-06-28T08:09:21","subject":"Re: [libcamera-devel] [PATCH] libcamera: base: thread: Prevent\n\tmessages to thread without an event loop","submitter":{"id":109,"url":"https://patchwork.libcamera.org/api/people/109/","name":"Tomi Valkeinen","email":"tomi.valkeinen@ideasonboard.com"},"content":"On 27/06/2022 19:46, Laurent Pinchart wrote:\n> A message posted to an object bound to a thread without an event loop\n> will never get delivered. This indicates a bug in the caller, and\n> materializes in ways that can be hard to debug, such as a signal never\n> being delivered. Add an assertion in Thread::postMessage() to catch this\n> at the source.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>   src/libcamera/base/thread.cpp | 1 +\n>   1 file changed, 1 insertion(+)\n> \n> diff --git a/src/libcamera/base/thread.cpp b/src/libcamera/base/thread.cpp\n> index 6bda9d1462f5..6ead1d7c12d0 100644\n> --- a/src/libcamera/base/thread.cpp\n> +++ b/src/libcamera/base/thread.cpp\n> @@ -530,6 +530,7 @@ void Thread::postMessage(std::unique_ptr<Message> msg, Object *receiver)\n>   \tmsg->receiver_ = receiver;\n>   \n>   \tASSERT(data_ == receiver->thread()->data_);\n> +\tASSERT(data_ != mainThread.data_);\n>   \n>   \tMutexLocker locker(data_->messages_.mutex_);\n>   \tdata_->messages_.list_.push_back(std::move(msg));\n> \n> base-commit: 27cc0a6b58bcca32071cb6ab96e5ee79c75031e5\n\nSo what was the issue with the code I had? The problem is that \nCameraManager is a libcamera Object, and was associated with the main \nthread...? And a PyCameraManager which doesn't inherit CameraManager is \nnot an Object and not associated with any thread, so it works?\n\n  Tomi","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 26DE9BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 28 Jun 2022 08:09:28 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4D4FF65635;\n\tTue, 28 Jun 2022 10:09:27 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3EFD56559A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Jun 2022 10:09:25 +0200 (CEST)","from [192.168.1.111] (91-158-154-79.elisa-laajakaista.fi\n\t[91.158.154.79])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B66DF55A;\n\tTue, 28 Jun 2022 10:09:24 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656403767;\n\tbh=rSVQicc9TMCMQgnyPmjR+w7Bi4AB3retX+4C/3vJoe8=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=NUAX/D/LMs7Qb2g1DH94YZm1Uc2MJH749/bbEK9f6NMGeoU2vCAYqAQrV7pjRXjfx\n\t87Ppml2ZZJ6b+W3FT354LRwEi2MDp30q+Vuf2uiId2dbJzFbvmGvZEcF03LGLeQRGG\n\tXpKBW8obwKtz2eDFdRcLmW6BDW0Akrf7RVgfPqUxxhW0D7gPm3yGlpuVWU+RXiccuO\n\tTg/tSqfYVmzrNLHOLLqAKuDaZwDpIRBVnSF/ZZWzBHQrsvS/KJhIbr2WRIYJIm8LWK\n\tUm6T1ljGY+qgdevUsiVwbTADapDlMWr0kuUEPZw+LZwxWHkqb/R+zpiDcrNn8h8Etd\n\tzZcuyuZ+PXRQA==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656403764;\n\tbh=rSVQicc9TMCMQgnyPmjR+w7Bi4AB3retX+4C/3vJoe8=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=vmZdhArLJl2n81Pjs0W5QsLtQqWcX3gpWszQwbM1eXPRMPnn1Q8woElOn50hBsN5y\n\tVfeoUviztzMskvaAWITNVIV3jF6e9wAJfmNMs2buxU7cZ9a4a1LaqDIglTa+Pvr04y\n\t9NRGs3mwjBTEfWJJNhmXzNsZzbbrc6+291kOYD+4="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"vmZdhArL\"; dkim-atps=neutral","Message-ID":"<98e1f2d7-c63d-e237-3a5f-e048688ba7f2@ideasonboard.com>","Date":"Tue, 28 Jun 2022 11:09:21 +0300","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101\n\tThunderbird/91.9.1","Content-Language":"en-US","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20220627164612.12049-1-laurent.pinchart@ideasonboard.com>","In-Reply-To":"<20220627164612.12049-1-laurent.pinchart@ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [PATCH] libcamera: base: thread: Prevent\n\tmessages to thread without an event loop","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>","From":"Tomi Valkeinen via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23644,"web_url":"https://patchwork.libcamera.org/comment/23644/","msgid":"<YrrN82vkLFP1khx+@pendragon.ideasonboard.com>","date":"2022-06-28T09:46:27","subject":"Re: [libcamera-devel] [PATCH] libcamera: base: thread: Prevent\n\tmessages to thread without an event loop","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Tue, Jun 28, 2022 at 11:09:21AM +0300, Tomi Valkeinen wrote:\n> On 27/06/2022 19:46, Laurent Pinchart wrote:\n> > A message posted to an object bound to a thread without an event loop\n> > will never get delivered. This indicates a bug in the caller, and\n> > materializes in ways that can be hard to debug, such as a signal never\n> > being delivered. Add an assertion in Thread::postMessage() to catch this\n> > at the source.\n> > \n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> >   src/libcamera/base/thread.cpp | 1 +\n> >   1 file changed, 1 insertion(+)\n> > \n> > diff --git a/src/libcamera/base/thread.cpp b/src/libcamera/base/thread.cpp\n> > index 6bda9d1462f5..6ead1d7c12d0 100644\n> > --- a/src/libcamera/base/thread.cpp\n> > +++ b/src/libcamera/base/thread.cpp\n> > @@ -530,6 +530,7 @@ void Thread::postMessage(std::unique_ptr<Message> msg, Object *receiver)\n> >   \tmsg->receiver_ = receiver;\n> >   \n> >   \tASSERT(data_ == receiver->thread()->data_);\n> > +\tASSERT(data_ != mainThread.data_);\n> >   \n> >   \tMutexLocker locker(data_->messages_.mutex_);\n> >   \tdata_->messages_.list_.push_back(std::move(msg));\n> > \n> > base-commit: 27cc0a6b58bcca32071cb6ab96e5ee79c75031e5\n> \n> So what was the issue with the code I had? The problem is that \n> CameraManager is a libcamera Object, and was associated with the main \n> thread...? And a PyCameraManager which doesn't inherit CameraManager is \n> not an Object and not associated with any thread, so it works?\n\nThat's right. Because PyCameraManager inherited from Object, it\nautomatically got support for queued signal delivery, where a signal\nemitted in one thread would be processed in a different thread. This\nmechanism requires the receiving object to be bound to a thread that has\nan event loop managed by libcamera. By default an Object is bound to the\nthread it's created in.\n\nThe CameraManager is created in the Python main thread, and the signal\nis emitted from an internal libcamera thread. The signal will thus be\nqueued (the default connection type is Auto, which means that signals\nare delivered directly if the receiver object is bound to the thread\nthat the signal is emitted from, or queued otherwise), which queues a\nmessage for the receiver's thread event loop. As the receiver thread is\nthe Python main thread (the application thread from a libcamera point of\nview), which doesn't have a libcamera event loop, the message is never\nprocessed.\n\nIf the receiver doesn't inherit from the Object class, then the signal\nwill be delivered directly, in the emitter's thread. You can achieve the\nsame result with an Object receiver by specifying the direct connection\ntype when connecting the signal.","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 55378BD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 28 Jun 2022 09:46:49 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B497A65632;\n\tTue, 28 Jun 2022 11:46:48 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 525916559A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Jun 2022 11:46:47 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B75834A8;\n\tTue, 28 Jun 2022 11:46:46 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656409608;\n\tbh=eGXIx+CWiI4JvghA5cWRggPEy7INUnfK3wpsluOhJA8=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=nFn/6X0dzq0fpViLVmxJRlaeOoku2spViyVzXGj6rPLn4R+aj/tX+Td2JEnrP8KXm\n\tGWQyu2S/jLqjIVwXPylpNwS30YD2bPhnwu+D/QRASXTXqtB6rW6fbSfpjJaDrzfwgE\n\tcvCjM0JbYuoXZsXFGmWhw8GY7xru5MGqh6u2LzAHjA2HJ6uq5jd2Yt9LLTgJtaJ/vk\n\tJVqNmAPJTo9WNTQGIXtpq04rwuHcAP/+hltnZeEP2ZvFWcvBPFRaxLpf1DAIBsqzge\n\tzeD5vBioqddPcSP+WmFk5CfIxaXjxG9x/YIRgIMDWlmyX3VlZ0mqHwVcnrZ/QtXkNL\n\tTeYvX8vXqAZ5g==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656409606;\n\tbh=eGXIx+CWiI4JvghA5cWRggPEy7INUnfK3wpsluOhJA8=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=A08628gw0kfPV0OVvIvT/syRRXGgJ6wrxMYrLyTy5vhCrZXKhP3D2R3Ef569ldFVU\n\tswNN6X6Ii05/XVtldLwzf4CLzObo7uV63eOuOgvcHG7s+611gwK4N0OsRw4K5qJWX8\n\ttBYTODdppkCXEVr/XjEvl5FVhSHH11MRzaPgK4Ec="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"A08628gw\"; dkim-atps=neutral","Date":"Tue, 28 Jun 2022 12:46:27 +0300","To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Message-ID":"<YrrN82vkLFP1khx+@pendragon.ideasonboard.com>","References":"<20220627164612.12049-1-laurent.pinchart@ideasonboard.com>\n\t<98e1f2d7-c63d-e237-3a5f-e048688ba7f2@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<98e1f2d7-c63d-e237-3a5f-e048688ba7f2@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH] libcamera: base: thread: Prevent\n\tmessages to thread without an event loop","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>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":25322,"web_url":"https://patchwork.libcamera.org/comment/25322/","msgid":"<Yz9hi4mzJL0qOHY+@pendragon.ideasonboard.com>","date":"2022-10-06T23:15:23","subject":"Re: [libcamera-devel] [PATCH] libcamera: base: thread: Prevent\n\tmessages to thread without an event loop","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Ping for review.\n\nOn Tue, Jun 28, 2022 at 12:46:27PM +0300, Laurent Pinchart via libcamera-devel wrote:\n> On Tue, Jun 28, 2022 at 11:09:21AM +0300, Tomi Valkeinen wrote:\n> > On 27/06/2022 19:46, Laurent Pinchart wrote:\n> > > A message posted to an object bound to a thread without an event loop\n> > > will never get delivered. This indicates a bug in the caller, and\n> > > materializes in ways that can be hard to debug, such as a signal never\n> > > being delivered. Add an assertion in Thread::postMessage() to catch this\n> > > at the source.\n> > > \n> > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > > ---\n> > >   src/libcamera/base/thread.cpp | 1 +\n> > >   1 file changed, 1 insertion(+)\n> > > \n> > > diff --git a/src/libcamera/base/thread.cpp b/src/libcamera/base/thread.cpp\n> > > index 6bda9d1462f5..6ead1d7c12d0 100644\n> > > --- a/src/libcamera/base/thread.cpp\n> > > +++ b/src/libcamera/base/thread.cpp\n> > > @@ -530,6 +530,7 @@ void Thread::postMessage(std::unique_ptr<Message> msg, Object *receiver)\n> > >   \tmsg->receiver_ = receiver;\n> > >   \n> > >   \tASSERT(data_ == receiver->thread()->data_);\n> > > +\tASSERT(data_ != mainThread.data_);\n> > >   \n> > >   \tMutexLocker locker(data_->messages_.mutex_);\n> > >   \tdata_->messages_.list_.push_back(std::move(msg));\n> > > \n> > > base-commit: 27cc0a6b58bcca32071cb6ab96e5ee79c75031e5\n> > \n> > So what was the issue with the code I had? The problem is that \n> > CameraManager is a libcamera Object, and was associated with the main \n> > thread...? And a PyCameraManager which doesn't inherit CameraManager is \n> > not an Object and not associated with any thread, so it works?\n> \n> That's right. Because PyCameraManager inherited from Object, it\n> automatically got support for queued signal delivery, where a signal\n> emitted in one thread would be processed in a different thread. This\n> mechanism requires the receiving object to be bound to a thread that has\n> an event loop managed by libcamera. By default an Object is bound to the\n> thread it's created in.\n> \n> The CameraManager is created in the Python main thread, and the signal\n> is emitted from an internal libcamera thread. The signal will thus be\n> queued (the default connection type is Auto, which means that signals\n> are delivered directly if the receiver object is bound to the thread\n> that the signal is emitted from, or queued otherwise), which queues a\n> message for the receiver's thread event loop. As the receiver thread is\n> the Python main thread (the application thread from a libcamera point of\n> view), which doesn't have a libcamera event loop, the message is never\n> processed.\n> \n> If the receiver doesn't inherit from the Object class, then the signal\n> will be delivered directly, in the emitter's thread. You can achieve the\n> same result with an Object receiver by specifying the direct connection\n> type when connecting the signal.","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 6FDE5C0DA4\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu,  6 Oct 2022 23:15:32 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id BA46662D05;\n\tFri,  7 Oct 2022 01:15:31 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 92572603D7\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri,  7 Oct 2022 01:15:29 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E94D96D6;\n\tFri,  7 Oct 2022 01:15:28 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1665098131;\n\tbh=DNXaiokyZ91acDm1zWzPPJ/036xjEvVxRNP7PFHktVY=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=njXA2hYzfRPnbR0HKYVnok8ct/mQ4iLU7YkGARl0KqsbToToTpxKhpmCfRdLo8KKp\n\t6QWhqe9nW8nTMgOHutBdmx5Uk9AFvOnWNgq1rLTeafwaVI4CSLoNRxq9HCxWOUcfFK\n\tS2zWyVvdt8Xac/g8aR8JnFx6JHRfvVImiCqRZUTIscvejSH+/u3Zu+e82a6FzKlHoA\n\tVLOfqUwQA/73cRXCfD3+hv500EC2oA0x+D9NvMNQscJDfg8f9rEZlq58sm0sHWgTEI\n\teDVy4oTrtsbj0qlzddIJ81d69zakTWG810jE3Fathq2ebWIbk94uGreNzVAzHX3rbF\n\tUs8UCJhggzK1w==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1665098129;\n\tbh=DNXaiokyZ91acDm1zWzPPJ/036xjEvVxRNP7PFHktVY=;\n\th=Date:From:To:Subject:References:In-Reply-To:From;\n\tb=gcoPYzTlyhNSepE2bmUx9NJYi/PnTWpDcJq94i2OOX0I/eGDfWVsJNPOo1R8Lvi/x\n\t1e1K4PdiWJClnC8TTvXvBLHR00E6h9vA5EJOOSJ76nm5H6M0kEuvLKX2ag34ockCkN\n\tKwQ4dVEOj0TxazNOJtQYOdYjCCDzildjWbH0AErw="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"gcoPYzTl\"; dkim-atps=neutral","Date":"Fri, 7 Oct 2022 02:15:23 +0300","To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Message-ID":"<Yz9hi4mzJL0qOHY+@pendragon.ideasonboard.com>","References":"<20220627164612.12049-1-laurent.pinchart@ideasonboard.com>\n\t<98e1f2d7-c63d-e237-3a5f-e048688ba7f2@ideasonboard.com>\n\t<YrrN82vkLFP1khx+@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<YrrN82vkLFP1khx+@pendragon.ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH] libcamera: base: thread: Prevent\n\tmessages to thread without an event loop","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>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":25324,"web_url":"https://patchwork.libcamera.org/comment/25324/","msgid":"<fb626220-441f-626b-e832-106254f10fc4@ideasonboard.com>","date":"2022-10-07T09:42:12","subject":"Re: [libcamera-devel] [PATCH] libcamera: base: thread: Prevent\n\tmessages to thread without an event loop","submitter":{"id":86,"url":"https://patchwork.libcamera.org/api/people/86/","name":"Umang Jain","email":"umang.jain@ideasonboard.com"},"content":"Hi Laurent,\n\nThank you for the explanation.\n\nNeed few clarifications below\n\nOn 6/28/22 3:16 PM, Laurent Pinchart via libcamera-devel wrote:\n> On Tue, Jun 28, 2022 at 11:09:21AM +0300, Tomi Valkeinen wrote:\n>> On 27/06/2022 19:46, Laurent Pinchart wrote:\n>>> A message posted to an object bound to a thread without an event loop\n>>> will never get delivered. This indicates a bug in the caller, and\n>>> materializes in ways that can be hard to debug, such as a signal never\n>>> being delivered. Add an assertion in Thread::postMessage() to catch this\n>>> at the source.\n>>>\n>>> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>>> ---\n>>>    src/libcamera/base/thread.cpp | 1 +\n>>>    1 file changed, 1 insertion(+)\n>>>\n>>> diff --git a/src/libcamera/base/thread.cpp b/src/libcamera/base/thread.cpp\n>>> index 6bda9d1462f5..6ead1d7c12d0 100644\n>>> --- a/src/libcamera/base/thread.cpp\n>>> +++ b/src/libcamera/base/thread.cpp\n>>> @@ -530,6 +530,7 @@ void Thread::postMessage(std::unique_ptr<Message> msg, Object *receiver)\n>>>    \tmsg->receiver_ = receiver;\n>>>    \n>>>    \tASSERT(data_ == receiver->thread()->data_);\n>>> +\tASSERT(data_ != mainThread.data_);\n\nSimply reading the commit message and inferring, the first change I \nexpected was on the lines;\n         ASSERT (data_->dispatcher_ != nullptr)\n\nor for readability,\n\n   \tASSERT(receiver->thread()->data_->dispatcher_ != nullptr);\n\n\nthat is, checking the receiver's thread event loop exists or not.\n>>>    \n>>>    \tMutexLocker locker(data_->messages_.mutex_);\n>>>    \tdata_->messages_.list_.push_back(std::move(msg));\n>>>\n>>> base-commit: 27cc0a6b58bcca32071cb6ab96e5ee79c75031e5\n>> So what was the issue with the code I had? The problem is that\n>> CameraManager is a libcamera Object, and was associated with the main\n>> thread...? And a PyCameraManager which doesn't inherit CameraManager is\n>> not an Object and not associated with any thread, so it works?\n> That's right. Because PyCameraManager inherited from Object, it\n> automatically got support for queued signal delivery, where a signal\n> emitted in one thread would be processed in a different thread. This\n> mechanism requires the receiving object to be bound to a thread that has\n> an event loop managed by libcamera. By default an Object is bound to the\n> thread it's created in.\n>\n> The CameraManager is created in the Python main thread, and the signal\n> is emitted from an internal libcamera thread. The signal will thus be\n> queued (the default connection type is Auto, which means that signals\n> are delivered directly if the receiver object is bound to the thread\n> that the signal is emitted from, or queued otherwise), which queues a\n> message for the receiver's thread event loop. As the receiver thread is\n> the Python main thread (the application thread from a libcamera point of\n> view), which doesn't have a libcamera event loop, the message is never\n> processed.\n\nI understand the explanation above.\n\nHowever I'm a bit lost with mainThread static variable. Am I right to \ninfer that the mainThread is the Python's main thread in this case? If \nyes, the patch is correct, refraining the messages to be posted to a \nobject whose threads has no event loop.\n\nHowever, how about if the mainThread inherits from libcamera (hence \nObject, Thread, Signal delivery is in place) but tries to send a message \nto another Object bound to itself (i.e. mainThread)\nWon't the assertion in this patch fail ?\n\n> If the receiver doesn't inherit from the Object class, then the signal\n> will be delivered directly, in the emitter's thread. You can achieve the\n> same result with an Object receiver by specifying the direct connection\n> type when connecting the signal.\n>","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 2A599C0DA4\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri,  7 Oct 2022 09:42:20 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 7B7D662D0A;\n\tFri,  7 Oct 2022 11:42:19 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0F53760AC2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri,  7 Oct 2022 11:42:18 +0200 (CEST)","from [192.168.1.103] (unknown [103.251.226.3])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 842504D3;\n\tFri,  7 Oct 2022 11:42:16 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1665135739;\n\tbh=YNSy/7CuuiPmHT0X1bOqzqBztFgEbt+TFikKKCeJWuQ=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=tQvKBz4RBJ3cUfE06hgr9RhIkEGPgW9tieSfvBP0vyWpVIpPVQ03/RePVTr/11XSI\n\tReVs6DGkim86gNLwoScC34XS4VFte8WTkZVl+7ghjg6JHMDpJ1LUMznbW52XdhXvYY\n\tGvsCQpdgpv+o9lCTpKo2mbWTvwUNRUwLOKeM7MYig3cQBb/3EuRTb2ZpgtQ6wqfGa9\n\tAMPEKLBnx8SAgO/t1mylEeRV/Zs/5qRsz1f+85z5jBbeR/SfU4yVsUv10cRkClPDGs\n\tYk25ehAto6hAJGk9banhL9TONuALKQ2+gD7FAF/YiE/0oBofEAVQwtGIO3eXSrgI/S\n\tSEWnaChHk08Wg==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1665135737;\n\tbh=YNSy/7CuuiPmHT0X1bOqzqBztFgEbt+TFikKKCeJWuQ=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=Wwqa/nrwLTEJCV5sImRr255KE8wu6Jy90oksCA9ieRLBS6kP9DTlPbaADJH2sgway\n\ta/o5GE9IwUCk7RniWsxtlY9FZ9JcVn0g2G1PrjFuWKWW79Vs6zkqyxjivPYXOrgwG0\n\tR7vIkthg0S6oWUtWgI4+EqCaWrvjG0XP5513DdmQ="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"Wwqa/nrw\"; dkim-atps=neutral","Message-ID":"<fb626220-441f-626b-e832-106254f10fc4@ideasonboard.com>","Date":"Fri, 7 Oct 2022 15:12:12 +0530","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101\n\tThunderbird/102.2.1","Content-Language":"en-US","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tTomi Valkeinen <tomi.valkeinen@ideasonboard.com>","References":"<20220627164612.12049-1-laurent.pinchart@ideasonboard.com>\n\t<98e1f2d7-c63d-e237-3a5f-e048688ba7f2@ideasonboard.com>\n\t<YrrN82vkLFP1khx+@pendragon.ideasonboard.com>","In-Reply-To":"<YrrN82vkLFP1khx+@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","Subject":"Re: [libcamera-devel] [PATCH] libcamera: base: thread: Prevent\n\tmessages to thread without an event loop","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>","From":"Umang Jain via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"Umang Jain <umang.jain@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":25325,"web_url":"https://patchwork.libcamera.org/comment/25325/","msgid":"<2458a505-c7c1-8d66-05f3-61d33d550949@ideasonboard.com>","date":"2022-10-07T11:54:48","subject":"Re: [libcamera-devel] [PATCH] libcamera: base: thread: Prevent\n\tmessages to thread without an event loop","submitter":{"id":86,"url":"https://patchwork.libcamera.org/api/people/86/","name":"Umang Jain","email":"umang.jain@ideasonboard.com"},"content":"Hi,\n\nOn 10/7/22 3:12 PM, Umang Jain via libcamera-devel wrote:\n> Hi Laurent,\n>\n> Thank you for the explanation.\n>\n> Need few clarifications below\n>\n> On 6/28/22 3:16 PM, Laurent Pinchart via libcamera-devel wrote:\n>> On Tue, Jun 28, 2022 at 11:09:21AM +0300, Tomi Valkeinen wrote:\n>>> On 27/06/2022 19:46, Laurent Pinchart wrote:\n>>>> A message posted to an object bound to a thread without an event loop\n>>>> will never get delivered. This indicates a bug in the caller, and\n>>>> materializes in ways that can be hard to debug, such as a signal never\n>>>> being delivered. Add an assertion in Thread::postMessage() to catch \n>>>> this\n>>>> at the source.\n>>>>\n>>>> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>>>> ---\n>>>>    src/libcamera/base/thread.cpp | 1 +\n>>>>    1 file changed, 1 insertion(+)\n>>>>\n>>>> diff --git a/src/libcamera/base/thread.cpp \n>>>> b/src/libcamera/base/thread.cpp\n>>>> index 6bda9d1462f5..6ead1d7c12d0 100644\n>>>> --- a/src/libcamera/base/thread.cpp\n>>>> +++ b/src/libcamera/base/thread.cpp\n>>>> @@ -530,6 +530,7 @@ void \n>>>> Thread::postMessage(std::unique_ptr<Message> msg, Object *receiver)\n>>>>        msg->receiver_ = receiver;\n>>>>           ASSERT(data_ == receiver->thread()->data_);\n>>>> +    ASSERT(data_ != mainThread.data_);\n>\n> Simply reading the commit message and inferring, the first change I \n> expected was on the lines;\n>         ASSERT (data_->dispatcher_ != nullptr)\n>\n> or for readability,\n>\n>       ASSERT(receiver->thread()->data_->dispatcher_ != nullptr);\n>\n>\n> that is, checking the receiver's thread event loop exists or not.\n>>>>           MutexLocker locker(data_->messages_.mutex_);\n>>>>        data_->messages_.list_.push_back(std::move(msg));\n>>>>\n>>>> base-commit: 27cc0a6b58bcca32071cb6ab96e5ee79c75031e5\n>>> So what was the issue with the code I had? The problem is that\n>>> CameraManager is a libcamera Object, and was associated with the main\n>>> thread...? And a PyCameraManager which doesn't inherit CameraManager is\n>>> not an Object and not associated with any thread, so it works?\n>> That's right. Because PyCameraManager inherited from Object, it\n>> automatically got support for queued signal delivery, where a signal\n>> emitted in one thread would be processed in a different thread. This\n>> mechanism requires the receiving object to be bound to a thread that has\n>> an event loop managed by libcamera. By default an Object is bound to the\n>> thread it's created in.\n>>\n>> The CameraManager is created in the Python main thread, and the signal\n>> is emitted from an internal libcamera thread. The signal will thus be\n>> queued (the default connection type is Auto, which means that signals\n>> are delivered directly if the receiver object is bound to the thread\n>> that the signal is emitted from, or queued otherwise), which queues a\n>> message for the receiver's thread event loop. As the receiver thread is\n>> the Python main thread (the application thread from a libcamera point of\n>> view), which doesn't have a libcamera event loop, the message is never\n>> processed.\n>\n> I understand the explanation above.\n>\n> However I'm a bit lost with mainThread static variable. Am I right to \n> infer that the mainThread is the Python's main thread in this case? If \n> yes, the patch is correct, refraining the messages to be posted to a \n> object whose threads has no event loop.\n>\n> However, how about if the mainThread inherits from libcamera (hence \n> Object, Thread, Signal delivery is in place) but tries to send a \n> message to another Object bound to itself (i.e. mainThread)\n> Won't the assertion in this patch fail ?\n\nRan the test suite with this patch and saw 3 failures\n\n66/71 libcamera / timer-thread FAIL           15.52s   killed by signal \n6 SIGABRT\n67/71 libcamera / event-thread FAIL           23.13s   killed by signal \n6 SIGABRT\n68/71 libcamera / object-invoke FAIL           23.99s   killed by signal \n6 SIGABRT\n69/71 libcamera / object-delete TIMEOUT        30.02s   killed by signal \n15 SIGTERM\n\nAll triggering the assertion.\n>\n>> If the receiver doesn't inherit from the Object class, then the signal\n>> will be delivered directly, in the emitter's thread. You can achieve the\n>> same result with an Object receiver by specifying the direct connection\n>> type when connecting the signal.\n>>\n>","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 031FBBD16B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri,  7 Oct 2022 11:54:58 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2BBF462D0A;\n\tFri,  7 Oct 2022 13:54:57 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 59E2360A88\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri,  7 Oct 2022 13:54:55 +0200 (CEST)","from [192.168.1.103] (unknown [103.251.226.3])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 9EFB8BBE;\n\tFri,  7 Oct 2022 13:54:53 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1665143697;\n\tbh=vYgpxCwfNd4z4AGjAtIL9XKytaBeVo6XuXKcWah0hdA=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=S+bVWY534MbOnbZwSa/ud+5Ib43aFGZRkqGVSQnBPiNg2KQ6+y7zSxQV4zROgb1td\n\txpE5v5oMuCjdbIhIa3qHARjTjAAAZvzfgZm1fc8PcVUkH4Cx4kHjQdukbJHCLthZK+\n\tjKioeWNvuVTiryV9NuZZofK6W8J3VBZGXzIjZkyQRP1BatItzUzaqv+37IulJpRIEE\n\tmOpFuQ9nQdZ0R9XTi2Pw9xKJW6A+mmAibPTZu7dadQj2vmdTcEGMM5Ys7O6Bzx1G05\n\tbog7PF7TehCOsFmN3pm9Pz0IWhJopdmgZBfoBBLbv6ug/SFNHWePheKzSut9M5Mhq1\n\ti2CPun3OGDS2A==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1665143694;\n\tbh=vYgpxCwfNd4z4AGjAtIL9XKytaBeVo6XuXKcWah0hdA=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=hxcDQ8LJU32SaI4bejAI583HqPIHaQBNNal2yNLGt3lp5IIeKedO76TnmER8zGA9G\n\tyl7COuxkFOR60nVO5uJL/VmZBnifHz2wy2g2q2AhSRLNRuFGf236ayg1UUd6fc03ly\n\tBJrVM7IG+tbF0oVYUUnKRlpk/dqUY7AzxEepteRQ="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"hxcDQ8LJ\"; dkim-atps=neutral","Message-ID":"<2458a505-c7c1-8d66-05f3-61d33d550949@ideasonboard.com>","Date":"Fri, 7 Oct 2022 17:24:48 +0530","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101\n\tThunderbird/102.2.1","Content-Language":"en-US","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tTomi Valkeinen <tomi.valkeinen@ideasonboard.com>","References":"<20220627164612.12049-1-laurent.pinchart@ideasonboard.com>\n\t<98e1f2d7-c63d-e237-3a5f-e048688ba7f2@ideasonboard.com>\n\t<YrrN82vkLFP1khx+@pendragon.ideasonboard.com>\n\t<fb626220-441f-626b-e832-106254f10fc4@ideasonboard.com>","In-Reply-To":"<fb626220-441f-626b-e832-106254f10fc4@ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","Subject":"Re: [libcamera-devel] [PATCH] libcamera: base: thread: Prevent\n\tmessages to thread without an event loop","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>","From":"Umang Jain via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"Umang Jain <umang.jain@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":27648,"web_url":"https://patchwork.libcamera.org/comment/27648/","msgid":"<20230801143428.GA3404@pendragon.ideasonboard.com>","date":"2023-08-01T14:34:28","subject":"Re: [libcamera-devel] [PATCH] libcamera: base: thread: Prevent\n\tmessages to thread without an event loop","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Fri, Oct 07, 2022 at 05:24:48PM +0530, Umang Jain wrote:\n> On 10/7/22 3:12 PM, Umang Jain via libcamera-devel wrote:\n> > Hi Laurent,\n> >\n> > Thank you for the explanation.\n> >\n> > Need few clarifications below\n> >\n> > On 6/28/22 3:16 PM, Laurent Pinchart via libcamera-devel wrote:\n> >> On Tue, Jun 28, 2022 at 11:09:21AM +0300, Tomi Valkeinen wrote:\n> >>> On 27/06/2022 19:46, Laurent Pinchart wrote:\n> >>>> A message posted to an object bound to a thread without an event loop\n> >>>> will never get delivered. This indicates a bug in the caller, and\n> >>>> materializes in ways that can be hard to debug, such as a signal never\n> >>>> being delivered. Add an assertion in Thread::postMessage() to catch \n> >>>> this\n> >>>> at the source.\n> >>>>\n> >>>> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> >>>> ---\n> >>>>    src/libcamera/base/thread.cpp | 1 +\n> >>>>    1 file changed, 1 insertion(+)\n> >>>>\n> >>>> diff --git a/src/libcamera/base/thread.cpp b/src/libcamera/base/thread.cpp\n> >>>> index 6bda9d1462f5..6ead1d7c12d0 100644\n> >>>> --- a/src/libcamera/base/thread.cpp\n> >>>> +++ b/src/libcamera/base/thread.cpp\n> >>>> @@ -530,6 +530,7 @@ void Thread::postMessage(std::unique_ptr<Message> msg, Object *receiver)\n> >>>>  \tmsg->receiver_ = receiver;\n> >>>>\n> >>>>  \tASSERT(data_ == receiver->thread()->data_);\n> >>>> +\tASSERT(data_ != mainThread.data_);\n> >\n> > Simply reading the commit message and inferring, the first change I \n> > expected was on the lines;\n> >\n> >         ASSERT (data_->dispatcher_ != nullptr)\n> >\n> > or for readability,\n> >\n> >       ASSERT(receiver->thread()->data_->dispatcher_ != nullptr);\n> >\n> > that is, checking the receiver's thread event loop exists or not.\n\nThat should work too, but it's longer, and would require accessing the\ndispatcher with the right atomic operation.\n\n> >>>>  \t MutexLocker locker(data_->messages_.mutex_);\n> >>>>  \tdata_->messages_.list_.push_back(std::move(msg));\n> >>>>\n> >>>> base-commit: 27cc0a6b58bcca32071cb6ab96e5ee79c75031e5\n> >>>\n> >>> So what was the issue with the code I had? The problem is that\n> >>> CameraManager is a libcamera Object, and was associated with the main\n> >>> thread...? And a PyCameraManager which doesn't inherit CameraManager is\n> >>> not an Object and not associated with any thread, so it works?\n> >>\n> >> That's right. Because PyCameraManager inherited from Object, it\n> >> automatically got support for queued signal delivery, where a signal\n> >> emitted in one thread would be processed in a different thread. This\n> >> mechanism requires the receiving object to be bound to a thread that has\n> >> an event loop managed by libcamera. By default an Object is bound to the\n> >> thread it's created in.\n> >>\n> >> The CameraManager is created in the Python main thread, and the signal\n> >> is emitted from an internal libcamera thread. The signal will thus be\n> >> queued (the default connection type is Auto, which means that signals\n> >> are delivered directly if the receiver object is bound to the thread\n> >> that the signal is emitted from, or queued otherwise), which queues a\n> >> message for the receiver's thread event loop. As the receiver thread is\n> >> the Python main thread (the application thread from a libcamera point of\n> >> view), which doesn't have a libcamera event loop, the message is never\n> >> processed.\n> >\n> > I understand the explanation above.\n> >\n> > However I'm a bit lost with mainThread static variable. Am I right to \n> > infer that the mainThread is the Python's main thread in this case? If \n> > yes, the patch is correct, refraining the messages to be posted to a \n> > object whose threads has no event loop.\n\nmainThread was initially designed as the Thread instance for the\napplication's main thread. It is in practice used to represent any of\nthe threads that are not under libcamera's control. This should\neventually be improved, as all those threads will be identified by the\nsame thread ID in log messages (see how ThreadData::current() assigns\nmainThread.data_ to currentThreadData, and sets the tid_ there).\n\n> > However, how about if the mainThread inherits from libcamera (hence \n> > Object, Thread, Signal delivery is in place) but tries to send a \n> > message to another Object bound to itself (i.e. mainThread)\n> > Won't the assertion in this patch fail ?\n\nThe \"main\" thread, from a C++ point of view, is the one that runs\nmain(), and by definition this can't inherit from the Thread class.\n\n> Ran the test suite with this patch and saw 3 failures\n> \n> 66/71 libcamera / timer-thread FAIL           15.52s   killed by signal 6 SIGABRT\n> 67/71 libcamera / event-thread FAIL           23.13s   killed by signal 6 SIGABRT\n> 68/71 libcamera / object-invoke FAIL          23.99s   killed by signal 6 SIGABRT\n> 69/71 libcamera / object-delete TIMEOUT       30.02s   killed by signal 15 SIGTERM\n> \n> All triggering the assertion.\n\n:-( Those tests really abuse the API. I'll see if I can fix them.\n\n> >> If the receiver doesn't inherit from the Object class, then the signal\n> >> will be delivered directly, in the emitter's thread. You can achieve the\n> >> same result with an Object receiver by specifying the direct connection\n> >> type when connecting the signal.","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 53422BDB13\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  1 Aug 2023 14:34:25 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 68818627EB;\n\tTue,  1 Aug 2023 16:34:24 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id A2D5961E1D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  1 Aug 2023 16:34:22 +0200 (CEST)","from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi\n\t[213.243.189.158])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 1D0103D4;\n\tTue,  1 Aug 2023 16:33:19 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1690900464;\n\tbh=1Ygjud5LKoJ+RQz8SiK5V53stUQ1WRYUFhsMICL548c=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=tHYIjbXT+W5wRk3gZZq+PaQa6fZez6pYgSot5ivhKacpsJFyyNhqwpqRoEp7C8h4X\n\t15CGCz5TdcfT0k/BbjBEaXOaY8yOzvJnx9ofBRmnciyKVkKD+9CG4OEd2rVHORbkBk\n\tBZBK9IjzfwilDCrinkerElJTjiPhM5c/3mlcVYDJDRznbak90wTsv5cT83EaAlfxMv\n\trf4efiBJl1SQN0fu4eeyfR84O900APKUZUkQDuFkLZREPIKesmixyJbvxk9kTra8yp\n\t12q3BudXyyzoFbvVG0bJyRNbK+1mHCXRqxPG4K1yKh1BcoPDt/WpsOJxfikJ5RPM9c\n\txxDomeFnkA9HQ==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1690900399;\n\tbh=1Ygjud5LKoJ+RQz8SiK5V53stUQ1WRYUFhsMICL548c=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=bI8ASZ+ZRAPGtt73JSMO0kp6DHcgWuQNtucOMM82yl8vhnPhMgLS9riMAjEnuPt94\n\tGX7FDIXt63Cj0Htq+Cma20eRe7xM7wsil/z3LFiUWSsbvCz1v6M9AZRzLzdtEr5ig6\n\trhdtXrTf4mpaEJtUpKSFeT9RWnB4vmqKPoyiL+Jk="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"bI8ASZ+Z\"; dkim-atps=neutral","Date":"Tue, 1 Aug 2023 17:34:28 +0300","To":"Umang Jain <umang.jain@ideasonboard.com>","Message-ID":"<20230801143428.GA3404@pendragon.ideasonboard.com>","References":"<20220627164612.12049-1-laurent.pinchart@ideasonboard.com>\n\t<98e1f2d7-c63d-e237-3a5f-e048688ba7f2@ideasonboard.com>\n\t<YrrN82vkLFP1khx+@pendragon.ideasonboard.com>\n\t<fb626220-441f-626b-e832-106254f10fc4@ideasonboard.com>\n\t<2458a505-c7c1-8d66-05f3-61d33d550949@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<2458a505-c7c1-8d66-05f3-61d33d550949@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH] libcamera: base: thread: Prevent\n\tmessages to thread without an event loop","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>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]