iceoryx_doc  1.0.1
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_posh/internal/popo/building_blocks/condition_listener.hpp"
21 #include "iceoryx_posh/popo/enum_trigger_type.hpp"
22 #include "iceoryx_posh/popo/notification_attorney.hpp"
23 #include "iceoryx_posh/popo/notification_callback.hpp"
24 #include "iceoryx_posh/popo/trigger_handle.hpp"
25 #include "iceoryx_utils/cxx/expected.hpp"
26 #include "iceoryx_utils/cxx/method_callback.hpp"
27 #include "iceoryx_utils/cxx/type_traits.hpp"
28 #include "iceoryx_utils/internal/concurrent/loffli.hpp"
29 #include "iceoryx_utils/internal/concurrent/smart_lock.hpp"
30 
31 #include <thread>
32 
33 namespace iox
34 {
35 namespace popo
36 {
37 enum class ListenerError
38 {
39  INVALID_STATE,
40  LISTENER_FULL,
41  EVENT_ALREADY_ATTACHED,
42  EMPTY_INVALIDATION_CALLBACK
43 };
44 
66 class Listener
67 {
68  public:
69  Listener() noexcept;
70  Listener(const Listener&) = delete;
71  Listener(Listener&&) = delete;
72  ~Listener();
73 
74  Listener& operator=(const Listener&) = delete;
75  Listener& operator=(Listener&&) = delete;
76 
89  template <typename T,
90  typename EventType,
91  typename ContextDataType,
92  typename = std::enable_if_t<std::is_enum<EventType>::value>>
93  cxx::expected<ListenerError> attachEvent(T& eventOrigin,
94  const EventType eventType,
95  const NotificationCallback<T, ContextDataType>& eventCallback) noexcept;
96 
107  template <typename T, typename ContextDataType>
108  cxx::expected<ListenerError> attachEvent(T& eventOrigin,
109  const NotificationCallback<T, ContextDataType>& eventCallback) noexcept;
110 
117  template <typename T, typename EventType, typename = std::enable_if_t<std::is_enum<EventType>::value>>
118  void detachEvent(T& eventOrigin, const EventType eventType) noexcept;
119 
123  template <typename T>
124  void detachEvent(T& eventOrigin) noexcept;
125 
128  static constexpr uint64_t capacity() noexcept;
129 
132  uint64_t size() const noexcept;
133 
134  protected:
135  Listener(ConditionVariableData& conditionVariableData) noexcept;
136 
137  private:
138  class Event_t;
139 
140  void threadLoop() noexcept;
141  cxx::expected<uint32_t, ListenerError>
142  addEvent(void* const origin,
143  void* const userType,
144  const uint64_t eventType,
145  const uint64_t eventTypeHash,
146  internal::GenericCallbackRef_t callback,
147  internal::TranslationCallbackRef_t translationCallback,
148  const cxx::MethodCallback<void, uint64_t> invalidationCallback) noexcept;
149 
150  void removeTrigger(const uint64_t index) noexcept;
151 
152  private:
153  enum class NoEnumUsed : EventEnumIdentifier
154  {
155  PLACEHOLDER = 0
156  };
157 
158  class Event_t
159  {
160  public:
161  ~Event_t();
162 
163  bool isEqualTo(const void* const origin, const uint64_t eventType, const uint64_t eventTypeHash) const noexcept;
164  bool reset() noexcept;
165  bool init(const uint64_t eventId,
166  void* const origin,
167  void* const userType,
168  const uint64_t eventType,
169  const uint64_t eventTypeHash,
170  internal::GenericCallbackRef_t callback,
171  internal::TranslationCallbackRef_t translationCallback,
172  const cxx::MethodCallback<void, uint64_t> invalidationCallback) noexcept;
173  void executeCallback() noexcept;
174  bool isInitialized() const noexcept;
175 
176  private:
177  static constexpr uint64_t INVALID_ID = std::numeric_limits<uint64_t>::max();
178 
179  void* m_origin = nullptr;
180  uint64_t m_eventType = INVALID_ID;
181  uint64_t m_eventTypeHash = INVALID_ID;
182 
183  internal::GenericCallbackPtr_t m_callback = nullptr;
184  internal::TranslationCallbackPtr_t m_translationCallback = nullptr;
185  void* m_userType = nullptr;
186 
187  uint64_t m_eventId = INVALID_ID;
188  cxx::MethodCallback<void, uint64_t> m_invalidationCallback;
189  };
190 
191  class IndexManager_t
192  {
193  public:
194  IndexManager_t() noexcept;
195  bool pop(uint32_t& index) noexcept;
196  void push(const uint32_t index) noexcept;
197  uint64_t indicesInUse() const noexcept;
198 
199  using LoFFLi = concurrent::LoFFLi;
200  LoFFLi::Index_t
201  m_loffliStorage[LoFFLi::requiredIndexMemorySize(MAX_NUMBER_OF_EVENTS_PER_LISTENER) / sizeof(uint32_t)];
202  LoFFLi m_loffli;
203  std::atomic<uint64_t> m_indicesInUse{0U};
204  } m_indexManager;
205 
206 
207  std::thread m_thread;
208  concurrent::smart_lock<Event_t, std::recursive_mutex> m_events[MAX_NUMBER_OF_EVENTS_PER_LISTENER];
209  std::mutex m_addEventMutex;
210 
211  std::atomic_bool m_wasDtorCalled{false};
212  ConditionVariableData* m_conditionVariableData = nullptr;
213  ConditionListener m_conditionListener;
214 };
215 } // namespace popo
216 } // namespace iox
217 
218 #include "iceoryx_posh/internal/popo/listener.inl"
219 
220 #endif
The Listener is a class which reacts to registered events by executing a corresponding callback concu...
Definition: listener.hpp:67
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...
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...
static constexpr uint64_t capacity() noexcept
Returns the capacity of the Listener.
Definition: listener.inl:73
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 ...
Definition: listener.inl:60
uint64_t size() const noexcept
Returns the size of the Listener.
Definition: service_description.hpp:29
Definition: condition_variable_data.hpp:31
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