iceoryx_hoofs 2.0.5
Loading...
Searching...
No Matches
named_pipe.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#ifndef IOX_HOOFS_POSIX_WRAPPER_NAMED_PIPE_HPP
17#define IOX_HOOFS_POSIX_WRAPPER_NAMED_PIPE_HPP
18
19#include "iceoryx_hoofs/concurrent/lockfree_queue.hpp"
20#include "iceoryx_hoofs/cxx/string.hpp"
21#include "iceoryx_hoofs/design_pattern/creation.hpp"
22#include "iceoryx_hoofs/internal/posix_wrapper/ipc_channel.hpp"
23#include "iceoryx_hoofs/internal/posix_wrapper/shared_memory_object.hpp"
24#include "iceoryx_hoofs/internal/units/duration.hpp"
25#include "iceoryx_hoofs/posix_wrapper/semaphore.hpp"
26
27#include <cstdint>
28
29namespace iox
30{
31namespace posix
32{
33class NamedPipe : public DesignPattern::Creation<NamedPipe, IpcChannelError>
34{
35 public:
36 // no system restrictions at all, except available memory. MAX_MESSAGE_SIZE and MAX_NUMBER_OF_MESSAGES can be
37 // increased as long as there is enough memory available
38 static constexpr uint64_t MAX_MESSAGE_SIZE = 4U * 1024U;
39 static constexpr uint64_t MAX_NUMBER_OF_MESSAGES = 10U;
40
41 static constexpr uint64_t NULL_TERMINATOR_SIZE = 0U;
42 static constexpr units::Duration CYCLE_TIME = units::Duration::fromMilliseconds(10);
43 static constexpr const char NAMED_PIPE_PREFIX[] = "iox_np_";
44
47
48 NamedPipe(const NamedPipe&) = delete;
49 NamedPipe& operator=(const NamedPipe&) = delete;
50
53 NamedPipe() noexcept;
54
55 NamedPipe(NamedPipe&& rhs) noexcept;
56 NamedPipe& operator=(NamedPipe&& rhs) noexcept;
57 ~NamedPipe() noexcept;
58
61 cxx::expected<IpcChannelError> destroy() noexcept;
62
66 static cxx::expected<bool, IpcChannelError> unlinkIfExists(const IpcChannelName_t& name) noexcept;
67
70 cxx::expected<bool, IpcChannelError> isOutdated() noexcept;
71
74 cxx::expected<IpcChannelError> trySend(const std::string& message) const noexcept;
75
80 cxx::expected<IpcChannelError> send(const std::string& message) const noexcept;
81
86 cxx::expected<IpcChannelError> timedSend(const std::string& message, const units::Duration& timeout) const noexcept;
87
90 cxx::expected<std::string, IpcChannelError> tryReceive() const noexcept;
91
95 cxx::expected<std::string, IpcChannelError> receive() const noexcept;
96
100 cxx::expected<std::string, IpcChannelError> timedReceive(const units::Duration& timeout) const noexcept;
101
102 private:
103 friend class DesignPattern::Creation<NamedPipe, IpcChannelError>;
104
111 NamedPipe(const IpcChannelName_t& name,
112 const IpcChannelSide channelSide,
113 const size_t maxMsgSize = MAX_MESSAGE_SIZE,
114 const uint64_t maxMsgNumber = MAX_NUMBER_OF_MESSAGES) noexcept;
115
116 template <typename Prefix>
117 static IpcChannelName_t convertName(const Prefix& p, const IpcChannelName_t& name) noexcept;
118
119 private:
120 cxx::optional<SharedMemoryObject> m_sharedMemory;
121
122 class NamedPipeData
123 {
124 public:
125 NamedPipeData(bool& isInitialized, IpcChannelError& error, const uint64_t maxMsgNumber) noexcept;
126 NamedPipeData(const NamedPipeData&) = delete;
127 NamedPipeData(NamedPipeData&& rhs) = delete;
128 ~NamedPipeData() noexcept;
129
130 NamedPipeData& operator=(const NamedPipeData&) = delete;
131 NamedPipeData& operator=(NamedPipeData&& rhs) = delete;
132
133 Semaphore& sendSemaphore() noexcept;
134 Semaphore& receiveSemaphore() noexcept;
135
136 bool waitForInitialization() const noexcept;
137 bool hasValidState() const noexcept;
138
139 MessageQueue_t messages;
140
141 private:
142 static constexpr uint64_t SEND_SEMAPHORE = 0U;
143 static constexpr uint64_t RECEIVE_SEMAPHORE = 1U;
144
145 static constexpr uint64_t INVALID_DATA = 0xBAADF00DAFFEDEAD;
146 static constexpr uint64_t VALID_DATA = 0xBAD0FF1CEBEEFBEE;
147 static constexpr units::Duration WAIT_FOR_INIT_TIMEOUT = units::Duration::fromSeconds(1);
148 static constexpr units::Duration WAIT_FOR_INIT_SLEEP_TIME = units::Duration::fromMilliseconds(1);
149
150 std::atomic<uint64_t> initializationGuard{INVALID_DATA};
151 using semaphoreMemory_t = uint8_t[sizeof(Semaphore)];
152 alignas(Semaphore) semaphoreMemory_t semaphores[2U];
153 };
154
155
156 NamedPipeData* m_data = nullptr;
157};
158} // namespace posix
159} // namespace iox
160
161#endif
This pattern can be used if you write an abstraction where you have to throw an exception in the cons...
Definition creation.hpp:99
bool isInitialized() const noexcept
returns true if the object was constructed successfully, otherwise false
string implementation with some adjustments in the API, because we are not allowed to throw exception...
Definition string.hpp:90
Definition named_pipe.hpp:34
NamedPipe() noexcept
For compatibility with IpcChannel alias, default ctor which creates an uninitialized NamedPipe.
static cxx::expected< bool, IpcChannelError > unlinkIfExists(const IpcChannelName_t &name) noexcept
removes a named pipe artifact from the system
cxx::expected< IpcChannelError > timedSend(const std::string &message, const units::Duration &timeout) const noexcept
sends a message via the named pipe.
cxx::expected< std::string, IpcChannelError > receive() const noexcept
receives a message via the named pipe. if the pipe is empty this call is blocking until a message was...
cxx::expected< IpcChannelError > destroy() noexcept
destroys an initialized named pipe.
cxx::expected< std::string, IpcChannelError > timedReceive(const units::Duration &timeout) const noexcept
receives a message via the named pipe.
cxx::expected< IpcChannelError > trySend(const std::string &message) const noexcept
tries to send a message via the named pipe. if the pipe is full IpcChannelError::TIMEOUT is returned
cxx::expected< bool, IpcChannelError > isOutdated() noexcept
for compatibility with IpcChannelError
cxx::expected< IpcChannelError > send(const std::string &message) const noexcept
sends a message via the named pipe. if the pipe is full this call is blocking until the message could...
cxx::expected< std::string, IpcChannelError > tryReceive() const noexcept
tries to receive a message via the named pipe. if the pipe is empty IpcChannelError::TIMEOUT is retur...
Posix semaphore C++ Wrapping class.
Definition semaphore.hpp:82
building block to easily create free function for logging in a library context
Definition lockfree_queue.hpp:29