1616#define RCLCPP__STRATEGIES__MESSAGE_POOL_MEMORY_STRATEGY_HPP_
1717
1818#include < array>
19+ #include < cstring>
1920#include < memory>
2021#include < mutex>
2122#include < stdexcept>
@@ -58,11 +59,18 @@ class MessagePoolMemoryStrategy
5859 MessagePoolMemoryStrategy ()
5960 {
6061 for (size_t i = 0 ; i < Size; ++i) {
61- pool_[i] = std::make_shared< MessageT>() ;
62+ pool_[i] = new MessageT;
6263 free_list_.push_back (i);
6364 }
6465 }
6566
67+ ~MessagePoolMemoryStrategy ()
68+ {
69+ for (size_t i = 0 ; i < Size; ++i) {
70+ delete pool_[i];
71+ }
72+ }
73+
6674 // / Borrow a message from the message pool.
6775 /* *
6876 * Manage the message pool ring buffer.
@@ -73,23 +81,21 @@ class MessagePoolMemoryStrategy
7381 {
7482 std::lock_guard<std::mutex> lock (pool_mutex_);
7583 if (free_list_.size () == 0 ) {
76- for (size_t i = 0 ; i < Size; ++i) {
77- if (pool_[i].use_count () == 1 ) {
78- free_list_.push_back (i);
79- break ;
80- }
81- }
82- if (free_list_.size () == 0 ) {
83- throw std::runtime_error (" No more free slots in the pool" );
84- }
84+ throw std::runtime_error (" No more free slots in the pool" );
8585 }
8686
8787 size_t current_index = free_list_.pop_front ();
8888
89- pool_[current_index]->~MessageT ();
90- new (pool_[current_index].get ())MessageT;
91-
92- return pool_[current_index];
89+ return std::shared_ptr<MessageT>(
90+ pool_[current_index], [this ](MessageT * p) {
91+ for (size_t i = 0 ; i < Size; ++i) {
92+ if (pool_[i] == p) {
93+ p = {};
94+ free_list_.push_back (i);
95+ break ;
96+ }
97+ }
98+ });
9399 }
94100
95101 // / Return a message to the message pool.
@@ -100,28 +106,11 @@ class MessagePoolMemoryStrategy
100106 void return_message (std::shared_ptr<MessageT> & msg)
101107 {
102108 (void )msg;
103-
104- // What we really want to do here is to figure out whether the user has taken an additional
105- // reference to the message, and only add it to the free list if that is *not* the case.
106- // However, we can't really do that for the currently passed-in msg; it can have an arbitrary
107- // reference count due to the mechanisms of rclcpp. Instead, we look at all the rest of the
108- // pointers, and add the ones that the user has released into the free pool.
109- // We do the same thing in borrow_message(), so if the user has a pool of size 1
110- // (or only one free slot), we'll always find it.
111-
112- std::lock_guard<std::mutex> lock (pool_mutex_);
113- if (free_list_.size () == 0 ) {
114- for (size_t i = 0 ; i < Size; ++i) {
115- if (pool_[i].use_count () == 1 ) {
116- free_list_.push_back (i);
117- }
118- }
119- }
120109 }
121110
122111protected:
123112 template <size_t N>
124- class CyclicSizeTArray
113+ class CircularArray
125114 {
126115public:
127116 void push_back (const size_t v)
@@ -159,8 +148,8 @@ class MessagePoolMemoryStrategy
159148 };
160149
161150 std::mutex pool_mutex_;
162- std::array<std::shared_ptr< MessageT> , Size> pool_;
163- CyclicSizeTArray <Size> free_list_;
151+ std::array<MessageT * , Size> pool_;
152+ CircularArray <Size> free_list_;
164153};
165154
166155} // namespace message_pool_memory_strategy
0 commit comments