Ensure compliant node construction/destruction API. (#206)
Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
This commit is contained in:
parent
5930ea020c
commit
3d03bf6c53
1 changed files with 71 additions and 41 deletions
|
@ -48,6 +48,7 @@
|
||||||
#include "rmw/names_and_types.h"
|
#include "rmw/names_and_types.h"
|
||||||
#include "rmw/rmw.h"
|
#include "rmw/rmw.h"
|
||||||
#include "rmw/sanity_checks.h"
|
#include "rmw/sanity_checks.h"
|
||||||
|
#include "rmw/validate_namespace.h"
|
||||||
#include "rmw/validate_node_name.h"
|
#include "rmw/validate_node_name.h"
|
||||||
|
|
||||||
#include "fallthrough_macro.hpp"
|
#include "fallthrough_macro.hpp"
|
||||||
|
@ -1222,14 +1223,39 @@ extern "C" rmw_node_t * rmw_create_node(
|
||||||
{
|
{
|
||||||
static_cast<void>(domain_id);
|
static_cast<void>(domain_id);
|
||||||
static_cast<void>(localhost_only);
|
static_cast<void>(localhost_only);
|
||||||
RET_NULL_X(name, return nullptr);
|
RMW_CHECK_ARGUMENT_FOR_NULL(context, nullptr);
|
||||||
RET_NULL_X(namespace_, return nullptr);
|
RMW_CHECK_TYPE_IDENTIFIERS_MATCH(
|
||||||
rmw_ret_t ret;
|
context,
|
||||||
int dummy_validation_result;
|
context->implementation_identifier,
|
||||||
size_t dummy_invalid_index;
|
eclipse_cyclonedds_identifier,
|
||||||
if ((ret =
|
return nullptr);
|
||||||
rmw_validate_node_name(name, &dummy_validation_result, &dummy_invalid_index)) != RMW_RET_OK)
|
RMW_CHECK_FOR_NULL_WITH_MSG(
|
||||||
{
|
context->impl,
|
||||||
|
"expected initialized context",
|
||||||
|
return nullptr);
|
||||||
|
if (context->impl->is_shutdown) {
|
||||||
|
RCUTILS_SET_ERROR_MSG("context has been shutdown");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int validation_result = RMW_NODE_NAME_VALID;
|
||||||
|
rmw_ret_t ret = rmw_validate_node_name(name, &validation_result, nullptr);
|
||||||
|
if (RMW_RET_OK != ret) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (RMW_NODE_NAME_VALID != validation_result) {
|
||||||
|
const char * reason = rmw_node_name_validation_result_string(validation_result);
|
||||||
|
RMW_SET_ERROR_MSG_WITH_FORMAT_STRING("invalid node name: %s", reason);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
validation_result = RMW_NAMESPACE_VALID;
|
||||||
|
ret = rmw_validate_namespace(namespace_, &validation_result, nullptr);
|
||||||
|
if (RMW_RET_OK != ret) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (RMW_NAMESPACE_VALID != validation_result) {
|
||||||
|
const char * reason = rmw_node_name_validation_result_string(validation_result);
|
||||||
|
RMW_SET_ERROR_MSG_WITH_FORMAT_STRING("invalid node namespace: %s", reason);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1237,25 +1263,29 @@ extern "C" rmw_node_t * rmw_create_node(
|
||||||
if (RMW_RET_OK != ret) {
|
if (RMW_RET_OK != ret) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
auto finalize_context = rcpputils::make_scope_exit(
|
||||||
|
[context]() {context->impl->fini();});
|
||||||
|
|
||||||
auto * node_impl = new CddsNode();
|
std::unique_ptr<CddsNode> node_impl(new (std::nothrow) CddsNode());
|
||||||
rmw_node_t * node_handle = nullptr;
|
RET_ALLOC_X(node_impl, return nullptr);
|
||||||
RET_ALLOC_X(node_impl, goto fail_node_impl);
|
|
||||||
|
|
||||||
node_handle = rmw_node_allocate();
|
rmw_node_t * node = rmw_node_allocate();
|
||||||
RET_ALLOC_X(node_handle, goto fail_node_handle);
|
RET_ALLOC_X(node, return nullptr);
|
||||||
node_handle->implementation_identifier = eclipse_cyclonedds_identifier;
|
auto cleanup_node = rcpputils::make_scope_exit(
|
||||||
node_handle->data = node_impl;
|
[node]() {
|
||||||
node_handle->context = context;
|
rmw_free(const_cast<char *>(node->name));
|
||||||
|
rmw_free(const_cast<char *>(node->namespace_));
|
||||||
|
rmw_node_free(node);
|
||||||
|
});
|
||||||
|
|
||||||
node_handle->name = static_cast<const char *>(rmw_allocate(sizeof(char) * strlen(name) + 1));
|
node->name = static_cast<const char *>(rmw_allocate(sizeof(char) * strlen(name) + 1));
|
||||||
RET_ALLOC_X(node_handle->name, goto fail_node_handle_name);
|
RET_ALLOC_X(node->name, return nullptr);
|
||||||
memcpy(const_cast<char *>(node_handle->name), name, strlen(name) + 1);
|
memcpy(const_cast<char *>(node->name), name, strlen(name) + 1);
|
||||||
|
|
||||||
node_handle->namespace_ =
|
node->namespace_ =
|
||||||
static_cast<const char *>(rmw_allocate(sizeof(char) * strlen(namespace_) + 1));
|
static_cast<const char *>(rmw_allocate(sizeof(char) * strlen(namespace_) + 1));
|
||||||
RET_ALLOC_X(node_handle->namespace_, goto fail_node_handle_namespace);
|
RET_ALLOC_X(node->namespace_, return nullptr);
|
||||||
memcpy(const_cast<char *>(node_handle->namespace_), namespace_, strlen(namespace_) + 1);
|
memcpy(const_cast<char *>(node->namespace_), namespace_, strlen(namespace_) + 1);
|
||||||
|
|
||||||
{
|
{
|
||||||
// Though graph_cache methods are thread safe, both cache update and publishing have to also
|
// Though graph_cache methods are thread safe, both cache update and publishing have to also
|
||||||
|
@ -1275,30 +1305,28 @@ extern "C" rmw_node_t * rmw_create_node(
|
||||||
// If publishing the message failed, we don't have to publish an update
|
// If publishing the message failed, we don't have to publish an update
|
||||||
// after removing it from the graph cache */
|
// after removing it from the graph cache */
|
||||||
static_cast<void>(common->graph_cache.remove_node(common->gid, name, namespace_));
|
static_cast<void>(common->graph_cache.remove_node(common->gid, name, namespace_));
|
||||||
goto fail_pub_info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return node_handle;
|
|
||||||
|
|
||||||
fail_pub_info:
|
|
||||||
rmw_free(const_cast<char *>(node_handle->namespace_));
|
|
||||||
fail_node_handle_namespace:
|
|
||||||
rmw_free(const_cast<char *>(node_handle->name));
|
|
||||||
fail_node_handle_name:
|
|
||||||
rmw_node_free(node_handle);
|
|
||||||
fail_node_handle:
|
|
||||||
delete node_impl;
|
|
||||||
fail_node_impl:
|
|
||||||
context->impl->fini();
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup_node.cancel();
|
||||||
|
node->implementation_identifier = eclipse_cyclonedds_identifier;
|
||||||
|
node->data = node_impl.release();
|
||||||
|
node->context = context;
|
||||||
|
finalize_context.cancel();
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" rmw_ret_t rmw_destroy_node(rmw_node_t * node)
|
extern "C" rmw_ret_t rmw_destroy_node(rmw_node_t * node)
|
||||||
{
|
{
|
||||||
rmw_ret_t result_ret = RMW_RET_OK;
|
rmw_ret_t result_ret = RMW_RET_OK;
|
||||||
RET_WRONG_IMPLID(node);
|
RMW_CHECK_ARGUMENT_FOR_NULL(node, RMW_RET_INVALID_ARGUMENT);
|
||||||
|
RMW_CHECK_TYPE_IDENTIFIERS_MATCH(
|
||||||
|
node,
|
||||||
|
node->implementation_identifier,
|
||||||
|
eclipse_cyclonedds_identifier,
|
||||||
|
return RMW_RET_INCORRECT_RMW_IMPLEMENTATION);
|
||||||
auto node_impl = static_cast<CddsNode *>(node->data);
|
auto node_impl = static_cast<CddsNode *>(node->data);
|
||||||
RET_NULL(node_impl);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// Though graph_cache methods are thread safe, both cache update and publishing have to also
|
// Though graph_cache methods are thread safe, both cache update and publishing have to also
|
||||||
|
@ -1314,11 +1342,13 @@ extern "C" rmw_ret_t rmw_destroy_node(rmw_node_t * node)
|
||||||
common->pub, static_cast<void *>(&participant_msg), nullptr);
|
common->pub, static_cast<void *>(&participant_msg), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
rmw_free(const_cast<char *>(node->name));
|
rmw_context_t * context = node->context;
|
||||||
rmw_free(const_cast<char *>(node->namespace_));
|
rcutils_allocator_t allocator = context->options.allocator;
|
||||||
node->context->impl->fini();
|
allocator.deallocate(const_cast<char *>(node->name), allocator.state);
|
||||||
rmw_node_free(node);
|
allocator.deallocate(const_cast<char *>(node->namespace_), allocator.state);
|
||||||
|
allocator.deallocate(node, allocator.state);
|
||||||
delete node_impl;
|
delete node_impl;
|
||||||
|
context->impl->fini();
|
||||||
return result_ret;
|
return result_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue