ROS 2 rclcpp + rcl - humble  humble
ROS 2 C++ Client Library with ROS Client Library
message_pool_memory_strategy.hpp
1 // Copyright 2015 Open Source Robotics Foundation, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef RCLCPP__STRATEGIES__MESSAGE_POOL_MEMORY_STRATEGY_HPP_
16 #define RCLCPP__STRATEGIES__MESSAGE_POOL_MEMORY_STRATEGY_HPP_
17 
18 #include <memory>
19 
20 #include "rosidl_runtime_cpp/traits.hpp"
21 
22 #include "rclcpp/macros.hpp"
23 #include "rclcpp/message_memory_strategy.hpp"
24 #include "rclcpp/visibility_control.hpp"
25 
26 namespace rclcpp
27 {
28 namespace strategies
29 {
30 namespace message_pool_memory_strategy
31 {
32 
34 
40 template<
41  typename MessageT,
42  size_t Size,
43  typename std::enable_if<
44  rosidl_generator_traits::has_fixed_size<MessageT>::value
45  >::type * = nullptr
46 >
49 {
50 public:
51  RCLCPP_SMART_PTR_DEFINITIONS(MessagePoolMemoryStrategy)
52 
53 
55  : next_array_index_(0)
56  {
57  for (size_t i = 0; i < Size; ++i) {
58  pool_[i].msg_ptr_ = std::make_shared<MessageT>();
59  pool_[i].used = false;
60  }
61  }
62 
64 
69  std::shared_ptr<MessageT> borrow_message()
70  {
71  size_t current_index = next_array_index_;
72  next_array_index_ = (next_array_index_ + 1) % Size;
73  if (pool_[current_index].used) {
74  throw std::runtime_error("Tried to access message that was still in use! Abort.");
75  }
76  pool_[current_index].msg_ptr_->~MessageT();
77  new (pool_[current_index].msg_ptr_.get())MessageT;
78 
79  pool_[current_index].used = true;
80  return pool_[current_index].msg_ptr_;
81  }
82 
84 
88  void return_message(std::shared_ptr<MessageT> & msg)
89  {
90  for (size_t i = 0; i < Size; ++i) {
91  if (pool_[i].msg_ptr_ == msg) {
92  pool_[i].used = false;
93  return;
94  }
95  }
96  throw std::runtime_error("Unrecognized message ptr in return_message.");
97  }
98 
99 protected:
100  struct PoolMember
101  {
102  std::shared_ptr<MessageT> msg_ptr_;
103  bool used;
104  };
105 
106  std::array<PoolMember, Size> pool_;
107  size_t next_array_index_;
108 };
109 
110 } // namespace message_pool_memory_strategy
111 } // namespace strategies
112 } // namespace rclcpp
113 
114 #endif // RCLCPP__STRATEGIES__MESSAGE_POOL_MEMORY_STRATEGY_HPP_
Default allocation strategy for messages received by subscriptions.
std::shared_ptr< MessageT > borrow_message()
Borrow a message from the message pool.
void return_message(std::shared_ptr< MessageT > &msg)
Return a message to the message pool.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.