diff --git a/include/mav/Connection.h b/include/mav/Connection.h index a3eda87..10738af 100644 --- a/include/mav/Connection.h +++ b/include/mav/Connection.h @@ -55,6 +55,7 @@ namespace mav { using Expectation = std::shared_ptr>; private: + using ExpectationWeakRef = std::weak_ptr>; struct FunctionCallback { std::function callback; @@ -62,7 +63,7 @@ namespace mav { }; struct PromiseCallback { - Expectation promise; + ExpectationWeakRef promise; std::function selector; }; @@ -126,11 +127,16 @@ namespace mav { } it++; } else if constexpr (std::is_same_v) { - if (arg.selector(message)) { - arg.promise->set_value(message); + auto promise = arg.promise.lock(); + if (!promise) { it = _message_callbacks.erase(it); } else { - it++; + if (arg.selector(message)) { + promise->set_value(message); + it = _message_callbacks.erase(it); + } else { + it++; + } } } }, callback); @@ -152,8 +158,13 @@ namespace mav { } it++; } else if constexpr (std::is_same_v) { - arg.promise->set_exception(exception); - it = _message_callbacks.erase(it); + auto promise = arg.promise.lock(); + if (!promise) { + it = _message_callbacks.erase(it); + } else { + promise->set_exception(exception); + it = _message_callbacks.erase(it); + } } }, callback); } diff --git a/tests/Network.cpp b/tests/Network.cpp index ab1bc59..6d9cc3d 100644 --- a/tests/Network.cpp +++ b/tests/Network.cpp @@ -272,6 +272,10 @@ TEST_CASE("Create network runtime") { auto expectation = connection->expect("TEST_MESSAGE"); CHECK_THROWS_AS(auto message = connection->receive(expectation, 100), TimeoutException); } + // send a heartbeat. Any message will clear expired expectations + interface.addToReceiveQueue("\xfd\x09\x00\x00\x00\xfd\x01\x00\x00\x00\x04\x00\x00\x00\x01\x02\x03\x05\x06\x77\x53"s, interface_partner); + // wait for the heartbeat to be received, to make sure timing is correct in test + connection->receive("HEARTBEAT"); CHECK_EQ(connection->callbackCount(), 0); } }