rclcpp::spin_until_future_complete does not return after future completes
- Platform: Ubuntu 20.04 x64, kernel 5.11.0-27-generic, gcc 9.3.0
- ROS version: ROS2 foxy (installed via Debian packages https://docs.ros.org/en/foxy/Installation/Ubuntu-Install-Debians.html)
Consider the following code
#include <chrono>
#include <iostream>
#include <thread>
#include "rclcpp/rclcpp.hpp"
int main(int argc, char** argv)
{
rclcpp::init(argc, argv);
auto node = std::make_shared<rclcpp::Node>("my_node");
auto future = std::async(std::launch::async, []() {
std::cout << "starting to sleep..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "sleep done" << std::endl;
});
auto shared_future = future.share();
std::cout << "starting to spin..." << std::endl;
rclcpp::spin_until_future_complete(node, shared_future);
std::cout << "spin done" << std::endl;
rclcpp::shutdown();
return EXIT_SUCCESS;
}
Expected behavior: rclcpp::spin_until_future_complete()
should return after the lambda passed to std::async()
returns.
Actual behavior: rclcpp::spin_until_future_complete()
does not return after labmda completes. Instead, it will only return after hitting Ctrl+C
.
Is this intended or am I somehow missusing the API?
Edit: I have checked the unit tests that call rclcpp::spin_until_future_complete
(https://github.com/ros2/rclcpp/blob/master/rclcpp/test/rclcpp/executors/test_executors.cpp) only test the case there the shared_future
is already ready when rclcpp::spin_until_future_complete
is called. I can confirm that my example above works as expected if I add a sleep statement before calling rclcpp::spin_until_future_complete
so that the lambda finishes before the call.
Edit #2: It seems like the current behavior of rclcpp::spin_until_future_complete
is that it will block forever if the future completes after the calling the function. The workaround is to provide a non-infinite timeout, check if the return value indicates a timeout and call the function again if it does. However, rclcpp::spin_until_future_complete
will only indicate completion of the future after the timeout expires instead of as soon as the future completes.
Asked by simong on 2021-09-09 09:01:55 UTC
Comments
Haven't looked much, but possibly rclcpp#1916?
Asked by 130s on 2023-04-18 15:22:12 UTC