Skip to content

Commit

Permalink
iox-eclipse-iceoryx#1036 Add builder pattern to 'UnixDomainSocket'
Browse files Browse the repository at this point in the history
  • Loading branch information
elBoberido committed Sep 4, 2023
1 parent 4406d46 commit c92eafb
Show file tree
Hide file tree
Showing 3 changed files with 274 additions and 199 deletions.
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 <elboberido@m-hias.de>. 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,6 +45,7 @@ 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;

Expand All @@ -55,17 +60,26 @@ 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;
/// @todo iox-#1036 Remove when all channels are ported to the builder pattern
static expected<UnixDomainSocket, IpcChannelError>
create(const IpcChannelName_t& name,
const IpcChannelSide channelSide,
const uint64_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
static expected<UnixDomainSocket, IpcChannelError>
create(const NoPathPrefix_t,
const UdsName_t& name,
const IpcChannelSide channelSide,
const uint64_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_sockfd != INVALID_FD;
}

/// @brief unlink the provided unix domain socket
/// @param name of the unix domain socket to unlink
Expand Down Expand Up @@ -99,51 +113,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, "")

return ok(std::move(newObject));
}
/// @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)

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 c92eafb

Please sign in to comment.