15 #ifndef RCLCPP__WAIT_SET_POLICIES__DETAIL__STORAGE_POLICY_COMMON_HPP_
16 #define RCLCPP__WAIT_SET_POLICIES__DETAIL__STORAGE_POLICY_COMMON_HPP_
24 #include "rclcpp/exceptions.hpp"
25 #include "rclcpp/logging.hpp"
26 #include "rclcpp/macros.hpp"
27 #include "rclcpp/visibility_control.hpp"
28 #include "rclcpp/waitable.hpp"
32 namespace wait_set_policies
38 template<
bool HasStrongOwnership>
43 class SubscriptionsIterable,
44 class GuardConditionsIterable,
45 class ExtraGuardConditionsIterable,
47 class ClientsIterable,
48 class ServicesIterable,
49 class WaitablesIterable
53 const SubscriptionsIterable & subscriptions,
54 const GuardConditionsIterable & guard_conditions,
55 const ExtraGuardConditionsIterable & extra_guard_conditions,
56 const TimersIterable & timers,
57 const ClientsIterable & clients,
58 const ServicesIterable & services,
59 const WaitablesIterable & waitables,
60 rclcpp::Context::SharedPtr context
65 if (
nullptr == context) {
66 throw std::invalid_argument(
"context is nullptr");
69 size_t subscriptions_from_waitables = 0;
70 size_t guard_conditions_from_waitables = 0;
71 size_t timers_from_waitables = 0;
72 size_t clients_from_waitables = 0;
73 size_t services_from_waitables = 0;
74 size_t events_from_waitables = 0;
75 for (
const auto & waitable_entry : waitables) {
76 auto waitable_ptr_pair = get_raw_pointer_from_smart_pointer(waitable_entry.waitable);
77 if (
nullptr == waitable_ptr_pair.second) {
78 if (HasStrongOwnership) {
79 throw std::runtime_error(
"unexpected condition, fixed storage policy needs pruning");
82 needs_pruning_ =
true;
97 subscriptions.size() + subscriptions_from_waitables,
98 guard_conditions.size() + extra_guard_conditions.size() + guard_conditions_from_waitables,
99 timers.size() + timers_from_waitables,
100 clients.size() + clients_from_waitables,
101 services.size() + services_from_waitables,
102 events_from_waitables,
103 context_->get_rcl_context().get(),
107 rclcpp::exceptions::throw_from_rcl_error(ret);
114 extra_guard_conditions,
126 rclcpp::exceptions::throw_from_rcl_error(ret);
127 }
catch (
const std::exception & exception) {
130 "Error in destruction of rcl wait set: %s", exception.what());
135 template<
class EntityT>
136 std::pair<void *, EntityT *>
137 get_raw_pointer_from_smart_pointer(
const std::shared_ptr<EntityT> & shared_pointer)
139 return {
nullptr, shared_pointer.get()};
142 template<
class EntityT>
143 std::pair<std::shared_ptr<EntityT>, EntityT *>
144 get_raw_pointer_from_smart_pointer(
const std::weak_ptr<EntityT> & weak_pointer)
146 auto shared_pointer = weak_pointer.lock();
147 return {shared_pointer, shared_pointer.get()};
159 class SubscriptionsIterable,
160 class GuardConditionsIterable,
161 class ExtraGuardConditionsIterable,
162 class TimersIterable,
163 class ClientsIterable,
164 class ServicesIterable,
165 class WaitablesIterable
169 const SubscriptionsIterable & subscriptions,
170 const GuardConditionsIterable & guard_conditions,
171 const ExtraGuardConditionsIterable & extra_guard_conditions,
172 const TimersIterable & timers,
173 const ClientsIterable & clients,
174 const ServicesIterable & services,
175 const WaitablesIterable & waitables
178 bool was_resized =
false;
188 size_t subscriptions_from_waitables = 0;
189 size_t guard_conditions_from_waitables = 0;
190 size_t timers_from_waitables = 0;
191 size_t clients_from_waitables = 0;
192 size_t services_from_waitables = 0;
193 size_t events_from_waitables = 0;
194 for (
const auto & waitable_entry : waitables) {
195 auto waitable_ptr_pair = get_raw_pointer_from_smart_pointer(waitable_entry.waitable);
196 if (
nullptr == waitable_ptr_pair.second) {
198 if (HasStrongOwnership) {
201 throw std::runtime_error(
"unexpected condition, fixed storage policy needs pruning");
204 needs_pruning_ =
true;
217 subscriptions.size() + subscriptions_from_waitables,
218 guard_conditions.size() + extra_guard_conditions.size() + guard_conditions_from_waitables,
219 timers.size() + timers_from_waitables,
220 clients.size() + clients_from_waitables,
221 services.size() + services_from_waitables,
222 events_from_waitables
225 rclcpp::exceptions::throw_from_rcl_error(ret);
233 needs_resize_ =
false;
241 rclcpp::exceptions::throw_from_rcl_error(ret);
246 for (
const auto & subscription_entry : subscriptions) {
247 auto subscription_ptr_pair =
248 get_raw_pointer_from_smart_pointer(subscription_entry.subscription);
249 if (
nullptr == subscription_ptr_pair.second) {
251 if (HasStrongOwnership) {
254 throw std::runtime_error(
"unexpected condition, fixed storage policy needs pruning");
257 needs_pruning_ =
true;
262 subscription_ptr_pair.second->get_subscription_handle().get(),
265 rclcpp::exceptions::throw_from_rcl_error(ret);
270 auto add_guard_conditions =
271 [
this](
const auto & inner_guard_conditions)
273 for (
const auto & guard_condition : inner_guard_conditions) {
274 auto guard_condition_ptr_pair = get_raw_pointer_from_smart_pointer(guard_condition);
275 if (
nullptr == guard_condition_ptr_pair.second) {
277 if (HasStrongOwnership) {
280 throw std::runtime_error(
"unexpected condition, fixed storage policy needs pruning");
283 needs_pruning_ =
true;
288 &guard_condition_ptr_pair.second->get_rcl_guard_condition(),
291 rclcpp::exceptions::throw_from_rcl_error(ret);
297 add_guard_conditions(guard_conditions);
300 add_guard_conditions(extra_guard_conditions);
303 for (
const auto & timer : timers) {
304 auto timer_ptr_pair = get_raw_pointer_from_smart_pointer(timer);
305 if (
nullptr == timer_ptr_pair.second) {
307 if (HasStrongOwnership) {
310 throw std::runtime_error(
"unexpected condition, fixed storage policy needs pruning");
313 needs_pruning_ =
true;
318 timer_ptr_pair.second->get_timer_handle().get(),
321 rclcpp::exceptions::throw_from_rcl_error(ret);
326 for (
const auto & client : clients) {
327 auto client_ptr_pair = get_raw_pointer_from_smart_pointer(client);
328 if (
nullptr == client_ptr_pair.second) {
330 if (HasStrongOwnership) {
333 throw std::runtime_error(
"unexpected condition, fixed storage policy needs pruning");
336 needs_pruning_ =
true;
341 client_ptr_pair.second->get_client_handle().get(),
344 rclcpp::exceptions::throw_from_rcl_error(ret);
349 for (
const auto & service : services) {
350 auto service_ptr_pair = get_raw_pointer_from_smart_pointer(service);
351 if (
nullptr == service_ptr_pair.second) {
353 if (HasStrongOwnership) {
356 throw std::runtime_error(
"unexpected condition, fixed storage policy needs pruning");
359 needs_pruning_ =
true;
364 service_ptr_pair.second->get_service_handle().get(),
367 rclcpp::exceptions::throw_from_rcl_error(ret);
372 for (
auto & waitable_entry : waitables) {
373 auto waitable_ptr_pair = get_raw_pointer_from_smart_pointer(waitable_entry.waitable);
374 if (
nullptr == waitable_ptr_pair.second) {
376 if (HasStrongOwnership) {
379 throw std::runtime_error(
"unexpected condition, fixed storage policy needs pruning");
382 needs_pruning_ =
true;
391 storage_get_rcl_wait_set()
const
393 return rcl_wait_set_;
397 storage_get_rcl_wait_set()
399 return rcl_wait_set_;
403 storage_flag_for_resize()
405 needs_resize_ =
true;
409 rclcpp::Context::SharedPtr context_;
411 bool needs_pruning_ =
false;
412 bool needs_resize_ =
false;
#define rcl_get_default_allocator
Return a properly initialized rcl_allocator_t with default values.
virtual RCLCPP_PUBLIC void add_to_wait_set(rcl_wait_set_t *wait_set)=0
Add the Waitable to a wait set.
virtual RCLCPP_PUBLIC size_t get_number_of_ready_guard_conditions()
Get the number of ready guard_conditions.
virtual RCLCPP_PUBLIC size_t get_number_of_ready_timers()
Get the number of ready timers.
virtual RCLCPP_PUBLIC size_t get_number_of_ready_clients()
Get the number of ready clients.
virtual RCLCPP_PUBLIC size_t get_number_of_ready_events()
Get the number of ready events.
virtual RCLCPP_PUBLIC size_t get_number_of_ready_subscriptions()
Get the number of ready subscriptions.
virtual RCLCPP_PUBLIC size_t get_number_of_ready_services()
Get the number of ready services.
Common structure for storage policies, which provides rcl wait set access.
void storage_rebuild_rcl_wait_set_with_sets(const SubscriptionsIterable &subscriptions, const GuardConditionsIterable &guard_conditions, const ExtraGuardConditionsIterable &extra_guard_conditions, const TimersIterable &timers, const ClientsIterable &clients, const ServicesIterable &services, const WaitablesIterable &waitables)
Rebuild the wait set, preparing it for the next wait call.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
RCLCPP_PUBLIC Logger get_logger(const std::string &name)
Return a named logger.
Container for subscription's, guard condition's, etc to be waited on.
#define RCL_RET_OK
Success return code.
rmw_ret_t rcl_ret_t
The type that holds an rcl return code.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_wait_set_add_subscription(rcl_wait_set_t *wait_set, const rcl_subscription_t *subscription, size_t *index)
Store a pointer to the given subscription in the next empty spot in the set.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_wait_set_add_service(rcl_wait_set_t *wait_set, const rcl_service_t *service, size_t *index)
Store a pointer to the service in the next empty spot in the set.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_wait_set_init(rcl_wait_set_t *wait_set, size_t number_of_subscriptions, size_t number_of_guard_conditions, size_t number_of_timers, size_t number_of_clients, size_t number_of_services, size_t number_of_events, rcl_context_t *context, rcl_allocator_t allocator)
Initialize a rcl wait set with space for items to be waited on.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_wait_set_clear(rcl_wait_set_t *wait_set)
Remove (sets to NULL) all entities in the wait set.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_wait_set_add_timer(rcl_wait_set_t *wait_set, const rcl_timer_t *timer, size_t *index)
Store a pointer to the timer in the next empty spot in the set.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_wait_set_add_client(rcl_wait_set_t *wait_set, const rcl_client_t *client, size_t *index)
Store a pointer to the client in the next empty spot in the set.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_wait_set_fini(rcl_wait_set_t *wait_set)
Finalize a rcl wait set.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_wait_set_resize(rcl_wait_set_t *wait_set, size_t subscriptions_size, size_t guard_conditions_size, size_t timers_size, size_t clients_size, size_t services_size, size_t events_size)
Reallocate space for entities in the wait set.
RCL_PUBLIC RCL_WARN_UNUSED rcl_wait_set_t rcl_get_zero_initialized_wait_set(void)
Return a rcl_wait_set_t struct with members set to NULL.
RCL_PUBLIC RCL_WARN_UNUSED rcl_ret_t rcl_wait_set_add_guard_condition(rcl_wait_set_t *wait_set, const rcl_guard_condition_t *guard_condition, size_t *index)
Store a pointer to the guard condition in the next empty spot in the set.