Skip to content

Commit

Permalink
iox-eclipse-iceoryx#32 refactor message queue existance check and add…
Browse files Browse the repository at this point in the history
…ed static unlink function

Signed-off-by: Kraus Mathias (CC-AD/ESW1) <[email protected]>
  • Loading branch information
elBoberido committed Feb 4, 2020
1 parent b29cf77 commit 85f2e88
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 39 deletions.
18 changes: 3 additions & 15 deletions iceoryx_posh/source/runtime/message_queue_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,7 @@ bool MqBase::closeMessageQueue() noexcept

bool MqBase::reopen() noexcept
{
if (posix::MessageQueue::exists(m_interfaceName).get_value_or(false))
{
return openMessageQueue(m_channelSide);
}
else
{
return false;
}
return openMessageQueue(m_channelSide);
}

bool MqBase::mqMapsToFile() noexcept
Expand All @@ -197,21 +190,16 @@ bool MqBase::hasClosableMessageQueue() const noexcept

void MqBase::cleanupOutdatedMessageQueue(const std::string& name) noexcept
{
// if the message queue already exists, take ownership and use RAII for cleanup
if (posix::MessageQueue::exists(name).get_value_or(false))
if (posix::MessageQueue::unlinkIfExists(name).get_value_or(false))
{
LogWarn() << "MQ still there, doing an unlink of " << name;
posix::MessageQueue::create(name, posix::IpcChannelMode::BLOCKING, posix::IpcChannelSide::SERVER);
}
}

MqInterfaceUser::MqInterfaceUser(const std::string& name, const long maxMessages, const long messageSize) noexcept
: MqBase(name, maxMessages, messageSize)
{
if (posix::MessageQueue::exists(name).get_value_or(false))
{
openMessageQueue(posix::IpcChannelSide::CLIENT);
}
openMessageQueue(posix::IpcChannelSide::CLIENT);
}

MqInterfaceCreator::MqInterfaceCreator(const std::string& name, const long maxMessages, const long messageSize) noexcept
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class MessageQueue : public DesignPattern::Creation<MessageQueue, IpcChannelErro
public:
static constexpr mqd_t INVALID_DESCRIPTOR = -1;
static constexpr int32_t ERROR_CODE = -1;
static constexpr size_t SHORTEST_VALID_QUEUE_NAME = 2;
static constexpr size_t NULL_TERMINATOR_SIZE = 1;
static constexpr size_t MAX_MESSAGE_SIZE = 4096;

Expand All @@ -67,7 +68,7 @@ class MessageQueue : public DesignPattern::Creation<MessageQueue, IpcChannelErro

~MessageQueue();

static cxx::expected<bool, IpcChannelError> exists(const std::string& name);
static cxx::expected<bool, IpcChannelError> unlinkIfExists(const std::string& name);

/// close and remove message queue.
cxx::expected<IpcChannelError> destroy();
Expand Down
54 changes: 31 additions & 23 deletions iceoryx_utils/source/posix_wrapper/message_queue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ MessageQueue::MessageQueue(const std::string& name,
}
else
{
if (channelSide == IpcChannelSide::SERVER)
{
auto mqCall = cxx::makeSmartC(
mq_unlink, cxx::ReturnMode::PRE_DEFINED_ERROR_CODE, {ERROR_CODE}, {ENOENT}, m_name.c_str());
if (!mqCall.hasErrors())
{
if (mqCall.getErrNum() != ENOENT)
{
std::cout << "MQ still there, doing an unlink of " << name << std::endl;
}
}
}
// fields have a different order in QNX,
// so we need to initialize by name
m_attributes.mq_flags = (mode == IpcChannelMode::NON_BLOCKING) ? O_NONBLOCK : 0;
Expand Down Expand Up @@ -103,34 +115,19 @@ MessageQueue& MessageQueue::operator=(MessageQueue&& other)
return *this;
}

cxx::expected<bool, IpcChannelError> MessageQueue::exists(const std::string& name)
cxx::expected<bool, IpcChannelError> MessageQueue::unlinkIfExists(const std::string& name)
{
if (name.empty() || name.at(0) != '/')
if (name.size() < SHORTEST_VALID_QUEUE_NAME || name.at(0) != '/')
{
return cxx::error<IpcChannelError>(IpcChannelError::INVALID_CHANNEL_NAME);
}

int32_t openFlags = O_RDWR;

// the mask will be applied to the permissions, therefore we need to set it to 0
mode_t umaskSaved = umask(0);

struct mq_attr attributes;

auto mqCall = cxx::makeSmartC(mq_open,
cxx::ReturnMode::PRE_DEFINED_ERROR_CODE,
{ERROR_CODE},
{ENOENT},
name.c_str(),
openFlags,
MessageQueue::m_filemode,
&attributes);

umask(umaskSaved);
auto mqCall =
cxx::makeSmartC(mq_unlink, cxx::ReturnMode::PRE_DEFINED_ERROR_CODE, {ERROR_CODE}, {ENOENT}, name.c_str());

if (!mqCall.hasErrors())
{
// ENOENT is set if the message queue could not be opened
// ENOENT is set if the message queue could not be unlinked
return cxx::success<bool>(mqCall.getErrNum() != ENOENT);
}
else
Expand Down Expand Up @@ -209,7 +206,7 @@ cxx::expected<std::string, IpcChannelError> MessageQueue::receive() const
cxx::expected<int32_t, IpcChannelError>
MessageQueue::open(const std::string& name, const IpcChannelMode mode, const IpcChannelSide channelSide)
{
if (name.empty() || name.at(0) != '/')
if (name.size() < SHORTEST_VALID_QUEUE_NAME || name.at(0) != '/')
{
return cxx::error<IpcChannelError>(IpcChannelError::INVALID_CHANNEL_NAME);
}
Expand All @@ -227,7 +224,7 @@ MessageQueue::open(const std::string& name, const IpcChannelMode mode, const Ipc
auto mqCall = cxx::makeSmartC(mq_open,
cxx::ReturnMode::PRE_DEFINED_ERROR_CODE,
{ERROR_CODE},
{},
{ENOENT},
name.c_str(),
openFlags,
m_filemode,
Expand All @@ -237,7 +234,18 @@ MessageQueue::open(const std::string& name, const IpcChannelMode mode, const Ipc

if (!mqCall.hasErrors())
{
return cxx::success<int32_t>(mqCall.getReturnValue());
if (mqCall.getErrNum() == 0)
{
return cxx::success<int32_t>(mqCall.getReturnValue());
}
else if (mqCall.getErrNum() == ENOENT)
{
return cxx::error<IpcChannelError>(IpcChannelError::NO_SUCH_CHANNEL);
}
else
{
return createErrorFromErrnum(mqCall.getErrNum());
}
}
else
{
Expand Down

0 comments on commit 85f2e88

Please sign in to comment.