1818#include < memory>
1919#include < stdexcept>
2020
21+ #include " rcl/types.h"
22+
2123#include " rclcpp/allocator/allocator_common.hpp"
24+ #include " rclcpp/exceptions.hpp"
2225#include " rclcpp/macros.hpp"
2326#include " rclcpp/visibility_control.hpp"
2427
28+ #include " rmw/serialized_message.h"
29+
2530namespace rclcpp
2631{
2732namespace message_memory_strategy
@@ -39,14 +44,29 @@ class MessageMemoryStrategy
3944 using MessageAlloc = typename MessageAllocTraits::allocator_type;
4045 using MessageDeleter = allocator::Deleter<MessageAlloc, MessageT>;
4146
47+ using SerializedMessageAllocTraits = allocator::AllocRebind<rcl_serialized_message_t , Alloc>;
48+ using SerializedMessageAlloc = typename SerializedMessageAllocTraits::allocator_type;
49+ using SerializedMessageDeleter =
50+ allocator::Deleter<SerializedMessageAlloc, rcl_serialized_message_t >;
51+
52+ using BufferAllocTraits = allocator::AllocRebind<char , Alloc>;
53+ using BufferAlloc = typename BufferAllocTraits::allocator_type;
54+ using BufferDeleter = allocator::Deleter<BufferAlloc, char >;
55+
4256 MessageMemoryStrategy ()
4357 {
4458 message_allocator_ = std::make_shared<MessageAlloc>();
59+ serialized_message_allocator_ = std::make_shared<SerializedMessageAlloc>();
60+ buffer_allocator_ = std::make_shared<BufferAlloc>();
61+ rcutils_allocator_ = allocator::get_rcl_allocator<char , BufferAlloc>(*buffer_allocator_.get ());
4562 }
4663
4764 explicit MessageMemoryStrategy (std::shared_ptr<Alloc> allocator)
4865 {
4966 message_allocator_ = std::make_shared<MessageAlloc>(*allocator.get ());
67+ serialized_message_allocator_ = std::make_shared<SerializedMessageAlloc>(*allocator.get ());
68+ buffer_allocator_ = std::make_shared<BufferAlloc>(*allocator.get ());
69+ rcutils_allocator_ = allocator::get_rcl_allocator<char , BufferAlloc>(*buffer_allocator_.get ());
5070 }
5171
5272 // / Default factory method
@@ -62,15 +82,60 @@ class MessageMemoryStrategy
6282 return std::allocate_shared<MessageT, MessageAlloc>(*message_allocator_.get ());
6383 }
6484
85+ virtual std::shared_ptr<rcl_serialized_message_t > borrow_serialized_message (size_t capacity)
86+ {
87+ auto msg = new rcl_serialized_message_t ;
88+ *msg = rmw_get_zero_initialized_serialized_message ();
89+ auto ret = rmw_serialized_message_init (msg, capacity, &rcutils_allocator_);
90+ if (ret != RCL_RET_OK) {
91+ rclcpp::exceptions::throw_from_rcl_error (ret);
92+ }
93+
94+ auto serialized_msg = std::shared_ptr<rcl_serialized_message_t >(msg,
95+ [](rmw_serialized_message_t * msg) {
96+ auto ret = rmw_serialized_message_fini (msg);
97+ delete msg;
98+ if (ret != RCL_RET_OK) {
99+ rclcpp::exceptions::throw_from_rcl_error (ret, " leaking memory" );
100+ }
101+ });
102+
103+ return serialized_msg;
104+ }
105+
106+ virtual std::shared_ptr<rcl_serialized_message_t > borrow_serialized_message ()
107+ {
108+ return borrow_serialized_message (default_buffer_capacity_);
109+ }
110+
111+ virtual void set_default_buffer_capacity (size_t capacity)
112+ {
113+ default_buffer_capacity_ = capacity;
114+ }
115+
65116 // / Release ownership of the message, which will deallocate it if it has no more owners.
66117 /* * \param[in] msg Shared pointer to the message we are returning. */
67118 virtual void return_message (std::shared_ptr<MessageT> & msg)
68119 {
69120 msg.reset ();
70121 }
71122
123+ virtual void return_serialized_message (std::shared_ptr<rcl_serialized_message_t > & serialized_msg)
124+ {
125+ serialized_msg.reset ();
126+ }
127+
72128 std::shared_ptr<MessageAlloc> message_allocator_;
73129 MessageDeleter message_deleter_;
130+
131+ std::shared_ptr<SerializedMessageAlloc> serialized_message_allocator_;
132+ SerializedMessageDeleter serialized_message_deleter_;
133+
134+ std::shared_ptr<BufferAlloc> buffer_allocator_;
135+ BufferDeleter buffer_deleter_;
136+ size_t default_buffer_capacity_ = 0 ;
137+
138+ rcutils_allocator_t rcutils_allocator_;
74139};
75140
76141} // namespace message_memory_strategy
0 commit comments