Skip to content

Commit 069a001

Browse files
Release ownership of entities after spinning cancelled (#2556)
* Release ownership of entities after spinning cancelled Signed-off-by: Barry Xu <barry.xu@sony.com> * Move release action to every exit point in different spin functions Signed-off-by: Barry Xu <barry.xu@sony.com> * Move wait_result_.reset() before setting spinning to false Signed-off-by: Barry Xu <barry.xu@sony.com> * Update test code Signed-off-by: Barry Xu <barry.xu@sony.com> * Move test code to test_executors.cpp Signed-off-by: Barry Xu <barry.xu@sony.com> --------- Signed-off-by: Barry Xu <barry.xu@sony.com>
1 parent c743c17 commit 069a001

File tree

5 files changed

+31
-6
lines changed

5 files changed

+31
-6
lines changed

rclcpp/src/rclcpp/executor.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ Executor::spin_until_future_complete_impl(
275275
if (spinning.exchange(true)) {
276276
throw std::runtime_error("spin_until_future_complete() called while already spinning");
277277
}
278-
RCPPUTILS_SCOPE_EXIT(this->spinning.store(false); );
278+
RCPPUTILS_SCOPE_EXIT(wait_result_.reset();this->spinning.store(false););
279279
while (rclcpp::ok(this->context_) && spinning.load()) {
280280
// Do one item of work.
281281
spin_once_impl(timeout_left);
@@ -364,7 +364,7 @@ Executor::spin_some_impl(std::chrono::nanoseconds max_duration, bool exhaustive)
364364
if (spinning.exchange(true)) {
365365
throw std::runtime_error("spin_some() called while already spinning");
366366
}
367-
RCPPUTILS_SCOPE_EXIT(this->spinning.store(false); );
367+
RCPPUTILS_SCOPE_EXIT(wait_result_.reset();this->spinning.store(false););
368368

369369
// clear the wait result and wait for work without blocking to collect the work
370370
// for the first time
@@ -431,7 +431,7 @@ Executor::spin_once(std::chrono::nanoseconds timeout)
431431
if (spinning.exchange(true)) {
432432
throw std::runtime_error("spin_once() called while already spinning");
433433
}
434-
RCPPUTILS_SCOPE_EXIT(this->spinning.store(false); );
434+
RCPPUTILS_SCOPE_EXIT(wait_result_.reset();this->spinning.store(false););
435435
spin_once_impl(timeout);
436436
}
437437

rclcpp/src/rclcpp/executors/multi_threaded_executor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ MultiThreadedExecutor::spin()
5555
if (spinning.exchange(true)) {
5656
throw std::runtime_error("spin() called while already spinning");
5757
}
58-
RCPPUTILS_SCOPE_EXIT(this->spinning.store(false););
58+
RCPPUTILS_SCOPE_EXIT(wait_result_.reset();this->spinning.store(false););
5959
std::vector<std::thread> threads;
6060
size_t thread_id = 0;
6161
{

rclcpp/src/rclcpp/executors/single_threaded_executor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ SingleThreadedExecutor::spin()
3030
if (spinning.exchange(true)) {
3131
throw std::runtime_error("spin() called while already spinning");
3232
}
33-
RCPPUTILS_SCOPE_EXIT(this->spinning.store(false); );
33+
RCPPUTILS_SCOPE_EXIT(wait_result_.reset();this->spinning.store(false););
3434

3535
// Clear any previous result and rebuild the waitset
3636
this->wait_result_.reset();

rclcpp/test/rclcpp/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ ament_add_gtest(test_executor test_executor.cpp
641641
TIMEOUT 120)
642642
ament_add_test_label(test_executor mimick)
643643
if(TARGET test_executor)
644-
target_link_libraries(test_executor ${PROJECT_NAME} mimick)
644+
target_link_libraries(test_executor ${PROJECT_NAME} mimick ${test_msgs_TARGETS})
645645
endif()
646646

647647
ament_add_gtest(test_graph_listener test_graph_listener.cpp)

rclcpp/test/rclcpp/executors/test_executors.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "rclcpp/time_source.hpp"
4040

4141
#include "test_msgs/msg/empty.hpp"
42+
#include "test_msgs/srv/empty.hpp"
4243

4344
#include "./executor_types.hpp"
4445
#include "./test_waitable.hpp"
@@ -831,3 +832,27 @@ TEST(TestExecutors, testSpinWithNonDefaultContext)
831832

832833
rclcpp::shutdown(non_default_context);
833834
}
835+
836+
TYPED_TEST(TestExecutors, release_ownership_entity_after_spinning_cancel)
837+
{
838+
using ExecutorType = TypeParam;
839+
ExecutorType executor;
840+
841+
auto future = std::async(std::launch::async, [&executor] {executor.spin();});
842+
843+
auto node = std::make_shared<rclcpp::Node>("test_node");
844+
auto callback = [](
845+
const test_msgs::srv::Empty::Request::SharedPtr, test_msgs::srv::Empty::Response::SharedPtr) {
846+
};
847+
auto server = node->create_service<test_msgs::srv::Empty>("test_service", callback);
848+
while (!executor.is_spinning()) {
849+
std::this_thread::sleep_for(50ms);
850+
}
851+
executor.add_node(node);
852+
std::this_thread::sleep_for(50ms);
853+
executor.cancel();
854+
std::future_status future_status = future.wait_for(1s);
855+
EXPECT_EQ(future_status, std::future_status::ready);
856+
857+
EXPECT_EQ(server.use_count(), 1);
858+
}

0 commit comments

Comments
 (0)