From patchwork Tue Jan 23 01:12:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19459 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 66702C32C4 for ; Tue, 23 Jan 2024 01:13:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9335A62955; Tue, 23 Jan 2024 02:13:04 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="SetXkB8W"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B185362981 for ; Tue, 23 Jan 2024 02:13:00 +0100 (CET) Received: from pendragon.ideasonboard.com (89-27-53-110.bb.dnainternet.fi [89.27.53.110]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 579661574; Tue, 23 Jan 2024 02:11:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1705972307; bh=yXzNLkAmP8fw3TYEP74DzvSAHQQJcmQkyhNtpFZydJM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SetXkB8Wb28GD/4sS1Cdl1D01jBoC5YQa6EcPKWV2b00sY9kUkAjM2IvgnHPUPKvU o941w1qyrt2fa6uzqCAGKy/y7donBWkmNG74JoWbsdCO9qEfCZfFu8T/5SZLaDGccq i8N6znhNobvgh3cAFNtz71VxrBHigoHmQwhnsGSo= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 11/12] libcamera: object: Document and ensure Object deletion constraints Date: Tue, 23 Jan 2024 03:12:48 +0200 Message-ID: <20240123011249.22716-12-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240123011249.22716-1-laurent.pinchart@ideasonboard.com> References: <20240123011249.22716-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Object instances are meant to be deleted from the thread they are bound to, and this requirement is documented. There are however exceptions to the rule, as threads may be stopped and restarted, with objects bound to them not being deleted and recreated for every stop/restart cycle. Bound objects may therefore need to be deleted after the thread has stopped, making it impossible to use Object::deleteLater(). Document the lifetime requirements more precisely, and enforce them with an assertion. Signed-off-by: Laurent Pinchart Reviewed-by: Milan Zamazal --- src/libcamera/base/object.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/libcamera/base/object.cpp b/src/libcamera/base/object.cpp index 14399d750e03..c6040fc6a78b 100644 --- a/src/libcamera/base/object.cpp +++ b/src/libcamera/base/object.cpp @@ -40,8 +40,9 @@ LOG_DEFINE_CATEGORY(Object) * Object class. * * Deleting an object from a thread other than the one the object is bound to is - * unsafe, unless the caller ensures that the object isn't processing any - * message concurrently. + * unsafe, unless the caller ensures that the object's thread is stopped and no + * parent or child of the object gets deleted concurrently. See + * Object::~Object() for more information. * * Object slots connected to signals will also run in the context of the * object's thread, regardless of whether the signal is emitted in the same or @@ -84,9 +85,20 @@ Object::Object(Object *parent) * Object instances shall be destroyed from the thread they are bound to, * otherwise undefined behaviour may occur. If deletion of an Object needs to * be scheduled from a different thread, deleteLater() shall be used. + * + * As an exception to this rule, Object instances may be deleted from a + * different thread if the thread the instance is bound to is stopped through + * the whole duration of the object's destruction, *and* the parent and children + * of the object do not get deleted concurrently. The caller is responsible for + * fulfilling those requirements. + * + * In all cases Object instances shall be deleted before the Thread they are + * bound to. */ Object::~Object() { + ASSERT(Thread::current() == thread_ || !thread_->isRunning()); + /* * Move signals to a private list to avoid concurrent iteration and * deletion of items from Signal::disconnect().