ROS 2 rclcpp + rcl - jazzy  jazzy
ROS 2 C++ Client Library with ROS Client Library
simple_events_queue.hpp
1 // Copyright 2023 iRobot Corporation.
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__EXPERIMENTAL__EXECUTORS__EVENTS_EXECUTOR__SIMPLE_EVENTS_QUEUE_HPP_
16 #define RCLCPP__EXPERIMENTAL__EXECUTORS__EVENTS_EXECUTOR__SIMPLE_EVENTS_QUEUE_HPP_
17 
18 #include <condition_variable>
19 #include <mutex>
20 #include <queue>
21 #include <utility>
22 
23 #include "rclcpp/experimental/executors/events_executor/events_queue.hpp"
24 
25 namespace rclcpp
26 {
27 namespace experimental
28 {
29 namespace executors
30 {
31 
39 {
40 public:
41  RCLCPP_PUBLIC
42  ~SimpleEventsQueue() override = default;
43 
49  RCLCPP_PUBLIC
50  void
52  {
54  single_event.num_events = 1;
55  {
56  std::unique_lock<std::mutex> lock(mutex_);
57  for (size_t ev = 0; ev < event.num_events; ev++) {
58  event_queue_.push(single_event);
59  }
60  }
61  events_queue_cv_.notify_one();
62  }
63 
69  RCLCPP_PUBLIC
70  bool
73  std::chrono::nanoseconds timeout = std::chrono::nanoseconds::max()) override
74  {
75  std::unique_lock<std::mutex> lock(mutex_);
76 
77  // Initialize to true because it's only needed if we have a valid timeout
78  bool has_data = true;
79  if (timeout != std::chrono::nanoseconds::max()) {
80  has_data =
81  events_queue_cv_.wait_for(lock, timeout, [this]() {return !event_queue_.empty();});
82  } else {
83  events_queue_cv_.wait(lock, [this]() {return !event_queue_.empty();});
84  }
85 
86  if (has_data) {
87  event = event_queue_.front();
88  event_queue_.pop();
89  return true;
90  }
91 
92  return false;
93  }
94 
100  RCLCPP_PUBLIC
101  bool
102  empty() const override
103  {
104  std::unique_lock<std::mutex> lock(mutex_);
105  return event_queue_.empty();
106  }
107 
113  RCLCPP_PUBLIC
114  size_t
115  size() const override
116  {
117  std::unique_lock<std::mutex> lock(mutex_);
118  return event_queue_.size();
119  }
120 
121 private:
122  // The underlying queue implementation
123  std::queue<rclcpp::experimental::executors::ExecutorEvent> event_queue_;
124  // Mutex to protect read/write access to the queue
125  mutable std::mutex mutex_;
126  // Variable used to notify when an event is added to the queue
127  std::condition_variable events_queue_cv_;
128 };
129 
130 } // namespace executors
131 } // namespace experimental
132 } // namespace rclcpp
133 
134 #endif // RCLCPP__EXPERIMENTAL__EXECUTORS__EVENTS_EXECUTOR__SIMPLE_EVENTS_QUEUE_HPP_
This abstract class can be used to implement different types of queues where ExecutorEvent can be sto...
This class implements an EventsQueue as a simple wrapper around a std::queue. It does not perform any...
RCLCPP_PUBLIC bool empty() const override
Test whether queue is empty Thread safe.
RCLCPP_PUBLIC bool dequeue(rclcpp::experimental::executors::ExecutorEvent &event, std::chrono::nanoseconds timeout=std::chrono::nanoseconds::max()) override
waits for an event until timeout, gets a single event Thread safe
RCLCPP_PUBLIC void enqueue(const rclcpp::experimental::executors::ExecutorEvent &event) override
enqueue event into the queue Thread safe
RCLCPP_PUBLIC size_t size() const override
Returns the number of elements in the queue. Thread safe.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.