From patchwork Mon Oct 3 23:58:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 17519 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 906A9C0DA4 for ; Mon, 3 Oct 2022 23:58:48 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EB2AE603F6; Tue, 4 Oct 2022 01:58:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1664841527; bh=0XfW4UVqEqzpmbcgfIqltsawUMmBvAWwHhqKtF10AqA=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=ThzOLyJScL7YxJYG6QZtdH1r6F3O69IDs6jHNPGZZ9IRRx2OAsq/SuTHk3Lgu64V1 NjQWxxRy2MnfnAPrH/DKFH9KbnLR0//vcwnwbDMuvznTxf+V+VXxEYPeQ7SEcPYS/X suRpVHia1uioOR7KzioYQiOIi9bAPu3DrSWPEAL8bQRHeVxTUYfeMj1m4Gel3WO2OS Fu07is7f92FuekCP8icYoFMmprhMQIyBS05k7SIjaW0RH65VNy5Gy3SMDZcX6CmzJA 3TkdH/0QY+zq+vLzI9sPqC2eUtaggjrAwbdZEpVKsV0kYvK/dTmc8OKP2riVs7gqLV OTuAe+E6/71YA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id ADDC0601C7 for ; Tue, 4 Oct 2022 01:58:46 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="CtoKfJkG"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0AE069DE for ; Tue, 4 Oct 2022 01:58:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1664841526; bh=0XfW4UVqEqzpmbcgfIqltsawUMmBvAWwHhqKtF10AqA=; h=From:To:Subject:Date:From; b=CtoKfJkGr9V3vIgTNfd3kozimIi2/s6onWtbSvUixNDOFPwY785nt6nuQQ/eBgu4x 8pJ0TSIiq7qUgR56jIXaqY9KLb885fZz7Krjtlkf1sRedlLK9xYkpuHfZcUm0oXsaR GOU4+Aziy8AJ7Ru2C04qBfwaG006iyQVz5qX12BY= To: libcamera-devel@lists.libcamera.org Date: Tue, 4 Oct 2022 02:58:43 +0300 Message-Id: <20221003235843.19175-1-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH] test: threads: Test thread cleanup upon abnormal termination 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" If a thread ends abnormally (that is, without retuning normally from its run() function, for instance with a direct call to pthread_cancel()), thread cleanup should still be performed. Add a test to ensure this. Signed-off-by: Laurent Pinchart Reviewed-by: Umang Jain --- test/threads.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/test/threads.cpp b/test/threads.cpp index d83b5833998f..7daa76edb00e 100644 --- a/test/threads.cpp +++ b/test/threads.cpp @@ -8,7 +8,9 @@ #include #include #include +#include #include +#include #include @@ -35,6 +37,32 @@ private: chrono::steady_clock::duration duration_; }; +class CancelThread : public Thread +{ +public: + CancelThread(bool &cancelled) + : cancelled_(cancelled) + { + } + +protected: + void run() + { + cancelled_ = true; + + /* Cancel the thread can call a guaranteed cancellation point. */ + pthread_cancel(pthread_self()); + + struct timespec req{ 0, 100*000*000 }; + nanosleep(&req, nullptr); + + cancelled_ = false; + } + +private: + bool &cancelled_; +}; + class ThreadTest : public Test { protected: @@ -118,6 +146,22 @@ protected: return TestFail; } + /* Test thread cleanup upon abnormal termination. */ + bool cancelled = false; + bool finished = false; + + thread = std::make_unique(cancelled); + thread->finished.connect(this, [&finished]() { finished = true; }); + + thread->start(); + thread->exit(0); + thread->wait(chrono::milliseconds(1000)); + + if (!cancelled || !finished) { + cout << "Cleanup failed upon abnormal termination" << endl; + return TestFail; + } + return TestPass; }