Skip to content

Commit

Permalink
Merge pull request #2016 from elBoberido/iox-1036-builder-pattern-for…
Browse files Browse the repository at this point in the history
…-unix-domain-socket

iox-#1036 builder pattern for unix domain socket
  • Loading branch information
elBoberido authored Sep 4, 2023
2 parents 4406d46 + 40b65ae commit f434f6f
Show file tree
Hide file tree
Showing 11 changed files with 267 additions and 265 deletions.
2 changes: 1 addition & 1 deletion .clang-tidy-diff-scans.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
./iceoryx_hoofs/source/posix_wrapper/shared_memory_object/*
./iceoryx_hoofs/test/moduletests/test_posix*

./iceoryx_hoofs/include/error_reporting/**/*
./iceoryx_hoofs/include/iceoryx_hoofs/error_reporting/**/*
./iceoryx_hoofs/source/error_reporting/**/*
./iceoryx_hoofs/testing/include/iceoryx_hoofs/testing/error_reporting/*
./iceoryx_hoofs/testing/error_reporting/*
Expand Down
1 change: 1 addition & 0 deletions doc/website/release-notes/iceoryx-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
- `SharedMemory`
- `MessageQueue`
- `NamedPipe`
- `UnixDomainSocket`
- `FileLock`
- Add the ability to adjust path and file permissions of the file lock
- `Mutex`
Expand Down
22 changes: 7 additions & 15 deletions iceoryx_dust/include/iceoryx_dust/posix_wrapper/message_queue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ namespace iox
{
namespace posix
{
class MessageQueueBuilder;

/// @brief Wrapper class for posix message queue
///
/// @code
Expand All @@ -54,7 +56,9 @@ class MessageQueue
static constexpr uint64_t SHORTEST_VALID_QUEUE_NAME = 2;
static constexpr uint64_t NULL_TERMINATOR_SIZE = 1;
static constexpr uint64_t MAX_MESSAGE_SIZE = 4096;
static constexpr uint64_t MAX_MESSAGE_NUMBER = 10;
static constexpr uint64_t MAX_NUMBER_OF_MESSAGES = 10;

using Builder_t = MessageQueueBuilder;

MessageQueue() noexcept = delete;
MessageQueue(const MessageQueue& other) = delete;
Expand All @@ -64,18 +68,6 @@ class MessageQueue

~MessageQueue() noexcept;

/// @todo iox-#1036 Remove when all channels are ported to the builder pattern
static expected<MessageQueue, IpcChannelError> create(const IpcChannelName_t& name,
const IpcChannelSide channelSide,
const uint64_t maxMsgSize = MAX_MESSAGE_SIZE,
const uint64_t maxMsgNumber = MAX_MESSAGE_NUMBER) noexcept;

/// @todo iox-#1036 Remove when all channels are ported to the builder pattern
bool isInitialized() const noexcept
{
return m_mqDescriptor != INVALID_DESCRIPTOR;
}

static expected<bool, IpcChannelError> unlinkIfExists(const IpcChannelName_t& name) noexcept;

/// @brief send a message to queue using std::string.
Expand All @@ -101,7 +93,7 @@ class MessageQueue
private:
friend class MessageQueueBuilder;

MessageQueue(const IpcChannelName_t&& name,
MessageQueue(const IpcChannelName_t& name,
const mq_attr attributes,
mqd_t mqDescriptor,
const IpcChannelSide channelSide) noexcept;
Expand Down Expand Up @@ -146,7 +138,7 @@ class MessageQueueBuilder
IOX_BUILDER_PARAMETER(uint64_t, maxMsgSize, MessageQueue::MAX_MESSAGE_SIZE)

/// @brief Defines the max number of messages for the message queue.
IOX_BUILDER_PARAMETER(uint64_t, maxMsgNumber, MessageQueue::MAX_MESSAGE_NUMBER)
IOX_BUILDER_PARAMETER(uint64_t, maxMsgNumber, MessageQueue::MAX_NUMBER_OF_MESSAGES)

public:
/// @brief create a message queue
Expand Down
17 changes: 5 additions & 12 deletions iceoryx_dust/include/iceoryx_dust/posix_wrapper/named_pipe.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "iceoryx_hoofs/internal/posix_wrapper/shared_memory_object.hpp"
#include "iceoryx_hoofs/posix_wrapper/unnamed_semaphore.hpp"
#include "iceoryx_platform/semaphore.hpp"
#include "iox/builder.hpp"
#include "iox/duration.hpp"
#include "iox/expected.hpp"
#include "iox/optional.hpp"
Expand All @@ -35,6 +36,8 @@ namespace iox
{
namespace posix
{
class NamedPipeBuilder;

class NamedPipe
{
public:
Expand All @@ -52,6 +55,8 @@ class NamedPipe
/// NOLINTNEXTLINE(hicpp-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays)
static constexpr const char NAMED_PIPE_PREFIX[] = "iox_np_";

using Builder_t = NamedPipeBuilder;

using Message_t = string<MAX_MESSAGE_SIZE>;
using MessageQueue_t = concurrent::LockFreeQueue<Message_t, MAX_NUMBER_OF_MESSAGES>;

Expand All @@ -63,18 +68,6 @@ class NamedPipe
NamedPipe& operator=(NamedPipe&& rhs) noexcept;
~NamedPipe() noexcept;

/// @todo iox-#1036 Remove when all channels are ported to the builder pattern
static expected<NamedPipe, IpcChannelError> create(const IpcChannelName_t& name,
const IpcChannelSide channelSide,
const size_t maxMsgSize = MAX_MESSAGE_SIZE,
const uint64_t maxMsgNumber = MAX_NUMBER_OF_MESSAGES) noexcept;

/// @todo iox-#1036 Remove when all channels are ported to the builder pattern
bool isInitialized() const noexcept
{
return m_data != nullptr;
}

/// @brief removes a named pipe artifact from the system
/// @return true if the artifact was removed, false when no artifact was found and
/// IpcChannelError::INTERNAL_LOGIC_ERROR when shm_unlink failed
Expand Down
18 changes: 2 additions & 16 deletions iceoryx_dust/source/posix_wrapper/message_queue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,31 +79,17 @@ expected<MessageQueue, IpcChannelError> MessageQueueBuilder::create() const noex
return ok(MessageQueue{std::move(sanitizedName), attributes, mqDescriptor, m_channelSide});
}

MessageQueue::MessageQueue(const IpcChannelName_t&& name,
MessageQueue::MessageQueue(const IpcChannelName_t& name,
const mq_attr attributes,
mqd_t mqDescriptor,
const IpcChannelSide channelSide) noexcept
: m_name(std::move(name))
: m_name(name)
, m_attributes(attributes)
, m_mqDescriptor(mqDescriptor)
, m_channelSide(channelSide)
{
}

// NOLINTNEXTLINE(readability-function-size) @todo iox-#832 make a struct out of arguments
expected<MessageQueue, IpcChannelError> MessageQueue::create(const IpcChannelName_t& name,
const IpcChannelSide channelSide,
const uint64_t maxMsgSize,
const uint64_t maxMsgNumber) noexcept
{
return MessageQueueBuilder()
.name(name)
.channelSide(channelSide)
.maxMsgSize(maxMsgSize)
.maxMsgNumber(maxMsgNumber)
.create();
}

MessageQueue::MessageQueue(MessageQueue&& other) noexcept
{
*this = std::move(other);
Expand Down
14 changes: 0 additions & 14 deletions iceoryx_dust/source/posix_wrapper/named_pipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,20 +120,6 @@ expected<NamedPipe, IpcChannelError> NamedPipeBuilder::create() const noexcept
return ok(NamedPipe{std::move(sharedMemory), data});
}

// NOLINTNEXTLINE(readability-function-size) @todo iox-#832 make a struct out of arguments
expected<NamedPipe, IpcChannelError> NamedPipe::create(const IpcChannelName_t& name,
const IpcChannelSide channelSide,
const size_t maxMsgSize,
const uint64_t maxMsgNumber) noexcept
{
return NamedPipeBuilder()
.name(name)
.channelSide(channelSide)
.maxMsgSize(maxMsgSize)
.maxMsgNumber(maxMsgNumber)
.create();
}

NamedPipe::NamedPipe(SharedMemoryObject&& sharedMemory, NamedPipeData* data) noexcept
: m_sharedMemory(std::move(sharedMemory))
, m_data(data)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved.
// Copyright (c) 2023 by Mathias Kraus <[email protected]>. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -24,13 +25,16 @@
#include "iceoryx_platform/socket.hpp"
#include "iceoryx_platform/stat.hpp"
#include "iceoryx_platform/un.hpp"
#include "iox/builder.hpp"
#include "iox/duration.hpp"
#include "iox/optional.hpp"

namespace iox
{
namespace posix
{
class UnixDomainSocketBuilder;

/// @brief Wrapper class for unix domain socket
class UnixDomainSocket
{
Expand All @@ -41,9 +45,12 @@ class UnixDomainSocket
static constexpr NoPathPrefix_t NoPathPrefix{};
static constexpr uint64_t NULL_TERMINATOR_SIZE = 1U;
static constexpr uint64_t MAX_MESSAGE_SIZE = platform::IOX_UDS_SOCKET_MAX_MESSAGE_SIZE - NULL_TERMINATOR_SIZE;
static constexpr uint64_t MAX_NUMBER_OF_MESSAGES = 10;
/// @brief The name length is limited by the size of the sockaddr_un::sun_path buffer and the IOX_SOCKET_PATH_PREFIX
static constexpr size_t LONGEST_VALID_NAME = sizeof(sockaddr_un::sun_path) - 1;

using Builder_t = UnixDomainSocketBuilder;

using UdsName_t = string<LONGEST_VALID_NAME>;
using Message_t = string<MAX_MESSAGE_SIZE>;

Expand All @@ -55,18 +62,6 @@ class UnixDomainSocket

~UnixDomainSocket() noexcept;

/// @brief factory method which guarantees that either a working object is produced
/// or an error value describing the error during construction
/// @tparam Targs the argument types which will be forwarded to the ctor
/// @param[in] args the argument values which will be forwarded to the ctor
/// @return returns an expected which either contains the object in a valid
/// constructed state or an error value stating why the construction failed.
template <typename... Targs>
static expected<UnixDomainSocket, IpcChannelError> create(Targs&&... args) noexcept;

/// @brief returns true if the object was constructed successfully, otherwise false
bool isInitialized() const noexcept;

/// @brief unlink the provided unix domain socket
/// @param name of the unix domain socket to unlink
/// @return true if the unix domain socket could be unlinked, false otherwise, IpcChannelError if error occured
Expand Down Expand Up @@ -99,51 +94,77 @@ class UnixDomainSocket
expected<std::string, IpcChannelError> timedReceive(const units::Duration& timeout) const noexcept;

private:
UnixDomainSocket(const IpcChannelName_t& name,
const IpcChannelSide channelSide,
const uint64_t maxMsgSize = MAX_MESSAGE_SIZE,
const uint64_t maxMsgNumber = 10U) noexcept;
friend class UnixDomainSocketBuilderNoPathPrefix;

UnixDomainSocket(const NoPathPrefix_t,
const UdsName_t& name,
UnixDomainSocket(const UdsName_t& name,
const IpcChannelSide channelSide,
const uint64_t maxMsgSize = MAX_MESSAGE_SIZE,
const uint64_t maxMsgNumber = 10U) noexcept;
const int32_t sockfd,
const sockaddr_un sockAddr,
const uint64_t maxMsgSize) noexcept;

expected<void, IpcChannelError> destroy() noexcept;

expected<void, IpcChannelError> initalizeSocket() noexcept;

IpcChannelError convertErrnoToIpcChannelError(const int32_t errnum) const noexcept;
IpcChannelError errnoToEnum(const int32_t errnum) const noexcept;
static IpcChannelError errnoToEnum(const UdsName_t& name, const int32_t errnum) noexcept;

expected<void, IpcChannelError> closeFileDescriptor() noexcept;
static expected<void, IpcChannelError> closeFileDescriptor(const UdsName_t& name,
const int sockfd,
const sockaddr_un& sockAddr,
IpcChannelSide channelSide) noexcept;

private:
static constexpr int32_t ERROR_CODE = -1;
static constexpr int32_t INVALID_FD = -1;

bool m_isInitialized{false};
IpcChannelError m_errorValue{IpcChannelError::NOT_INITIALIZED};

UdsName_t m_name;
IpcChannelSide m_channelSide = IpcChannelSide::CLIENT;
int32_t m_sockfd{INVALID_FD};
sockaddr_un m_sockAddr{};
uint64_t m_maxMessageSize{MAX_MESSAGE_SIZE};
};

class UnixDomainSocketBuilder
{
/// @brief Defines the socket name
IOX_BUILDER_PARAMETER(IpcChannelName_t, name, "")

/// @brief Defines how the socket is opened, i.e. as client or server
IOX_BUILDER_PARAMETER(IpcChannelSide, channelSide, IpcChannelSide::CLIENT)

/// @brief Defines the max message size of the socket
IOX_BUILDER_PARAMETER(uint64_t, maxMsgSize, UnixDomainSocket::MAX_MESSAGE_SIZE)

/// @brief Defines the max number of messages for the socket.
IOX_BUILDER_PARAMETER(uint64_t, maxMsgNumber, UnixDomainSocket::MAX_NUMBER_OF_MESSAGES)

template <typename... Targs>
expected<UnixDomainSocket, IpcChannelError> UnixDomainSocket::create(Targs&&... args) noexcept
public:
/// @brief create a unix domain socket
/// @return On success a 'UnixDomainSocket' is returned and on failure an 'IpcChannelError'.
expected<UnixDomainSocket, IpcChannelError> create() const noexcept;
};

class UnixDomainSocketBuilderNoPathPrefix
{
UnixDomainSocket newObject{std::forward<Targs>(args)...};
if (!newObject.m_isInitialized)
{
return err(newObject.m_errorValue);
}
/// @brief Defines the socket name
IOX_BUILDER_PARAMETER(UnixDomainSocket::UdsName_t, name, "")

/// @brief Defines how the socket is opened, i.e. as client or server
IOX_BUILDER_PARAMETER(IpcChannelSide, channelSide, IpcChannelSide::CLIENT)

return ok(std::move(newObject));
}
/// @brief Defines the max message size of the socket
IOX_BUILDER_PARAMETER(uint64_t, maxMsgSize, UnixDomainSocket::MAX_MESSAGE_SIZE)

/// @brief Defines the max number of messages for the socket.
IOX_BUILDER_PARAMETER(uint64_t, maxMsgNumber, UnixDomainSocket::MAX_NUMBER_OF_MESSAGES)

public:
/// @brief create a unix domain socket
/// @return On success a 'UnixDomainSocket' is returned and on failure an 'IpcChannelError'.
expected<UnixDomainSocket, IpcChannelError> create() const noexcept;
};

} // namespace posix
} // namespace iox
Expand Down
Loading

0 comments on commit f434f6f

Please sign in to comment.