23
23
24
24
#include " rcl/allocator.h"
25
25
#include " rcl/dynamic_message_type_support.h"
26
+ #include " rcl/error_handling.h"
26
27
#include " rcl/type_hash.h"
27
28
#include " rcl/types.h"
29
+ #include " rcutils/allocator.h"
28
30
#include " rcutils/logging_macros.h"
29
31
#include " rmw/dynamic_message_type_support.h"
30
32
@@ -46,7 +48,8 @@ using rclcpp::dynamic_typesupport::DynamicSerializationSupport;
46
48
// CONSTRUCTION ====================================================================================
47
49
DynamicMessageTypeSupport::DynamicMessageTypeSupport (
48
50
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)
50
53
: serialization_support_(nullptr ),
51
54
dynamic_message_type_(nullptr ),
52
55
dynamic_message_(nullptr ),
@@ -57,13 +60,16 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport(
57
60
rcl_ret_t ret;
58
61
59
62
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);
61
64
} else {
62
65
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);
64
67
}
65
68
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);
67
73
}
68
74
if (!ts) {
69
75
throw std::runtime_error (" could not init rosidl message type support" );
@@ -85,13 +91,16 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport(
85
91
ts,
86
92
[](rosidl_message_type_support_t * ts) -> void {
87
93
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 ;
89
98
90
99
// 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 );
95
104
}
96
105
);
97
106
@@ -112,7 +121,8 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport(
112
121
113
122
DynamicMessageTypeSupport::DynamicMessageTypeSupport (
114
123
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)
116
126
: serialization_support_(serialization_support),
117
127
dynamic_message_type_(nullptr ),
118
128
dynamic_message_(nullptr ),
@@ -141,6 +151,7 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport(
141
151
type_hash.get (), // type_hash
142
152
&description, // type_description
143
153
nullptr , // type_description_sources (not implemented for dynamic types)
154
+ &allocator, // allocator
144
155
&ts);
145
156
if (ret != RMW_RET_OK || !ts) {
146
157
throw std::runtime_error (" could not init rosidl message type support" );
@@ -158,13 +169,16 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport(
158
169
// are managed by the passed in SharedPtr wrapper classes. We just delete it.
159
170
rosidl_message_type_support_.reset (
160
171
ts,
161
- [](rosidl_message_type_support_t * ts) -> void {
172
+ [& ](rosidl_message_type_support_t * ts) -> void {
162
173
auto ts_impl = static_cast <const rosidl_dynamic_message_type_support_impl_t *>(ts->data );
174
+ auto impl_allocator = ts_impl->allocator ;
163
175
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 );
168
182
}
169
183
);
170
184
manage_description_ (ts_impl->type_description );
@@ -214,8 +228,7 @@ DynamicMessageTypeSupport::DynamicMessageTypeSupport(
214
228
throw std::runtime_error (" could not init type description." );
215
229
}
216
230
if (!rosidl_runtime_c__type_description__TypeDescription__copy (
217
- &description,
218
- description_.get ()))
231
+ &description, description_.get ()))
219
232
{
220
233
throw std::runtime_error (" could not copy type description." );
221
234
}
@@ -311,12 +324,13 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_(
311
324
312
325
rosidl_dynamic_message_type_support_impl_t * ts_impl =
313
326
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
320
334
};
321
335
if (!ts_impl) {
322
336
throw std::runtime_error (
@@ -326,26 +340,29 @@ DynamicMessageTypeSupport::init_rosidl_message_type_support_(
326
340
327
341
// NOTE(methylDragon): We don't finalize the rosidl_message_type_support->data since its members
328
342
// are managed by the passed in SharedPtr wrapper classes. We just delete it.
343
+ /* *INDENT-OFF* */
329
344
rosidl_message_type_support_.reset (
330
345
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
338
351
// get_type_description_sources_func
339
352
rosidl_get_dynamic_message_type_support_type_description_sources_function
340
- },
353
+ },
354
+ // Custom deleter
341
355
[](rosidl_message_type_support_t * ts) -> void {
342
356
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
343
359
auto allocator = rcl_get_default_allocator ();
344
360
// Only because we should've allocated it here (also it's C allocated)
345
361
allocator.deallocate (ts_impl->type_hash , &allocator.state );
346
362
delete ts_impl;
347
363
}
348
364
);
365
+ /* *INDENT-ON* */
349
366
350
367
if (!rosidl_message_type_support_) {
351
368
throw std::runtime_error (" Could not allocate rosidl_message_type_support_t struct" );
0 commit comments