[libcamera-devel] [PATCH 2/3] test: message: Test recursive Thread::dispatchMessages() calls

Laurent Pinchart laurent.pinchart at ideasonboard.com
Fri Jul 2 01:07:40 CEST 2021


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 <laurent.pinchart at ideasonboard.com>
---
 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>(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>(Message::None));
+		recursiveReceiver->postMessage(std::make_unique<Message>(Message::UserMessage));
+
+		this_thread::sleep_for(chrono::milliseconds(10));
+
+		if (!recursiveReceiver->success()) {
+			cout << "Recursive message delivery failed" << endl;
+			return TestFail;
+		}
+
+		delete recursiveReceiver;
+
 		return TestPass;
 	}
 
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list