From 1bbe5dffd9771836a9a2882fa0b4324d80075162 Mon Sep 17 00:00:00 2001 From: Leon Matthes Date: Fri, 5 Jul 2024 10:45:59 +0200 Subject: [PATCH] test: Deleting a slot while its running With the new connectReflective capability, slots can disconnect themselves. Make sure that this doesn't cause them to delete themselves while they're still running. --- tests/signal/tst_signal.cpp | 45 +++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tests/signal/tst_signal.cpp b/tests/signal/tst_signal.cpp index d5f46bc..252aafd 100644 --- a/tests/signal/tst_signal.cpp +++ b/tests/signal/tst_signal.cpp @@ -326,6 +326,51 @@ TEST_CASE("Signal connections") signal.emit(a, b); REQUIRE(lambdaCalled == true); } + + SUBCASE("A reflective connection cannot deconstruct itself while still in use") + { + class DestructorNotifier + { + public: + DestructorNotifier(bool *flag) + : destructorFlag(flag) { } + + ~DestructorNotifier() + { + if (destructorFlag) { + *destructorFlag = true; + } + } + + bool *destructorFlag = nullptr; + }; + + auto destructed = std::make_shared(false); + auto notifier = std::make_shared(&*destructed); + + Signal<> signal; + + auto handle = signal.connectReflective([destructed, notifier = std::move(notifier)](ConnectionHandle &handle) { + REQUIRE_FALSE(*destructed); + REQUIRE(handle.isActive()); + handle.disconnect(); + // Make sure our own lambda isn't deconstructed while it's runnning. + REQUIRE_FALSE(*destructed); + // However, the handle will no longer be valid. + REQUIRE_FALSE(handle.isActive()); + }); + + // Make sure the notifier has actually been moved into the lambda. + // This ensures the lambda has exclusive ownership of the DestructorNotifier. + REQUIRE_FALSE(notifier); + + REQUIRE_FALSE(*destructed); + REQUIRE(handle.isActive()); + signal.emit(); + + REQUIRE(*destructed); + REQUIRE_FALSE(handle.isActive()); + } } TEST_CASE("ConnectionEvaluator")