iceoryx_doc  1.0.1
posh_runtime.hpp
1 // Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
2 // Copyright (c) 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_RUNTIME_POSH_RUNTIME_HPP
18 #define IOX_POSH_RUNTIME_POSH_RUNTIME_HPP
19 
20 #include "iceoryx_posh/capro/service_description.hpp"
21 #include "iceoryx_posh/iceoryx_posh_types.hpp"
22 #include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp"
23 #include "iceoryx_posh/internal/popo/ports/application_port.hpp"
24 #include "iceoryx_posh/internal/popo/ports/interface_port.hpp"
25 #include "iceoryx_posh/internal/popo/ports/publisher_port_user.hpp"
26 #include "iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp"
27 #include "iceoryx_posh/internal/runtime/ipc_runtime_interface.hpp"
28 #include "iceoryx_posh/internal/runtime/node_property.hpp"
29 #include "iceoryx_posh/internal/runtime/shared_memory_user.hpp"
30 #include "iceoryx_posh/popo/subscriber_options.hpp"
31 #include "iceoryx_posh/runtime/port_config_info.hpp"
32 #include "iceoryx_utils/cxx/method_callback.hpp"
33 #include "iceoryx_utils/cxx/string.hpp"
34 #include "iceoryx_utils/internal/concurrent/periodic_task.hpp"
35 
36 #include <atomic>
37 #include <map>
38 #include <mutex>
39 #include <thread>
40 #include <vector>
41 
42 namespace iox
43 {
44 namespace roudi
45 {
46 class RuntimeTestInterface;
47 } // namespace roudi
48 
49 namespace runtime
50 {
51 class Node;
52 class NodeData;
53 
54 enum class FindServiceError
55 {
56  INVALID_STATE,
57  UNABLE_TO_WRITE_TO_ROUDI_CHANNEL,
58  INSTANCE_CONTAINER_OVERFLOW
59 };
60 
63 {
64  public:
68  static PoshRuntime& getInstance() noexcept;
69 
75  static PoshRuntime& initRuntime(const RuntimeName_t& name) noexcept;
76 
79  RuntimeName_t getInstanceName() const noexcept;
80 
83  void shutdown() noexcept;
84 
90  cxx::expected<InstanceContainer, FindServiceError>
91  findService(const capro::ServiceDescription& serviceDescription) noexcept;
92 
96  bool offerService(const capro::ServiceDescription& serviceDescription) noexcept;
97 
100  void stopOfferService(const capro::ServiceDescription& serviceDescription) noexcept;
101 
108  PublisherPortUserType::MemberType_t*
109  getMiddlewarePublisher(const capro::ServiceDescription& service,
110  const popo::PublisherOptions& publisherOptions = popo::PublisherOptions(),
111  const PortConfigInfo& portConfigInfo = PortConfigInfo()) noexcept;
112 
119  SubscriberPortUserType::MemberType_t*
120  getMiddlewareSubscriber(const capro::ServiceDescription& service,
121  const popo::SubscriberOptions& subscriberOptions = popo::SubscriberOptions(),
122  const PortConfigInfo& portConfigInfo = PortConfigInfo()) noexcept;
123 
128  popo::InterfacePortData* getMiddlewareInterface(const capro::Interfaces interface,
129  const NodeName_t& nodeName = {""}) noexcept;
130 
134 
137  popo::ConditionVariableData* getMiddlewareConditionVariable() noexcept;
138 
142  NodeData* createNode(const NodeProperty& nodeProperty) noexcept;
143 
146  const std::atomic<uint64_t>* getServiceRegistryChangeCounter() noexcept;
147 
153  bool sendRequestToRouDi(const IpcMessage& msg, IpcMessage& answer) noexcept;
154 
155  public:
156  PoshRuntime(const PoshRuntime&) = delete;
157  PoshRuntime& operator=(const PoshRuntime&) = delete;
158  PoshRuntime(PoshRuntime&&) = delete;
159  PoshRuntime& operator=(PoshRuntime&&) = delete;
160  virtual ~PoshRuntime() noexcept;
161 
162  friend class roudi::RuntimeTestInterface;
163 
164  protected:
165  using factory_t = PoshRuntime& (*)(cxx::optional<const RuntimeName_t*>);
166 
167  // Protected constructor for IPC setup
168  PoshRuntime(cxx::optional<const RuntimeName_t*> name, const bool doMapSharedMemoryIntoThread = true) noexcept;
169 
170  static PoshRuntime& defaultRuntimeFactory(cxx::optional<const RuntimeName_t*> name) noexcept;
171 
172  static RuntimeName_t& defaultRuntimeInstanceName() noexcept;
173 
178  static factory_t& getRuntimeFactory() noexcept;
179 
183  static void setRuntimeFactory(const factory_t& factory) noexcept;
184 
190  static PoshRuntime& getInstance(cxx::optional<const RuntimeName_t*> name) noexcept;
191 
192  private:
193  cxx::expected<PublisherPortUserType::MemberType_t*, IpcMessageErrorType>
194  requestPublisherFromRoudi(const IpcMessage& sendBuffer) noexcept;
195 
196  cxx::expected<SubscriberPortUserType::MemberType_t*, IpcMessageErrorType>
197  requestSubscriberFromRoudi(const IpcMessage& sendBuffer) noexcept;
198 
199  cxx::expected<popo::ConditionVariableData*, IpcMessageErrorType>
200  requestConditionVariableFromRoudi(const IpcMessage& sendBuffer) noexcept;
201 
203  const RuntimeName_t& verifyInstanceName(cxx::optional<const RuntimeName_t*> name) noexcept;
204 
205  const RuntimeName_t m_appName;
206  mutable std::mutex m_appIpcRequestMutex;
207 
208  // IPC channel interface for POSIX IPC from RouDi
209  IpcRuntimeInterface m_ipcChannelInterface;
210  // Shared memory interface for POSIX IPC from RouDi
211  SharedMemoryUser m_ShmInterface;
212  popo::ApplicationPort m_applicationPort;
213 
214  std::atomic<bool> m_shutdownRequested{false};
215  void sendKeepAliveAndHandleShutdownPreparation() noexcept;
216  static_assert(PROCESS_KEEP_ALIVE_INTERVAL > roudi::DISCOVERY_INTERVAL, "Keep alive interval too small");
217 
219  concurrent::PeriodicTask<cxx::MethodCallback<void>> m_keepAliveTask{
220  concurrent::PeriodicTaskAutoStart,
221  PROCESS_KEEP_ALIVE_INTERVAL,
222  "KeepAlive",
223  *this,
224  &PoshRuntime::sendKeepAliveAndHandleShutdownPreparation};
225 };
226 
227 } // namespace runtime
228 } // namespace iox
229 
230 #endif // IOX_POSH_RUNTIME_POSH_RUNTIME_HPP
The PublisherPortUser provides the API for accessing a publisher port from the user side....
Definition: publisher_port_user.hpp:39
The SubscriberPortUser provides the API for accessing a subscriber port from the user side....
Definition: subscriber_port_user.hpp:41
Definition: ipc_message.hpp:43
Definition: ipc_runtime_interface.hpp:29
struct which contains all the members of an object of type Node
Definition: node_data.hpp:30
The runtime that is needed for each application to communicate with the RouDi daemon.
Definition: posh_runtime.hpp:63
RuntimeName_t getInstanceName() const noexcept
get the name that was used to register with RouDi
bool sendRequestToRouDi(const IpcMessage &msg, IpcMessage &answer) noexcept
send a request to the RouDi daemon and get the response currently each request is followed by a respo...
static PoshRuntime & initRuntime(const RuntimeName_t &name) noexcept
creates the runtime with given name
bool offerService(const capro::ServiceDescription &serviceDescription) noexcept
offer the provided service, sends the offer from application to RouDi daemon
popo::ConditionVariableData * getMiddlewareConditionVariable() noexcept
request the RouDi daemon to create a condition variable
static factory_t & getRuntimeFactory() noexcept
gets current runtime factory. If the runtime factory is not yet initialized it is set to defaultRunti...
popo::ApplicationPortData * getMiddlewareApplication() noexcept
request the RouDi daemon to create an application port
static void setRuntimeFactory(const factory_t &factory) noexcept
sets runtime factory, terminates if given factory is empty
popo::InterfacePortData * getMiddlewareInterface(const capro::Interfaces interface, const NodeName_t &nodeName={""}) noexcept
request the RouDi daemon to create an interface port
const std::atomic< uint64_t > * getServiceRegistryChangeCounter() noexcept
requests the serviceRegistryChangeCounter from the shared memory
void shutdown() noexcept
initiates the shutdown of the runtime to unblock all potentially blocking publisher with the Subscrib...
PublisherPortUserType::MemberType_t * getMiddlewarePublisher(const capro::ServiceDescription &service, const popo::PublisherOptions &publisherOptions=popo::PublisherOptions(), const PortConfigInfo &portConfigInfo=PortConfigInfo()) noexcept
request the RouDi daemon to create a publisher port
NodeData * createNode(const NodeProperty &nodeProperty) noexcept
request the RouDi daemon to create a node
void stopOfferService(const capro::ServiceDescription &serviceDescription) noexcept
stop offering the provided service
SubscriberPortUserType::MemberType_t * getMiddlewareSubscriber(const capro::ServiceDescription &service, const popo::SubscriberOptions &subscriberOptions=popo::SubscriberOptions(), const PortConfigInfo &portConfigInfo=PortConfigInfo()) noexcept
request the RouDi daemon to create a subscriber port
static PoshRuntime & getInstance() noexcept
returns active runtime
cxx::expected< InstanceContainer, FindServiceError > findService(const capro::ServiceDescription &serviceDescription) noexcept
find all services that match the provided service description
shared memory setup for the management segment user side
Definition: shared_memory_user.hpp:33
Definition: service_description.hpp:29
Definition: application_port_data.hpp:29
helper struct which is convertable to string and constructable from a string which is required to sen...
Definition: node_property.hpp:29
Stores information necessary to create the right type of port on RouDi side. Different types of ports...
Definition: port_config_info.hpp:32