summaryrefslogtreecommitdiff
path: root/test/actor
diff options
context:
space:
mode:
Diffstat (limited to 'test/actor')
-rw-r--r--test/actor/actor.test.cpp56
1 files changed, 56 insertions, 0 deletions
diff --git a/test/actor/actor.test.cpp b/test/actor/actor.test.cpp
index 638c24ed7d..3d97469628 100644
--- a/test/actor/actor.test.cpp
+++ b/test/actor/actor.test.cpp
@@ -155,6 +155,62 @@ TEST(Actor, DestructionAllowedInReceiveOnSameThread) {
ASSERT_EQ(std::future_status::ready, status);
}
+TEST(Actor, SelfDestructionDoesntCrashWaitingReceivingThreads) {
+ // Ensures destruction doesn't cause waiting threads to
+ // crash when a actor closes it's own mailbox from a
+ // callback
+
+ struct Test {
+
+ Test(ActorRef<Test>){};
+
+ void callMeBack(std::function<void ()> callback) {
+ callback();
+ }
+ };
+
+
+ ThreadPool pool { 2 };
+
+ std::promise<void> actorClosedPromise;
+
+ auto closingActor = std::make_unique<Actor<Test>>(pool);
+ auto waitingActor = std::make_unique<Actor<Test>>(pool);
+
+ std::atomic<bool> waitingMessageProcessed {false};
+
+ // Callback (triggered while mutex is locked in Mailbox::receive())
+ closingActor->invoke(&Test::callMeBack, [&]() {
+
+ // Queue up another message from another thread
+ std::promise<void> messageQueuedPromise;
+ waitingActor->invoke(&Test::callMeBack, [&]() {
+ // This will be waiting on the mutex in
+ // Mailbox::receive(), holding a lock
+ // on the weak_ptr so the mailbox is not
+ // destroyed
+ closingActor->invoke(&Test::callMeBack, [&]() {
+ waitingMessageProcessed.store(true);
+ });
+ messageQueuedPromise.set_value();
+ });
+
+ // Wait for the message to be queued
+ ASSERT_EQ(
+ messageQueuedPromise.get_future().wait_for(std::chrono::seconds(1)),
+ std::future_status::ready
+ );
+
+ // Destroy the Actor/Mailbox in the same thread
+ closingActor.reset();
+ actorClosedPromise.set_value();
+ });
+
+ auto status = actorClosedPromise.get_future().wait_for(std::chrono::seconds(1));
+ ASSERT_EQ(std::future_status::ready, status);
+ ASSERT_FALSE(waitingMessageProcessed.load());
+}
+
TEST(Actor, OrderedMailbox) {
// Messages are processed in order.