iceoryx_posh  2.0.2
listener.hpp
1 // Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
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 // SPDX-License-Identifier: Apache-2.0
16 
17 #ifndef IOX_POSH_POPO_LISTENER_HPP
18 #define IOX_POSH_POPO_LISTENER_HPP
19 
20 #include "iceoryx_hoofs/cxx/expected.hpp"
21 #include "iceoryx_hoofs/cxx/method_callback.hpp"
22 #include "iceoryx_hoofs/cxx/type_traits.hpp"
23 #include "iceoryx_hoofs/internal/concurrent/loffli.hpp"
24 #include "iceoryx_hoofs/internal/concurrent/smart_lock.hpp"
25 #include "iceoryx_posh/internal/popo/building_blocks/condition_listener.hpp"
26 #include "iceoryx_posh/popo/enum_trigger_type.hpp"
27 #include "iceoryx_posh/popo/notification_attorney.hpp"
28 #include "iceoryx_posh/popo/notification_callback.hpp"
29 #include "iceoryx_posh/popo/trigger_handle.hpp"
30 #include "iceoryx_posh/runtime/posh_runtime.hpp"
31 
32 #include <thread>
33 
34 namespace iox
35 {
36 namespace popo
37 {
38 namespace internal
39 {
40 class Event_t
41 {
42  public:
43  ~Event_t() noexcept;
44 
45  bool isEqualTo(const void* const origin, const uint64_t eventType, const uint64_t eventTypeHash) const noexcept;
46  bool reset() noexcept;
47  bool init(const uint64_t eventId,
48  void* const origin,
49  void* const userType,
50  const uint64_t eventType,
51  const uint64_t eventTypeHash,
52  internal::GenericCallbackRef_t callback,
53  internal::TranslationCallbackRef_t translationCallback,
54  const cxx::MethodCallback<void, uint64_t> invalidationCallback) noexcept;
55  void executeCallback() noexcept;
56  bool isInitialized() const noexcept;
57 
58  private:
59  static constexpr uint64_t INVALID_ID = std::numeric_limits<uint64_t>::max();
60 
61  void* m_origin = nullptr;
62  uint64_t m_eventType = INVALID_ID;
63  uint64_t m_eventTypeHash = INVALID_ID;
64 
65  internal::GenericCallbackPtr_t m_callback = nullptr;
66  internal::TranslationCallbackPtr_t m_translationCallback = nullptr;
67  void* m_userType = nullptr;
68 
69  uint64_t m_eventId = INVALID_ID;
70  cxx::MethodCallback<void, uint64_t> m_invalidationCallback;
71 };
72 } // namespace internal
73 
74 enum class ListenerError
75 {
76  LISTENER_FULL,
77  EVENT_ALREADY_ATTACHED,
78  EMPTY_EVENT_CALLBACK,
79  EMPTY_INVALIDATION_CALLBACK
80 };
81 
103 template <uint64_t Capacity>
105 {
106  public:
107  ListenerImpl() noexcept;
108  ListenerImpl(const ListenerImpl&) = delete;
109  ListenerImpl(ListenerImpl&&) = delete;
110  ~ListenerImpl() noexcept;
111 
112  ListenerImpl& operator=(const ListenerImpl&) = delete;
113  ListenerImpl& operator=(ListenerImpl&&) = delete;
114 
127  template <typename T,
128  typename EventType,
129  typename ContextDataType,
130  typename = std::enable_if_t<std::is_enum<EventType>::value>>
131  cxx::expected<ListenerError> attachEvent(T& eventOrigin,
132  const EventType eventType,
133  const NotificationCallback<T, ContextDataType>& eventCallback) noexcept;
134 
145  template <typename T, typename ContextDataType>
146  cxx::expected<ListenerError> attachEvent(T& eventOrigin,
147  const NotificationCallback<T, ContextDataType>& eventCallback) noexcept;
148 
155  template <typename T, typename EventType, typename = std::enable_if_t<std::is_enum<EventType>::value>>
156  void detachEvent(T& eventOrigin, const EventType eventType) noexcept;
157 
161  template <typename T>
162  void detachEvent(T& eventOrigin) noexcept;
163 
166  static constexpr uint64_t capacity() noexcept;
167 
170  uint64_t size() const noexcept;
171 
172  protected:
173  ListenerImpl(ConditionVariableData& conditionVariableData) noexcept;
174 
175  private:
176  class Event_t;
177 
178  void threadLoop() noexcept;
179  cxx::expected<uint32_t, ListenerError>
180  addEvent(void* const origin,
181  void* const userType,
182  const uint64_t eventType,
183  const uint64_t eventTypeHash,
184  internal::GenericCallbackRef_t callback,
185  internal::TranslationCallbackRef_t translationCallback,
186  const cxx::MethodCallback<void, uint64_t> invalidationCallback) noexcept;
187 
188  void removeTrigger(const uint64_t index) noexcept;
189 
190  private:
191  enum class NoEnumUsed : EventEnumIdentifier
192  {
193  PLACEHOLDER = 0
194  };
195 
196 
197  class IndexManager_t
198  {
199  public:
200  IndexManager_t() noexcept;
201  bool pop(uint32_t& index) noexcept;
202  void push(const uint32_t index) noexcept;
203  uint64_t indicesInUse() const noexcept;
204 
205  using LoFFLi = concurrent::LoFFLi;
206  LoFFLi::Index_t m_loffliStorage[LoFFLi::requiredIndexMemorySize(Capacity) / sizeof(uint32_t)];
207  LoFFLi m_loffli;
208  std::atomic<uint64_t> m_indicesInUse{0U};
209  } m_indexManager;
210 
211 
212  std::thread m_thread;
213  concurrent::smart_lock<internal::Event_t, std::recursive_mutex> m_events[Capacity];
214  std::mutex m_addEventMutex;
215 
216  std::atomic_bool m_wasDtorCalled{false};
217  ConditionVariableData* m_conditionVariableData = nullptr;
218  ConditionListener m_conditionListener;
219 };
220 
221 class Listener : public ListenerImpl<MAX_NUMBER_OF_EVENTS_PER_LISTENER>
222 {
223  public:
225  Listener() noexcept;
226 
227  protected:
228  Listener(ConditionVariableData& conditionVariableData) noexcept;
229 };
230 
231 } // namespace popo
232 } // namespace iox
233 
234 #include "iceoryx_posh/internal/popo/listener.inl"
235 
236 #endif
The Listener is a class which reacts to registered events by executing a corresponding callback concu...
Definition: listener.hpp:105
void detachEvent(T &eventOrigin, const EventType eventType) noexcept
Detaches an event. Hereby, the event is defined as a class T, the eventOrigin and the eventType with ...
cxx::expected< ListenerError > attachEvent(T &eventOrigin, const NotificationCallback< T, ContextDataType > &eventCallback) noexcept
Attaches an event. Hereby the event is defined as a class T, the eventOrigin and the corresponding ca...
cxx::expected< ListenerError > attachEvent(T &eventOrigin, const EventType eventType, const NotificationCallback< T, ContextDataType > &eventCallback) noexcept
Attaches an event. Hereby the event is defined as a class T, the eventOrigin, an enum which further d...
void detachEvent(T &eventOrigin) noexcept
Detaches an event. Hereby, the event is defined as a class T, the eventOrigin.
static constexpr uint64_t capacity() noexcept
Returns the capacity of the Listener.
Definition: listener.hpp:222
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