Convert more node accessors to pybind11#730
Conversation
Signed-off-by: Greg Balke <greg@openrobotics.org>
Signed-off-by: Greg Balke <greg@openrobotics.org>
Signed-off-by: Greg Balke <greg@openrobotics.org>
Signed-off-by: Greg Balke <greg@openrobotics.org>
65b3947 to
865536e
Compare
Signed-off-by: Greg Balke <greg@openrobotics.org>
Signed-off-by: Greg Balke <greg@openrobotics.org>
Signed-off-by: Greg Balke <greg@openrobotics.org>
Signed-off-by: Greg Balke <greg@openrobotics.org>
| "failed to fini node names during error handling: "); | ||
| RCUTILS_SAFE_FWRITE_TO_STDERR(rcl_get_error_string().str); | ||
| RCUTILS_SAFE_FWRITE_TO_STDERR("\n"); | ||
| rcl_reset_error(); |
There was a problem hiding this comment.
@gbalke if an error was set by function A, resetting it before calling function B avoids warnings about error overwrite if function B happens to set an error as well. That is, consider moving each of these if clauses after the corresponding function call. It's pure printing, so no risk of an exception getting thrown there.
There was a problem hiding this comment.
I think I got mixed up because of #730 (comment). I'll change it back since I'm not throwing now.
Signed-off-by: Greg Balke <greg@openrobotics.org>
hidmic
left a comment
There was a problem hiding this comment.
LGTM but for one comment, pending green CI
rclpy/src/rclpy/node.cpp
Outdated
|
|
||
| RCPPUTILS_SCOPE_EXIT( | ||
| { | ||
| fini_names_ret = rcutils_string_array_fini(&node_names); | ||
| fini_namespaces_ret = rcutils_string_array_fini(&node_namespaces); | ||
| fini_enclaves_ret = rcutils_string_array_fini(&enclaves); | ||
| if (RCUTILS_RET_OK != fini_names_ret) { | ||
| for (size_t idx = 0; idx < node_names.size; ++idx) { | ||
| if (get_enclaves) { | ||
| pynode_names_and_namespaces[idx] = py::make_tuple( | ||
| py::str(node_names.data[idx]), | ||
| py::str(node_namespaces.data[idx]), | ||
| py::str(enclaves.data[idx])); | ||
| } else { | ||
| pynode_names_and_namespaces[idx] = py::make_tuple( | ||
| py::str(node_names.data[idx]), | ||
| py::str(node_namespaces.data[idx])); | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
@gbalke this won't have the intended effect. If it throws, it'll throw from a destructor and C++ will terminate the program :)
If I may, you may want to do something like:
RCPPUTILS_SCOPE_EXIT({ // setup cleanup block to be run on scope exit
rcutils_ret_t fini_ret = rcutils_string_array_fini(&node_names);
if (RCUTILS_RET_OK != fini_ret) {
RCUTILS_SAFE_FWRITE_TO_STDERR(
"[rclpy|" RCUTILS_STRINGIFY(__FILE__) ":" RCUTILS_STRINGIFY(__LINE__) "]: "
"failed to fini node names during error handling: ");
RCUTILS_SAFE_FWRITE_TO_STDERR(rcl_get_error_string().str);
RCUTILS_SAFE_FWRITE_TO_STDERR("\n");
rcl_reset_error();
}
fini_ret = rcutils_string_array_fini(&node_namespaces);
if (RCUTILS_RET_OK != fini_ret) {
RCUTILS_SAFE_FWRITE_TO_STDERR(
"[rclpy|" RCUTILS_STRINGIFY(__FILE__) ":" RCUTILS_STRINGIFY(__LINE__) "]: "
"failed to fini node namespaces during error handling: ");
RCUTILS_SAFE_FWRITE_TO_STDERR(rcl_get_error_string().str);
RCUTILS_SAFE_FWRITE_TO_STDERR("\n");
rcl_reset_error();
}
fini_ret = rcutils_string_array_fini(&enclaves);
if (RCUTILS_RET_OK != fini_ret) {
RCUTILS_SAFE_FWRITE_TO_STDERR(
"[rclpy|" RCUTILS_STRINGIFY(__FILE__) ":" RCUTILS_STRINGIFY(__LINE__) "]: "
"failed to fini enclaves string array during error handling: ");
RCUTILS_SAFE_FWRITE_TO_STDERR(rcl_get_error_string().str);
RCUTILS_SAFE_FWRITE_TO_STDERR("\n");
rcl_reset_error();
}
});
py::list pynode_names_and_namespaces(node_names.size);
for (size_t idx = 0; idx < node_names.size; ++idx) {
if (get_enclaves) {
pynode_names_and_namespaces[idx] = py::make_tuple(
py::str(node_names.data[idx]),
py::str(node_namespaces.data[idx]),
py::str(enclaves.data[idx]));
} else {
pynode_names_and_namespaces[idx] = py::make_tuple(
py::str(node_names.data[idx]),
py::str(node_namespaces.data[idx]));
}
}
return pynode_names_and_namespaces; // and then cleanup code is run automaticallyThere was a problem hiding this comment.
What I guess i don't understand is that the fini calls will happen before the for loop? Or is that the special magic of the SCOPE_EXIT statement? Where that will be called upon completion?
In essence, you're registering a callback with RCCPUTILS_SCOPE_EXIT.
There was a problem hiding this comment.
Read the comments on the blocks and now it makes sense 👍. Thanks for walking me through it haha.
There was a problem hiding this comment.
Or is that the special magic of the SCOPE_EXIT statement?
If you look under the hood, this RCPPUTILS_SCOPE_EXIT macro instantiates an object that takes your code, wraps it in a lambda function, and executes it on destruction. Using object construction/destruction to manage resource lifecycles is so common in C++ that it has a name. It's the primary idiom when it comes to exception safety.
Signed-off-by: Greg Balke <greg@openrobotics.org>
612b848 to
0a4fbd8
Compare
|
@sloretz lmk if you want to review this before I merge. |
Signed-off-by: Greg Balke <greg@openrobotics.org>
|
@ros-pull-request-builder retest this please ❤️ |
|
@ros-pull-request-builder retest this please 💔 |
Part of #665.
Handles: