summaryrefslogtreecommitdiff
path: root/test/message.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/message.cpp')
-rw-r--r--test/message.cpp79
1 files changed, 57 insertions, 22 deletions
diff --git a/test/message.cpp b/test/message.cpp
index 478bc79d..19e6646d 100644
--- a/test/message.cpp
+++ b/test/message.cpp
@@ -2,15 +2,18 @@
/*
* Copyright (C) 2019, Google Inc.
*
- * message.cpp - Messages test
+ * Messages test
*/
#include <chrono>
#include <iostream>
+#include <memory>
#include <thread>
-#include "message.h"
-#include "thread.h"
+#include <libcamera/base/message.h>
+#include <libcamera/base/object.h>
+#include <libcamera/base/thread.h>
+
#include "test.h"
using namespace std;
@@ -25,8 +28,8 @@ public:
MessageReceived,
};
- MessageReceiver()
- : status_(NoMessage)
+ MessageReceiver(Object *parent = nullptr)
+ : Object(parent), status_(NoMessage)
{
}
@@ -51,23 +54,43 @@ private:
Status status_;
};
-class SlowMessageReceiver : public Object
+class RecursiveMessageReceiver : public Object
{
+public:
+ RecursiveMessageReceiver()
+ : child_(this), success_(false)
+ {
+ }
+
+ bool success() const { return success_; }
+
protected:
- void message(Message *msg)
+ void message([[maybe_unused]] Message *msg)
{
if (msg->type() != Message::None) {
Object::message(msg);
return;
}
+ child_.postMessage(std::make_unique<Message>(Message::None));
+
/*
- * Don't access any member of the object here (including the
- * vtable) as the object will be deleted by the main thread
- * while we're sleeping.
+ * If the child has already received the message, something is
+ * wrong.
*/
- this_thread::sleep_for(chrono::milliseconds(100));
+ 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 MessageTest : public Test
@@ -86,16 +109,19 @@ protected:
return TestFail;
}
- MessageReceiver receiver;
- receiver.moveToThread(&thread_);
+ MessageReceiver *receiver = new MessageReceiver();
+ receiver->moveToThread(&thread_);
thread_.start();
- receiver.postMessage(std::make_unique<Message>(Message::None));
+ receiver->postMessage(std::make_unique<Message>(Message::None));
this_thread::sleep_for(chrono::milliseconds(100));
- switch (receiver.status()) {
+ MessageReceiver::Status status = receiver->status();
+ receiver->deleteLater();
+
+ switch (status) {
case MessageReceiver::NoMessage:
cout << "No message received" << endl;
return TestFail;
@@ -107,17 +133,26 @@ protected:
}
/*
- * Test for races between message delivery and object deletion.
- * Failures result in assertion errors, there is no need for
- * explicit checks.
+ * 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.
*/
- SlowMessageReceiver *slowReceiver = new SlowMessageReceiver();
- slowReceiver->moveToThread(&thread_);
- slowReceiver->postMessage(std::make_unique<Message>(Message::None));
+ 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));
- delete slowReceiver;
+ bool success = recursiveReceiver->success();
+ recursiveReceiver->deleteLater();
+
+ if (!success) {
+ cout << "Recursive message delivery failed" << endl;
+ return TestFail;
+ }
return TestPass;
}