diff options
-rw-r--r-- | host/lib/rfnoc/graph.cpp | 9 | ||||
-rw-r--r-- | host/tests/actions_test.cpp | 26 |
2 files changed, 31 insertions, 4 deletions
diff --git a/host/lib/rfnoc/graph.cpp b/host/lib/rfnoc/graph.cpp index b84ceee3e..00b0d9a5e 100644 --- a/host/lib/rfnoc/graph.cpp +++ b/host/lib/rfnoc/graph.cpp @@ -6,6 +6,7 @@ #include <uhd/exception.hpp> #include <uhd/utils/log.hpp> +#include <uhd/utils/scope_exit.hpp> #include <uhdlib/rfnoc/graph.hpp> #include <uhdlib/rfnoc/node_accessor.hpp> #include <boost/graph/filtered_graph.hpp> @@ -557,6 +558,8 @@ void graph_t::enqueue_action( << action->id); return; } + auto reset_handling_flag = + uhd::utils::scope_exit::make([&]() { _action_handling_ongoing.clear(); }); unsigned iteration_count = 0; while (!_action_queue.empty()) { @@ -607,10 +610,8 @@ void graph_t::enqueue_action( } UHD_LOG_TRACE(LOG_ID, "Delivered all actions, terminating action handling."); - // Release the action handling flag - _action_handling_ongoing.clear(); - // Now, the _graph_mutex is released, and someone else can start sending - // actions. + // Now, the _graph_mutex and _action_handling_ongoing are released, and + // someone else can start sending actions. } /****************************************************************************** diff --git a/host/tests/actions_test.cpp b/host/tests/actions_test.cpp index d2b5a6e3a..769cbea7a 100644 --- a/host/tests/actions_test.cpp +++ b/host/tests/actions_test.cpp @@ -221,3 +221,29 @@ BOOST_AUTO_TEST_CASE(test_action_forwarding_map_exception_invalid_destination) auto cmd = action_info::make("action"); BOOST_REQUIRE_THROW(generator.post_output_edge_action(cmd, 0), uhd::rfnoc_error); } + +BOOST_AUTO_TEST_CASE(test_action_exception_handling) +{ + node_accessor_t node_accessor{}; + uhd::rfnoc::detail::graph_t graph{}; + + class mock_throwing_node_t : public mock_radio_node_t + { + public: + mock_throwing_node_t() : mock_radio_node_t(0) + { + register_action_handler( + "throwing_action", [](const res_source_info&, action_info::sptr) { + throw uhd::runtime_error("Arbitrary UHD exception"); + }); + } + }; + + mock_throwing_node_t mock_radio{}; + graph.connect(&mock_radio, &mock_radio, {0, 0, graph_edge_t::DYNAMIC, false}); + graph.commit(); + // Check that it throws the first time + BOOST_REQUIRE_THROW(node_accessor.post_action(&mock_radio, {res_source_info::USER, 0}, action_info::make("throwing_action")), uhd::runtime_error); + // It should also throw the second time: we should actually be running this action even though the previous one threw an exception + BOOST_REQUIRE_THROW(node_accessor.post_action(&mock_radio, {res_source_info::USER, 0}, action_info::make("throwing_action")), uhd::runtime_error); +} |