iceoryx_posh  2.0.2
wait_set.hpp
1 // Copyright (c) 2020 - 2021 by Robert Bosch GmbH. All rights reserved.
2 // Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 // SPDX-License-Identifier: Apache-2.0
17 #ifndef IOX_POSH_POPO_WAIT_SET_HPP
18 #define IOX_POSH_POPO_WAIT_SET_HPP
19 
20 #include "iceoryx_hoofs/cxx/algorithm.hpp"
21 #include "iceoryx_hoofs/cxx/function_ref.hpp"
22 #include "iceoryx_hoofs/cxx/helplets.hpp"
23 #include "iceoryx_hoofs/cxx/list.hpp"
24 #include "iceoryx_hoofs/cxx/method_callback.hpp"
25 #include "iceoryx_hoofs/cxx/stack.hpp"
26 #include "iceoryx_hoofs/cxx/vector.hpp"
27 #include "iceoryx_posh/iceoryx_posh_types.hpp"
28 #include "iceoryx_posh/internal/popo/building_blocks/condition_listener.hpp"
29 #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp"
30 #include "iceoryx_posh/popo/enum_trigger_type.hpp"
31 #include "iceoryx_posh/popo/notification_attorney.hpp"
32 #include "iceoryx_posh/popo/notification_callback.hpp"
33 #include "iceoryx_posh/popo/notification_info.hpp"
34 #include "iceoryx_posh/popo/trigger.hpp"
35 #include "iceoryx_posh/popo/trigger_handle.hpp"
36 #include "iceoryx_posh/runtime/posh_runtime.hpp"
37 
38 #include <typeinfo>
39 
40 namespace iox
41 {
42 namespace popo
43 {
44 class Condition;
45 
46 enum class WaitSetError : uint8_t
47 {
48  WAIT_SET_FULL,
49  ALREADY_ATTACHED,
50 };
51 
52 
59 template <uint64_t Capacity = MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET>
60 class WaitSet
61 {
62  public:
63  static constexpr uint64_t CAPACITY = Capacity;
64  using TriggerArray = cxx::optional<Trigger>[Capacity];
65  using NotificationInfoVector = cxx::vector<const NotificationInfo*, CAPACITY>;
66 
67  WaitSet() noexcept;
68  ~WaitSet() noexcept;
69 
72  WaitSet(const WaitSet& rhs) = delete;
73  WaitSet(WaitSet&& rhs) = delete;
74  WaitSet& operator=(const WaitSet& rhs) = delete;
75  WaitSet& operator=(WaitSet&& rhs) = delete;
76 
81  void markForDestruction() noexcept;
82 
90  template <typename T,
91  typename EventType,
92  typename ContextDataType = internal::NoType_t,
93  typename = std::enable_if_t<std::is_enum<EventType>::value>>
94  cxx::expected<WaitSetError>
95  attachEvent(T& eventOrigin,
96  const EventType eventType,
97  const uint64_t notificationId = 0U,
98  const NotificationCallback<T, ContextDataType>& eventCallback = {}) noexcept;
99 
106  template <typename T,
107  typename EventType,
108  typename ContextDataType = internal::NoType_t,
109  typename = std::enable_if_t<std::is_enum<EventType>::value, void>>
110  cxx::expected<WaitSetError> attachEvent(T& eventOrigin,
111  const EventType eventType,
112  const NotificationCallback<T, ContextDataType>& eventCallback) noexcept;
113 
120  template <typename T, typename ContextDataType = internal::NoType_t>
121  cxx::expected<WaitSetError>
122  attachEvent(T& eventOrigin,
123  const uint64_t notificationId = 0U,
124  const NotificationCallback<T, ContextDataType>& eventCallback = {}) noexcept;
125 
131  template <typename T, typename ContextDataType = internal::NoType_t>
132  cxx::expected<WaitSetError> attachEvent(T& eventOrigin,
133  const NotificationCallback<T, ContextDataType>& eventCallback) noexcept;
134 
142  template <typename T,
143  typename StateType,
144  typename ContextDataType = internal::NoType_t,
145  typename = std::enable_if_t<std::is_enum<StateType>::value>>
146  cxx::expected<WaitSetError>
147  attachState(T& stateOrigin,
148  const StateType stateType,
149  const uint64_t id = 0U,
150  const NotificationCallback<T, ContextDataType>& stateCallback = {}) noexcept;
151 
158  template <typename T,
159  typename StateType,
160  typename ContextDataType = internal::NoType_t,
161  typename = std::enable_if_t<std::is_enum<StateType>::value, void>>
162  cxx::expected<WaitSetError> attachState(T& stateOrigin,
163  const StateType stateType,
164  const NotificationCallback<T, ContextDataType>& stateCallback) noexcept;
165 
172  template <typename T, typename ContextDataType = internal::NoType_t>
173  cxx::expected<WaitSetError>
174  attachState(T& stateOrigin,
175  const uint64_t id = 0U,
176  const NotificationCallback<T, ContextDataType>& stateCallback = {}) noexcept;
177 
183  template <typename T, typename ContextDataType = internal::NoType_t>
184  cxx::expected<WaitSetError> attachState(T& stateOrigin,
185  const NotificationCallback<T, ContextDataType>& stateCallback) noexcept;
186 
190  template <typename T, typename... Targs>
191  void detachEvent(T& eventOrigin, const Targs&... args) noexcept;
192 
196  template <typename T, typename... Targs>
197  void detachState(T& stateOrigin, const Targs&... args) noexcept;
198 
202  NotificationInfoVector timedWait(const units::Duration timeout) noexcept;
203 
206  NotificationInfoVector wait() noexcept;
207 
209  uint64_t size() const noexcept;
210 
212  static constexpr uint64_t capacity() noexcept;
213 
214  protected:
215  explicit WaitSet(ConditionVariableData& condVarData) noexcept;
216 
217  private:
218  enum class NoStateEnumUsed : StateEnumIdentifier
219  {
220  PLACEHOLDER
221  };
222 
223  enum class NoEventEnumUsed : EventEnumIdentifier
224  {
225  PLACEHOLDER
226  };
227 
228  using WaitFunction = cxx::function_ref<ConditionListener::NotificationVector_t()>;
229  template <typename T, typename ContextDataType>
230  cxx::expected<uint64_t, WaitSetError> attachImpl(T& eventOrigin,
231  const WaitSetIsConditionSatisfiedCallback& hasTriggeredCallback,
232  const uint64_t notificationId,
233  const NotificationCallback<T, ContextDataType>& eventCallback,
234  const uint64_t originType,
235  const uint64_t originTypeHash) noexcept;
236 
237  NotificationInfoVector waitAndReturnTriggeredTriggers(const WaitFunction& wait) noexcept;
238  NotificationInfoVector createVectorWithTriggeredTriggers() noexcept;
239 
240  void removeTrigger(const uint64_t uniqueTriggerId) noexcept;
241  void removeAllTriggers() noexcept;
242  void acquireNotifications(const WaitFunction& wait) noexcept;
243 
244  private:
246  TriggerArray m_triggerArray;
247  ConditionVariableData* m_conditionVariableDataPtr{nullptr};
248  ConditionListener m_conditionListener;
249 
250  cxx::stack<uint64_t, Capacity> m_indexRepository;
251  ConditionListener::NotificationVector_t m_activeNotifications;
252 };
253 
254 } // namespace popo
255 } // namespace iox
256 
257 #include "iceoryx_posh/internal/popo/wait_set.inl"
258 
259 #endif // IOX_POSH_POPO_WAIT_SET_HPP
Logical disjunction of a certain number of Triggers.
Definition: wait_set.hpp:61
cxx::expected< WaitSetError > attachEvent(T &eventOrigin, const EventType eventType, const NotificationCallback< T, ContextDataType > &eventCallback) noexcept
attaches an event of a given class to the WaitSet.
NotificationInfoVector wait() noexcept
Blocking wait till one or more of the triggers are triggered.
void markForDestruction() noexcept
Non-reversible call. After this call wait() and timedWait() do not block any longer and never return ...
cxx::expected< WaitSetError > attachState(T &stateOrigin, const uint64_t id=0U, const NotificationCallback< T, ContextDataType > &stateCallback={}) noexcept
attaches a state of a given class to the WaitSet.
cxx::expected< WaitSetError > attachEvent(T &eventOrigin, const EventType eventType, const uint64_t notificationId=0U, const NotificationCallback< T, ContextDataType > &eventCallback={}) noexcept
attaches an event of a given class to the WaitSet.
static constexpr uint64_t capacity() noexcept
returns the maximum amount of triggers which can be acquired from a waitset
NotificationInfoVector timedWait(const units::Duration timeout) noexcept
Blocking wait with time limit till one or more of the triggers are triggered.
cxx::expected< WaitSetError > attachEvent(T &eventOrigin, const NotificationCallback< T, ContextDataType > &eventCallback) noexcept
attaches an event of a given class to the WaitSet.
cxx::expected< WaitSetError > attachState(T &stateOrigin, const StateType stateType, const uint64_t id=0U, const NotificationCallback< T, ContextDataType > &stateCallback={}) noexcept
attaches a state of a given class to the WaitSet.
void detachState(T &stateOrigin, const Targs &... args) noexcept
detaches a state based trigger from the WaitSet
WaitSet(const WaitSet &rhs)=delete
all the Trigger have a pointer pointing to this waitset for cleanup calls, therefore the WaitSet cann...
cxx::expected< WaitSetError > attachState(T &stateOrigin, const NotificationCallback< T, ContextDataType > &stateCallback) noexcept
attaches a state of a given class to the WaitSet.
cxx::expected< WaitSetError > attachState(T &stateOrigin, const StateType stateType, const NotificationCallback< T, ContextDataType > &stateCallback) noexcept
attaches a state of a given class to the WaitSet.
void detachEvent(T &eventOrigin, const Targs &... args) noexcept
detaches an event from the WaitSet
uint64_t size() const noexcept
Returns the amount of stored Trigger inside of the WaitSet.
cxx::expected< WaitSetError > attachEvent(T &eventOrigin, const uint64_t notificationId=0U, const NotificationCallback< T, ContextDataType > &eventCallback={}) noexcept
attaches an event of a given class to the WaitSet.
the struct describes a callback with a user defined type which can be attached to a WaitSet or a List...
Definition: notification_callback.hpp:58