15 #ifndef RCLCPP__WAIT_SET_TEMPLATE_HPP_
16 #define RCLCPP__WAIT_SET_TEMPLATE_HPP_
46 template<
class SynchronizationPolicy,
class StoragePolicy>
47 class WaitSetTemplate final :
private SynchronizationPolicy,
private StoragePolicy
52 using typename StoragePolicy::SubscriptionEntry;
53 using typename StoragePolicy::WaitableEntry;
72 const typename StoragePolicy::SubscriptionsIterable & subscriptions = {},
73 const typename StoragePolicy::GuardConditionsIterable & guard_conditions = {},
74 const typename StoragePolicy::TimersIterable & timers = {},
75 const typename StoragePolicy::ClientsIterable & clients = {},
76 const typename StoragePolicy::ServicesIterable & services = {},
77 const typename StoragePolicy::WaitablesIterable & waitables = {},
78 rclcpp::Context::SharedPtr context =
80 : SynchronizationPolicy(context),
85 this->get_extra_guard_conditions(),
103 return this->storage_get_rcl_wait_set();
134 if (
nullptr == subscription) {
138 this->sync_add_subscription(
149 auto local_subscription = inner_subscription;
150 bool already_in_use =
151 local_subscription->exchange_in_use_by_wait_set_state(local_subscription.get(), true);
152 if (already_in_use) {
153 throw std::runtime_error(
"subscription already associated with a wait set");
155 this->storage_add_subscription(
std::move(local_subscription));
158 for (auto event : inner_subscription->get_event_handlers()) {
159 auto local_subscription = inner_subscription;
160 bool already_in_use =
161 local_subscription->exchange_in_use_by_wait_set_state(event.get(), true);
162 if (already_in_use) {
163 throw std::runtime_error(
"subscription event already associated with a wait set");
165 this->storage_add_waitable(std::move(event), std::move(local_subscription));
169 auto local_subscription = inner_subscription;
170 auto waitable = inner_subscription->get_intra_process_waitable();
171 if (nullptr != waitable) {
172 bool already_in_use = local_subscription->exchange_in_use_by_wait_set_state(
175 if (already_in_use) {
176 throw std::runtime_error(
177 "subscription intra-process waitable already associated with a wait set");
179 this->storage_add_waitable(
180 std::move(inner_subscription->get_intra_process_waitable()),
181 std::move(local_subscription));
208 if (
nullptr == subscription) {
212 this->sync_remove_subscription(
223 auto local_subscription = inner_subscription;
224 local_subscription->exchange_in_use_by_wait_set_state(local_subscription.get(), false);
225 this->storage_remove_subscription(std::move(local_subscription));
228 for (auto event : inner_subscription->get_event_handlers()) {
229 auto local_subscription = inner_subscription;
230 local_subscription->exchange_in_use_by_wait_set_state(event.get(), false);
231 this->storage_remove_waitable(std::move(event));
235 auto local_waitable = inner_subscription->get_intra_process_waitable();
236 if (nullptr != local_waitable) {
238 inner_subscription->exchange_in_use_by_wait_set_state(local_waitable.get(), false);
239 this->storage_remove_waitable(std::move(local_waitable));
275 if (
nullptr == guard_condition) {
279 this->sync_add_guard_condition(
282 bool already_in_use = inner_guard_condition->exchange_in_use_by_wait_set_state(
true);
283 if (already_in_use) {
289 this->storage_add_guard_condition(
std::move(inner_guard_condition));
315 if (
nullptr == guard_condition) {
319 this->sync_remove_guard_condition(
322 inner_guard_condition->exchange_in_use_by_wait_set_state(
false);
326 this->storage_remove_guard_condition(
std::move(inner_guard_condition));
343 if (
nullptr == timer) {
347 this->sync_add_timer(
350 bool already_in_use = inner_timer->exchange_in_use_by_wait_set_state(
true);
351 if (already_in_use) {
357 this->storage_add_timer(
std::move(inner_timer));
373 if (
nullptr == timer) {
377 this->sync_remove_timer(
380 inner_timer->exchange_in_use_by_wait_set_state(
false);
384 this->storage_remove_timer(
std::move(inner_timer));
401 if (
nullptr == client) {
405 this->sync_add_client(
408 bool already_in_use = inner_client->exchange_in_use_by_wait_set_state(
true);
409 if (already_in_use) {
415 this->storage_add_client(
std::move(inner_client));
431 if (
nullptr == client) {
435 this->sync_remove_client(
438 inner_client->exchange_in_use_by_wait_set_state(
false);
442 this->storage_remove_client(
std::move(inner_client));
459 if (
nullptr == service) {
463 this->sync_add_service(
466 bool already_in_use = inner_service->exchange_in_use_by_wait_set_state(
true);
467 if (already_in_use) {
473 this->storage_add_service(
std::move(inner_service));
489 if (
nullptr == service) {
493 this->sync_remove_service(
496 inner_service->exchange_in_use_by_wait_set_state(
false);
500 this->storage_remove_service(
std::move(inner_service));
533 if (
nullptr == waitable) {
537 this->sync_add_waitable(
544 bool already_in_use = inner_waitable->exchange_in_use_by_wait_set_state(
true);
545 if (already_in_use) {
567 if (
nullptr == waitable) {
571 this->sync_remove_waitable(
574 inner_waitable->exchange_in_use_by_wait_set_state(
false);
578 this->storage_remove_waitable(
std::move(inner_waitable));
602 this->sync_prune_deleted_entities(
606 this->storage_prune_deleted_entities();
651 template<
class Rep =
int64_t,
class Period = std::milli>
656 auto time_to_wait_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(time_to_wait);
659 this->storage_acquire_ownerships();
663 return this->
template sync_wait<WaitResult<WaitSetTemplate>>(
669 this->storage_rebuild_rcl_wait_set(
671 this->get_extra_guard_conditions()
677 return this->storage_get_rcl_wait_set();
682 switch (wait_result_kind) {
690 auto msg =
"unknown WaitResultKind with value: " +
std::to_string(wait_result_kind);
710 wait_result_acquire()
712 if (wait_result_holding_) {
715 wait_result_holding_ =
true;
717 this->sync_wait_result_acquire();
719 this->storage_acquire_ownerships();
729 wait_result_release()
731 if (!wait_result_holding_) {
734 wait_result_holding_ =
false;
736 this->storage_release_ownerships();
738 this->sync_wait_result_release();
741 bool wait_result_holding_ =
false;
746 #endif // RCLCPP__WAIT_SET_TEMPLATE_HPP_