Skip to content

Commit

Permalink
Implement allocator refactor for type support structs
Browse files Browse the repository at this point in the history
Signed-off-by: methylDragon <[email protected]>
  • Loading branch information
methylDragon committed Apr 7, 2023
1 parent 2ab3722 commit 632e515
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 4 deletions.
46 changes: 45 additions & 1 deletion rmw/include/rmw/dynamic_message_type_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,50 @@ extern "C"
/// Interfaces for runtime interface reflection

// RUNTIME INTERFACE REFLECTION TYPE SUPPORT =======================================================
/// Get dynamic type message typesupport with bound message description
/// Initialize dynamic type message typesupport, binding message description
/**
* NOTE: Take note of the ownership rules for the returned struct and the `description` argument!
*
* If the user passes a NULL description, it is deferred instead, the middleware is responsibile
* for populating the fields on type discovery!!!
*
* Ownership:
* - The `rosidl_message_type_support_t *` returned from this function has different ownership
* rules compared to the statically allocated `rosidl_message_type_support_t` structs from
* code-generated types!
* - The caller is responsible for deallocating the returned pointer
*
* <hr>
* Attribute | Adherence
* ------------------ | -------------
* Allocates Memory | Yes
* Thread-Safe | No
* Uses Atomics | No
* Lock-Free | Yes
*/
RMW_PUBLIC
RMW_WARN_UNUSED
rmw_ret_t
rmw_dynamic_message_type_support_handle_init(
rosidl_dynamic_typesupport_serialization_support_t * serialization_support,
bool middleware_supports_type_discovery,
const rosidl_type_hash_t * type_hash,
const rosidl_runtime_c__type_description__TypeDescription * type_description,
const rosidl_runtime_c__type_description__TypeSource__Sequence * type_description_sources,
rcutils_allocator_t * allocator,
rosidl_message_type_support_t * ts); // OUT

/// Finalize a rosidl_message_type_support_t obtained with
/// `rmw_dynamic_message_type_support_handle_create()`, which has dynamically allocated members
///
/// NOTE: Using this on a statically allocated typesupport will cause undefined behavior!
/// (Static memory will get freed in that case.)
RMW_PUBLIC
RMW_WARN_UNUSED
rmw_ret_t
rmw_dynamic_message_type_support_handle_fini(rosidl_message_type_support_t * ts);

/// Create dynamic type message typesupport with bound message description
/**
* NOTE: Take note of the ownership rules for the returned struct and the `description` argument!
*
Expand Down Expand Up @@ -66,6 +109,7 @@ rmw_dynamic_message_type_support_handle_create(
const rosidl_type_hash_t * type_hash,
const rosidl_runtime_c__type_description__TypeDescription * type_description,
const rosidl_runtime_c__type_description__TypeSource__Sequence * type_description_sources,
rcutils_allocator_t * allocator,
rosidl_message_type_support_t ** ts); // OUT

/// Destroy a rosidl_message_type_support_t obtained with
Expand Down
54 changes: 51 additions & 3 deletions rmw/src/dynamic_message_type_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,60 @@ extern "C"

// NOTE(methylDragon): How do we test this? It depends on specific serialization support. Do I just
// use the FastRTPS support then?
rmw_ret_t
rmw_dynamic_message_type_support_handle_init(
rosidl_dynamic_typesupport_serialization_support_t * serialization_support,
bool middleware_supports_type_discovery,
const rosidl_type_hash_t * type_hash,
const rosidl_runtime_c__type_description__TypeDescription * type_description,
const rosidl_runtime_c__type_description__TypeSource__Sequence * type_description_sources,
rcutils_allocator_t * allocator,
rosidl_message_type_support_t * ts)
{
if (!middleware_supports_type_discovery && type_description == NULL) {
RMW_SET_ERROR_MSG(
"Middleware does not support type discovery. Deferred dynamic type message type support will "
"never be populated. You must provide a type description.");
return RMW_RET_INVALID_ARGUMENT;
}
// TODO(methylDragon): Remove if and when the deferred description path is supported
if (type_description == NULL) {
RMW_SET_ERROR_MSG(
"Deferred type description is not currently supported. You must provide a type description.");
return RMW_RET_INVALID_ARGUMENT;
}

RMW_CHECK_ARGUMENT_FOR_NULL(serialization_support, RMW_RET_INVALID_ARGUMENT);
RMW_CHECK_ARGUMENT_FOR_NULL(type_hash, RMW_RET_INVALID_ARGUMENT);
RMW_CHECK_ARGUMENT_FOR_NULL(type_description, RMW_RET_INVALID_ARGUMENT);
RMW_CHECK_ARGUMENT_FOR_NULL(allocator, RMW_RET_INVALID_ARGUMENT);
RMW_CHECK_ARGUMENT_FOR_NULL(ts, RMW_RET_INVALID_ARGUMENT);

// NOTE(methylDragon): Not supported for now
// RMW_CHECK_ARGUMENT_FOR_NULL(type_description_sources, RMW_RET_INVALID_ARGUMENT);

return rmw_convert_rcutils_ret_to_rmw_ret(
rosidl_dynamic_message_type_support_handle_init(
serialization_support, type_hash, type_description, type_description_sources, allocator, ts));
}

rmw_ret_t
rmw_dynamic_message_type_support_handle_fini(rosidl_message_type_support_t * ts)
{
if (!ts) {
return RCUTILS_RET_OK;
}
return rmw_convert_rcutils_ret_to_rmw_ret(rosidl_dynamic_message_type_support_handle_fini(ts));
}

/// Create a rosidl_message_type_support_t from a TypeDescription message
rmw_ret_t
rmw_dynamic_message_type_support_handle_create(
rosidl_dynamic_typesupport_serialization_support_t * serialization_support,
bool middleware_supports_type_discovery,
const rosidl_type_hash_t * type_hash,
const rosidl_runtime_c__type_description__TypeDescription * type_description,
const rosidl_runtime_c__type_description__TypeSource__Sequence * type_description_sources,
rcutils_allocator_t * allocator,
rosidl_message_type_support_t ** ts)
{
if (!middleware_supports_type_discovery && type_description == NULL) {
Expand All @@ -60,20 +105,23 @@ rmw_dynamic_message_type_support_handle_create(
RMW_CHECK_ARGUMENT_FOR_NULL(serialization_support, RMW_RET_INVALID_ARGUMENT);
RMW_CHECK_ARGUMENT_FOR_NULL(type_hash, RMW_RET_INVALID_ARGUMENT);
RMW_CHECK_ARGUMENT_FOR_NULL(type_description, RMW_RET_INVALID_ARGUMENT);
RMW_CHECK_ARGUMENT_FOR_NULL(allocator, RMW_RET_INVALID_ARGUMENT);
RMW_CHECK_ARGUMENT_FOR_NULL(ts, RMW_RET_INVALID_ARGUMENT);

// NOTE(methylDragon): Not supported for now
// RMW_CHECK_ARGUMENT_FOR_NULL(type_description_sources, RMW_RET_INVALID_ARGUMENT);

return rmw_convert_rcutils_ret_to_rmw_ret(
rosidl_dynamic_message_type_support_handle_create(
serialization_support, type_hash, type_description, type_description_sources, ts));
serialization_support, type_hash, type_description, type_description_sources, allocator, ts));
}

rmw_ret_t
rmw_dynamic_message_type_support_handle_destroy(rosidl_message_type_support_t * ts)
{
RCUTILS_CHECK_ARGUMENT_FOR_NULL(ts, RMW_RET_INVALID_ARGUMENT);
if (!ts) {
return RCUTILS_RET_OK;
}
return rmw_convert_rcutils_ret_to_rmw_ret(rosidl_dynamic_message_type_support_handle_destroy(ts));
}

Expand Down

0 comments on commit 632e515

Please sign in to comment.