-
Notifications
You must be signed in to change notification settings - Fork 412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
protect rcl_node_init()/fini() with rcl logging mutex. #1124
Changes from all commits
9349a44
01bd2f9
f7b3ab5
3f30a55
6726811
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,10 +65,13 @@ NodeBase::NodeBase( | |
// Create the rcl node and store it in a shared_ptr with a custom destructor. | ||
std::unique_ptr<rcl_node_t> rcl_node(new rcl_node_t(rcl_get_zero_initialized_node())); | ||
|
||
ret = rcl_node_init( | ||
rcl_node.get(), | ||
node_name.c_str(), namespace_.c_str(), | ||
context_->get_rcl_context().get(), &rcl_node_options); | ||
{ | ||
std::lock_guard<std::mutex> guard(*(context_->get_rcl_logging_configure_mutex())); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are two subtle bugs here due to using a shared_ptr:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
We should add a check and handle that case correctly.
If the |
||
ret = rcl_node_init( | ||
rcl_node.get(), | ||
node_name.c_str(), namespace_.c_str(), | ||
context_->get_rcl_context().get(), &rcl_node_options); | ||
} | ||
if (ret != RCL_RET_OK) { | ||
// Finalize the interrupt guard condition. | ||
finalize_notify_guard_condition(); | ||
|
@@ -123,8 +126,14 @@ NodeBase::NodeBase( | |
|
||
node_handle_.reset( | ||
rcl_node.release(), | ||
[](rcl_node_t * node) -> void { | ||
if (rcl_node_fini(node) != RCL_RET_OK) { | ||
[this](rcl_node_t * node) -> void { | ||
rcl_ret_t ret; | ||
{ | ||
std::lock_guard<std::mutex> guard( | ||
*(this->context_->get_rcl_logging_configure_mutex())); | ||
ret = rcl_node_fini(node); | ||
} | ||
if (ret != RCL_RET_OK) { | ||
RCUTILS_LOG_ERROR_NAMED( | ||
"rclcpp", | ||
"Error in destruction of rcl node handle: %s", rcl_get_error_string().str); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The shared_ptr in the return signature seems unnecessary. Returning by (const) reference would express intention better since:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method should be marked const since it shouldn't mutate the Context
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I choose to hold a
shared_ptr
to the mutex in #998 because of the following reason:Then imagine the following situation:
In case
shutdown
for both contexts wasn't explicitly called the program, theContext
destructor will call it and that takes the logging mutex, which can segfault if the mutex was previously destroyed.That's the long story of why using the shared pointer ...
Having say that, I should've added a comment in the code. The rationale is not obvious at all.