From a8144e7db67183069e50bd6825db797919f70466 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 2 Aug 2024 13:55:17 +0000 Subject: [PATCH] DRAFT: Fix: Double spin required since 28.2.0 This is a first attempt to fix #2589. It passes all tests, and seems to work, but I am 90% certain it introduces unwanted races and lost wakeups. Anyway, its a starting point for a discussion... --- rclcpp/src/rclcpp/executor.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/rclcpp/src/rclcpp/executor.cpp b/rclcpp/src/rclcpp/executor.cpp index 69131cc111..2d0322b77b 100644 --- a/rclcpp/src/rclcpp/executor.cpp +++ b/rclcpp/src/rclcpp/executor.cpp @@ -726,6 +726,25 @@ Executor::wait_for_work(std::chrono::nanoseconds timeout) { TRACETOOLS_TRACEPOINT(rclcpp_executor_wait_for_work, timeout.count()); + // the real one has been added to the main waitset, therefore we need to create a copy + executors::ExecutorNotifyWaitable::SharedPtr notify_cpy = std::make_shared(*notify_waitable_); + + rclcpp::WaitSet notify_only_wait_set_({}, {}, {}, {}, {}, {}, context_); + notify_only_wait_set_.add_waitable(notify_cpy); + auto res = notify_only_wait_set_.wait(std::chrono::nanoseconds(0)); + if(res.kind() == WaitResultKind::Ready) { + auto & rcl_wait_set = res.get_wait_set().get_rcl_wait_set(); + if (notify_cpy->is_ready(rcl_wait_set)) { + notify_cpy->execute(notify_cpy->take_data()); + + // As this waitable is also used to signal + // a cancel, we need to check it here + if (!spinning.load()) { + return; + } + } + } + // Clear any previous wait result this->wait_result_.reset();