Skip to content

Commit 22aece1

Browse files
committed
iox-#33 Wait until NamedPipe is initialized
Signed-off-by: Christian Eltzschig <[email protected]>
1 parent 0a8ae0b commit 22aece1

File tree

2 files changed

+77
-2
lines changed

2 files changed

+77
-2
lines changed

iceoryx_hoofs/include/iceoryx_hoofs/posix_wrapper/named_pipe.hpp

+20-2
Original file line numberDiff line numberDiff line change
@@ -122,17 +122,35 @@ class NamedPipe : public DesignPattern::Creation<NamedPipe, IpcChannelError>
122122
private:
123123
cxx::optional<SharedMemoryObject> m_sharedMemory;
124124

125-
struct NamedPipeData
125+
class NamedPipeData
126126
{
127+
public:
127128
NamedPipeData(bool& isInitialized, IpcChannelError& error, const uint64_t maxMsgNumber) noexcept;
129+
NamedPipeData(const NamedPipeData&) = delete;
130+
NamedPipeData(NamedPipeData&& rhs) = delete;
131+
~NamedPipeData() noexcept;
132+
133+
NamedPipeData& operator=(const NamedPipeData&) = delete;
134+
NamedPipeData& operator=(NamedPipeData&& rhs) = delete;
128135

129136
Semaphore& sendSemaphore() noexcept;
130137
Semaphore& receiveSemaphore() noexcept;
131138

139+
bool waitForInitialization() const noexcept;
140+
bool hasValidState() const noexcept;
141+
142+
MessageQueue_t messages;
143+
144+
private:
132145
static constexpr uint64_t SEND_SEMAPHORE = 0U;
133146
static constexpr uint64_t RECEIVE_SEMAPHORE = 1U;
134147

135-
MessageQueue_t messages;
148+
static constexpr uint64_t INVALID_DATA = 0xBAADF00DAFFEDEAD;
149+
static constexpr uint64_t VALID_DATA = 0xBAD0FF1CEBEEFBEE;
150+
static constexpr units::Duration WAIT_FOR_INIT_TIMEOUT = units::Duration::fromSeconds(1);
151+
static constexpr units::Duration WAIT_FOR_INIT_SLEEP_TIME = units::Duration::fromMilliseconds(1);
152+
153+
std::atomic<uint64_t> initializationGuard{INVALID_DATA};
136154
using semaphoreMemory_t = uint8_t[sizeof(Semaphore)];
137155
alignas(alignof(Semaphore)) semaphoreMemory_t semaphores[2U];
138156
};

iceoryx_hoofs/source/posix_wrapper/named_pipe.cpp

+57
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ constexpr const char NamedPipe::NAMED_PIPE_PREFIX[];
2828
constexpr const char NamedPipe::SEND_SEMAPHORE_PREFIX[];
2929
constexpr const char NamedPipe::RECEIVE_SEMAPHORE_PREFIX[];
3030
constexpr units::Duration NamedPipe::CYCLE_TIME;
31+
constexpr units::Duration NamedPipe::NamedPipeData::WAIT_FOR_INIT_SLEEP_TIME;
3132

3233
NamedPipe::NamedPipe() noexcept
3334
{
@@ -113,6 +114,14 @@ NamedPipe::NamedPipe(const IpcChannelName_t& name,
113114
{
114115
new (m_data) NamedPipeData(m_isInitialized, m_errorValue, maxMsgNumber);
115116
}
117+
else
118+
{
119+
m_isInitialized = m_data->waitForInitialization();
120+
if (m_isInitialized == false)
121+
{
122+
m_errorValue = IpcChannelError::INTERNAL_LOGIC_ERROR;
123+
}
124+
}
116125
}
117126

118127
NamedPipe::NamedPipe(NamedPipe&& rhs) noexcept
@@ -326,8 +335,29 @@ NamedPipe::NamedPipeData::NamedPipeData(bool& isInitialized,
326335
&semaphores[SEND_SEMAPHORE], CreateUnnamedSharedMemorySemaphore, static_cast<unsigned int>(maxMsgNumber))
327336
.or_else([&](auto) { signalError("send"); });
328337

338+
if (!isInitialized)
339+
{
340+
return;
341+
}
342+
329343
Semaphore::placementCreate(&semaphores[RECEIVE_SEMAPHORE], CreateUnnamedSharedMemorySemaphore, 0U)
330344
.or_else([&](auto) { signalError("receive"); });
345+
346+
if (!isInitialized)
347+
{
348+
return;
349+
}
350+
351+
initializationGuard.store(VALID_DATA);
352+
}
353+
354+
NamedPipe::NamedPipeData::~NamedPipeData() noexcept
355+
{
356+
if (hasValidState())
357+
{
358+
sendSemaphore().~Semaphore();
359+
receiveSemaphore().~Semaphore();
360+
}
331361
}
332362

333363
Semaphore& NamedPipe::NamedPipeData::sendSemaphore() noexcept
@@ -340,5 +370,32 @@ Semaphore& NamedPipe::NamedPipeData::receiveSemaphore() noexcept
340370
return reinterpret_cast<Semaphore&>(semaphores[RECEIVE_SEMAPHORE]);
341371
}
342372

373+
bool NamedPipe::NamedPipeData::waitForInitialization() const noexcept
374+
{
375+
if (hasValidState())
376+
{
377+
return true;
378+
}
379+
380+
units::Duration remainingTime = WAIT_FOR_INIT_TIMEOUT;
381+
382+
while (remainingTime.toNanoseconds() > 0U)
383+
{
384+
std::this_thread::sleep_for(std::chrono::nanoseconds(WAIT_FOR_INIT_SLEEP_TIME.toNanoseconds()));
385+
remainingTime = remainingTime - WAIT_FOR_INIT_SLEEP_TIME;
386+
if (hasValidState())
387+
{
388+
return true;
389+
}
390+
}
391+
392+
return false;
393+
}
394+
395+
bool NamedPipe::NamedPipeData::hasValidState() const noexcept
396+
{
397+
return initializationGuard.load() == VALID_DATA;
398+
}
399+
343400
} // namespace posix
344401
} // namespace iox

0 commit comments

Comments
 (0)