From patchwork Thu Jul 1 23:07:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 12763 X-Patchwork-Delegate: laurent.pinchart@ideasonboard.com 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 71A4EC3222 for ; Thu, 1 Jul 2021 23:08:32 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 452C9684FA; Fri, 2 Jul 2021 01:08:31 +0200 (CEST) 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="Us7I5Qkg"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 439D8684E4 for ; Fri, 2 Jul 2021 01:08:26 +0200 (CEST) Received: from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D4142D89; Fri, 2 Jul 2021 01:08:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1625180906; bh=iWNAMCBnINoGWXKaO/8sOU6Au1BP2vvyHmdX6CATKbg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Us7I5QkgzXfwEv15SDMa9iz1BLTUZO69efkKKDUIgNr17fWGKrpb2Qj0ZXBGREU7E Dlcddu9W/Lhrp5cI4W45dDNLh8guB8Xr219eFzciU6Aq04PZIz6SyVvLtOAwQiDUJa 2ewOUg2+icsFQX+kyVgAf9DQesvgHxgYQza3BAZs= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 2 Jul 2021 02:07:40 +0300 Message-Id: <20210701230741.14320-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210701230741.14320-1-laurent.pinchart@ideasonboard.com> References: <20210701230741.14320-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/3] test: message: Test recursive Thread::dispatchMessages() calls 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" The Thread::dispatchMessages() function needs to support recursive calls, for instance to allow flushing delivery of invoked methods. Add a corresponding test, which currently fails with a double free. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- test/message.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/test/message.cpp b/test/message.cpp index eeea57feab76..7895cd7c2106 100644 --- a/test/message.cpp +++ b/test/message.cpp @@ -26,8 +26,8 @@ public: MessageReceived, }; - MessageReceiver() - : status_(NoMessage) + MessageReceiver(Object *parent = nullptr) + : Object(parent), status_(NoMessage) { } @@ -52,6 +52,45 @@ private: Status status_; }; +class RecursiveMessageReceiver : public Object +{ +public: + RecursiveMessageReceiver() + : child_(this), success_(false) + { + } + + bool success() const { return success_; } + +protected: + void message([[maybe_unused]] Message *msg) + { + if (msg->type() != Message::None) { + Object::message(msg); + return; + } + + child_.postMessage(std::make_unique(Message::None)); + + /* + * If the child has already received the message, something is + * wrong. + */ + if (child_.status() != MessageReceiver::NoMessage) + return; + + Thread::current()->dispatchMessages(Message::None); + + /* The child should now have received the message. */ + if (child_.status() == MessageReceiver::MessageReceived) + success_ = true; + } + +private: + MessageReceiver child_; + bool success_; +}; + class SlowMessageReceiver : public Object { protected: @@ -120,6 +159,29 @@ protected: delete slowReceiver; + this_thread::sleep_for(chrono::milliseconds(100)); + + /* + * Test recursive calls to Thread::dispatchMessages(). Messages + * should be delivered correctly, without crashes or memory + * leaks. Two messages need to be posted to ensure we don't only + * test the simple case of a queue containing a single message. + */ + RecursiveMessageReceiver *recursiveReceiver = new RecursiveMessageReceiver(); + recursiveReceiver->moveToThread(&thread_); + + recursiveReceiver->postMessage(std::make_unique(Message::None)); + recursiveReceiver->postMessage(std::make_unique(Message::UserMessage)); + + this_thread::sleep_for(chrono::milliseconds(10)); + + if (!recursiveReceiver->success()) { + cout << "Recursive message delivery failed" << endl; + return TestFail; + } + + delete recursiveReceiver; + return TestPass; }