From patchwork Sun Jan 21 03:59:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 19432 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 7F935C32C0 for ; Sun, 21 Jan 2024 04:00:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C74DF62950; Sun, 21 Jan 2024 05:00:06 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1705809606; bh=z0BmluV3+ys9PMdaTdconxWAgym5vmaEG5yZyDHy/JY=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=mUQshlTdBbOxXt9/Smd1UutBnz6RfatQ6z3PnnUdYJxQtSFlBrg1IUBpR+SYpjJel HKLtv2Co6IQ7YNk2Zr8YSpGJRKhJd81oNX754uTiIAV4mVn/zYMysRMBer9b3kxBMV U1iRBCkpjtCdHmabARKpWiXbk5+ahw0vDn8vTOLq6PKzHSQLna8ClLtwdh8izNNgcI IjPBiZX9r5vIgC51pzWf957mHMlWzkzpG6aJk7/Ev/+e1TBguPRftrFPRgx88jp2Pn gjUGoIFlTosIvmb0e1osr7Qc5U5I9EsC++ebefgyiRk4Ii80dDhNOLjICeiKLJWg8P k08wdZMfTZEsw== 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 7FFAE62956 for ; Sun, 21 Jan 2024 05:00:00 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="JVivAXNB"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (89-27-53-110.bb.dnainternet.fi [89.27.53.110]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 64B931574; Sun, 21 Jan 2024 04:58:48 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1705809528; bh=z0BmluV3+ys9PMdaTdconxWAgym5vmaEG5yZyDHy/JY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JVivAXNBa2vCimQqNH+EM2ADe9pJdqZHPqYoYJa3WFzHhWmYcnxT1emcAecFm5AqR m2KVNydz3Tcp224eWOUdniNXamYqQasLNPvUSqCzQWr9FsfV10A4mIC5P24x8MTgKI vZH7p195MjkFFcWs1rpvhfhHfdz0VzMqVohA+HqU= To: libcamera-devel@lists.libcamera.org Date: Sun, 21 Jan 2024 05:59:47 +0200 Message-ID: <20240121035948.4226-12-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240121035948.4226-1-laurent.pinchart@ideasonboard.com> References: <20240121035948.4226-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 11/12] libcamera: object: Document and ensure Object deletion constraints 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-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart 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 1fce5a2af9af..8af0337f5448 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().