Skip to content

Commit

Permalink
Multiple calls to Context::shutdown will throw an exception
Browse files Browse the repository at this point in the history
Signed-off-by: Barry Xu <[email protected]>
  • Loading branch information
Barry-Xu-2018 committed Sep 9, 2024
1 parent 40329f2 commit 0eb7ee5
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 0 deletions.
4 changes: 4 additions & 0 deletions rclpy/src/rclpy/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,17 @@ void
Context::shutdown()
{
std::lock_guard<std::mutex> guard{g_contexts_mutex};
if (already_shutdown_) {
throw CONTEXT_ALREADY_SHUTDOWN("Context already shutdown.");
}
auto iter = std::find(g_contexts.begin(), g_contexts.end(), rcl_context_.get());
if (iter != g_contexts.end()) {
g_contexts.erase(iter);
rcl_ret_t ret = rcl_shutdown(rcl_context_.get());
if (RCL_RET_OK != ret) {
throw RCLError("failed to shutdown");
}
already_shutdown_ = true;
}
}

Expand Down
1 change: 1 addition & 0 deletions rclpy/src/rclpy/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class Context : public Destroyable, public std::enable_shared_from_this<Context>

private:
std::shared_ptr<rcl_context_t> rcl_context_;
bool already_shutdown_{false};
};

/// Define a pybind11 wrapper for an rclpy::Context
Expand Down
5 changes: 5 additions & 0 deletions rclpy/src/rclpy/exceptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ class InvalidHandle : public std::runtime_error
using std::runtime_error::runtime_error;
};

class CONTEXT_ALREADY_SHUTDOWN : public std::runtime_error
{
using std::runtime_error::runtime_error;
};

} // namespace rclpy

#endif // RCLPY__EXCEPTIONS_HPP_
9 changes: 9 additions & 0 deletions rclpy/test/test_init_shutdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ def test_double_init():
rclpy.shutdown(context=context)


def test_double_shutdown():
context = rclpy.context.Context()
rclpy.init(context=context)
assert context.ok()
rclpy.shutdown(context=context)
with pytest.raises(RuntimeError):
rclpy.shutdown(context=context)


def test_create_node_without_init():
context = rclpy.context.Context()
with pytest.raises(NotInitializedException):
Expand Down

0 comments on commit 0eb7ee5

Please sign in to comment.