Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iox-#1036 builder pattern for unix domain socket #2016

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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, "")
elBoberido marked this conversation as resolved.
Show resolved Hide resolved

/// @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
elBoberido marked this conversation as resolved.
Show resolved Hide resolved
{
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
Loading