Skip to content

Commit 165fbd3

Browse files
committed
Implement allocator refactor for type support structs
Signed-off-by: methylDragon <[email protected]>
1 parent d871af0 commit 165fbd3

File tree

2 files changed

+53
-34
lines changed

2 files changed

+53
-34
lines changed

rclcpp/include/rclcpp/dynamic_typesupport/dynamic_message_type_support.hpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_SUPPORT_HPP_
1616
#define RCLCPP__DYNAMIC_TYPESUPPORT__DYNAMIC_MESSAGE_TYPE_SUPPORT_HPP_
1717

18+
#include <rcl/allocator.h>
1819
#include <rosidl_dynamic_typesupport/types.h>
1920
#include <rosidl_runtime_c/message_type_support_struct.h>
2021
#include <rosidl_runtime_c/type_description/type_description__struct.h>
@@ -67,15 +68,17 @@ class DynamicMessageTypeSupport : public std::enable_shared_from_this<DynamicMes
6768
RCLCPP_PUBLIC
6869
DynamicMessageTypeSupport(
6970
const rosidl_runtime_c__type_description__TypeDescription & description,
70-
const std::string & serialization_library_name = "");
71+
const std::string & serialization_library_name = "",
72+
rcl_allocator_t allocator = rcl_get_default_allocator());
7173

7274
/// From description, for provided serialization support
7375
/// Does NOT take ownership of the description (copies instead.)
7476
/// Constructs type support top-down (calling `rmw_dynamic_message_type_support_handle_create()`)
7577
RCLCPP_PUBLIC
7678
DynamicMessageTypeSupport(
7779
DynamicSerializationSupport::SharedPtr serialization_support,
78-
const rosidl_runtime_c__type_description__TypeDescription & description);
80+
const rosidl_runtime_c__type_description__TypeDescription & description,
81+
rcl_allocator_t allocator = rcl_get_default_allocator());
7982

8083
/// Assume ownership of managed types
8184
/// Does NOT take ownership of the description (copies instead.)
@@ -158,7 +161,6 @@ class DynamicMessageTypeSupport : public std::enable_shared_from_this<DynamicMes
158161
DynamicMessage::ConstSharedPtr
159162
get_shared_dynamic_message() const;
160163

161-
162164
// METHODS =======================================================================================
163165
RCLCPP_PUBLIC
164166
void

rclcpp/src/rclcpp/dynamic_typesupport/dynamic_message_type_support.cpp

+48-31
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323

2424
#include "rcl/allocator.h"
2525
#include "rcl/dynamic_message_type_support.h"
26+
#include "rcl/error_handling.h"
2627
#include "rcl/type_hash.h"
2728
#include "rcl/types.h"
29+
#include "rcutils/allocator.h"
2830
#include "rcutils/logging_macros.h"
2931
#include "rmw/dynamic_message_type_support.h"
3032

@@ -46,7 +48,8 @@ using rclcpp::dynamic_typesupport::DynamicSerializationSupport;
4648
// CONSTRUCTION ====================================================================================
4749
DynamicMessageTypeSupport::DynamicMessageTypeSupport(
4850
const rosidl_runtime_c__type_description__TypeDescription & description,
49-
const std::string & serialization_library_name)
51+
const std::string & serialization_library_name,
52+
rcl_allocator_t allocator)
5053
: serialization_support_(nullptr),
5154
dynamic_message_type_(nullptr),
5255
dynamic_message_(nullptr),
@@ -57,13 +60,16 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport(
5760
rcl_ret_t ret;
5861

5962
if (serialization_library_name.empty()) {
60-
ret = rcl_dynamic_message_type_support_handle_create(nullptr, &description, &ts);
63+
ret = rcl_dynamic_message_type_support_handle_create(nullptr, &description, &allocator, &ts);
6164
} else {
6265
ret = rcl_dynamic_message_type_support_handle_create(
63-
serialization_library_name.c_str(), &description, &ts);
66+
serialization_library_name.c_str(), &description, &allocator, &ts);
6467
}
6568
if (ret != RCL_RET_OK) {
66-
throw std::runtime_error("error initializing rosidl message type support");
69+
auto msg = std::string("error initializing rosidl message type support:\n") +
70+
rcl_get_error_string().str;
71+
rcl_reset_error();
72+
throw std::runtime_error(msg);
6773
}
6874
if (!ts) {
6975
throw std::runtime_error("could not init rosidl message type support");
@@ -85,13 +91,16 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport(
8591
ts,
8692
[](rosidl_message_type_support_t * ts) -> void {
8793
auto ts_impl = static_cast<const rosidl_dynamic_message_type_support_impl_t *>(ts->data);
88-
auto allocator = rcl_get_default_allocator();
94+
// User might have passed in a different allocator, but the type hash was allocated using
95+
// the default
96+
rcutils_allocator_t type_hash_allocator = rcutils_get_default_allocator();
97+
auto impl_allocator = ts_impl->allocator;
8998

9099
// These are all C allocated
91-
allocator.deallocate(ts_impl->type_hash, &allocator.state);
92-
allocator.deallocate(
93-
const_cast<rosidl_dynamic_message_type_support_impl_t *>(ts_impl), &allocator.state);
94-
allocator.deallocate(ts, &allocator.state);
100+
type_hash_allocator.deallocate(ts_impl->type_hash, &type_hash_allocator.state);
101+
impl_allocator.deallocate(
102+
const_cast<rosidl_dynamic_message_type_support_impl_t *>(ts_impl), &impl_allocator.state);
103+
impl_allocator.deallocate(ts, &impl_allocator.state);
95104
}
96105
);
97106

@@ -112,7 +121,8 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport(
112121

113122
DynamicMessageTypeSupport::DynamicMessageTypeSupport(
114123
DynamicSerializationSupport::SharedPtr serialization_support,
115-
const rosidl_runtime_c__type_description__TypeDescription & description)
124+
const rosidl_runtime_c__type_description__TypeDescription & description,
125+
rcl_allocator_t allocator)
116126
: serialization_support_(serialization_support),
117127
dynamic_message_type_(nullptr),
118128
dynamic_message_(nullptr),
@@ -141,6 +151,7 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport(
141151
type_hash.get(), // type_hash
142152
&description, // type_description
143153
nullptr, // type_description_sources (not implemented for dynamic types)
154+
&allocator, // allocator
144155
&ts);
145156
if (ret != RMW_RET_OK || !ts) {
146157
throw std::runtime_error("could not init rosidl message type support");
@@ -158,13 +169,16 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport(
158169
// are managed by the passed in SharedPtr wrapper classes. We just delete it.
159170
rosidl_message_type_support_.reset(
160171
ts,
161-
[](rosidl_message_type_support_t * ts) -> void {
172+
[&](rosidl_message_type_support_t * ts) -> void {
162173
auto ts_impl = static_cast<const rosidl_dynamic_message_type_support_impl_t *>(ts->data);
174+
auto impl_allocator = ts_impl->allocator;
163175

164-
// These are allocated with new
165-
delete ts_impl->type_hash; // Only because we should've allocated it here
166-
delete ts_impl;
167-
delete ts;
176+
delete ts_impl->type_hash; // Only because we should've allocated it here with the unique ptr
177+
178+
// These are allocated with the allocator by rmw_dynamic_message_type_support_handle_create
179+
impl_allocator.deallocate(
180+
const_cast<rosidl_dynamic_message_type_support_impl_t *>(ts_impl), &impl_allocator.state);
181+
impl_allocator.deallocate(ts, &impl_allocator.state);
168182
}
169183
);
170184
manage_description_(ts_impl->type_description);
@@ -214,8 +228,7 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport(
214228
throw std::runtime_error("could not init type description.");
215229
}
216230
if (!rosidl_runtime_c__type_description__TypeDescription__copy(
217-
&description,
218-
description_.get()))
231+
&description, description_.get()))
219232
{
220233
throw std::runtime_error("could not copy type description.");
221234
}
@@ -311,12 +324,13 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_(
311324

312325
rosidl_dynamic_message_type_support_impl_t * ts_impl =
313326
new rosidl_dynamic_message_type_support_impl_t {
314-
type_hash.get(), // type_hash
315-
description, // type_description
316-
nullptr, // NOTE(methylDragon): Not supported for now // type_description_sources
317-
serialization_support->get_rosidl_serialization_support(), // serialization_support
318-
dynamic_message_type->get_rosidl_dynamic_type(), // dynamic_message_type
319-
dynamic_message->get_rosidl_dynamic_data() // dynamic_message
327+
rcutils_get_default_allocator(), // allocator
328+
type_hash.get(), // type_hash
329+
description, // type_description
330+
nullptr, // NOTE(methylDragon): Not supported for now // type_description_sources
331+
serialization_support->get_rosidl_serialization_support(), // serialization_support
332+
dynamic_message_type->get_rosidl_dynamic_type(), // dynamic_message_type
333+
dynamic_message->get_rosidl_dynamic_data() // dynamic_message
320334
};
321335
if (!ts_impl) {
322336
throw std::runtime_error(
@@ -326,26 +340,29 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_(
326340

327341
// NOTE(methylDragon): We don't finalize the rosidl_message_type_support->data since its members
328342
// are managed by the passed in SharedPtr wrapper classes. We just delete it.
343+
/* *INDENT-OFF* */
329344
rosidl_message_type_support_.reset(
330345
new rosidl_message_type_support_t{
331-
rmw_get_dynamic_typesupport_identifier(), // typesupport_identifier
332-
ts_impl, // data
333-
get_message_typesupport_handle_function, // func
334-
// get_type_hash_func
335-
rosidl_get_dynamic_message_type_support_type_hash_function,
336-
// get_type_description_func
337-
rosidl_get_dynamic_message_type_support_type_description_function,
346+
rmw_get_dynamic_typesupport_identifier(), // typesupport_identifier
347+
ts_impl, // data
348+
get_message_typesupport_handle_function, // func
349+
rosidl_get_dynamic_message_type_support_type_hash_function, // get_type_hash_func
350+
rosidl_get_dynamic_message_type_support_type_description_function, // get_type_description_func
338351
// get_type_description_sources_func
339352
rosidl_get_dynamic_message_type_support_type_description_sources_function
340-
},
353+
},
354+
// Custom deleter
341355
[](rosidl_message_type_support_t * ts) -> void {
342356
auto ts_impl = static_cast<const rosidl_dynamic_message_type_support_impl_t *>(ts->data);
357+
// User might have passed in a different allocator, but the type hash was allocated using
358+
// the default
343359
auto allocator = rcl_get_default_allocator();
344360
// Only because we should've allocated it here (also it's C allocated)
345361
allocator.deallocate(ts_impl->type_hash, &allocator.state);
346362
delete ts_impl;
347363
}
348364
);
365+
/* *INDENT-ON* */
349366

350367
if (!rosidl_message_type_support_) {
351368
throw std::runtime_error("Could not allocate rosidl_message_type_support_t struct");

0 commit comments

Comments
 (0)