Skip to content

Commit

Permalink
Merge pull request #2014 from elBoberido/iox-1036-builder-pattern-for…
Browse files Browse the repository at this point in the history
…-message-queue

iox-#1036 Builder pattern for message queue
  • Loading branch information
elBoberido authored Sep 4, 2023
2 parents c58a4b8 + 3b67f47 commit e70767a
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 157 deletions.
35 changes: 18 additions & 17 deletions doc/website/release-notes/iceoryx-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
- Extend `concatenate`, `operator+`, `unsafe_append` and `append` of `iox::string` for chars [\#208](https://github.com/eclipse-iceoryx/iceoryx/issues/208)
- Extend `unsafe_append` and `append` methods of `iox::string` for `std::string` [\#208](https://github.com/eclipse-iceoryx/iceoryx/issues/208)
- The iceoryx development environment supports multiple running docker containers [\#1410](https://github.com/eclipse-iceoryx/iceoryx/issues/1410)
- Use builder pattern in FileLock [\#1036](https://github.com/eclipse-iceoryx/iceoryx/issues/1036)
- Add the ability to adjust path and file permissions of the file lock
- Create convenience macro for `NewType` [\#1425](https://github.com/eclipse-iceoryx/iceoryx/issues/1425)
- Add posix thread wrapper [\#1365](https://github.com/eclipse-iceoryx/iceoryx/issues/1365)
- Apps send only the heartbeat when monitoring is enabled in roudi [\#1436](https://github.com/eclipse-iceoryx/iceoryx/issues/1436)
Expand Down Expand Up @@ -99,8 +97,17 @@
- Use `GTEST_FAIL` and `GTEST_SUCCEED` instead of `FAIL` and `SUCCEED` [\#1072](https://github.com/eclipse-iceoryx/iceoryx/issues/1072)
- posix wrapper `SharedMemoryObject` is silent on success [\#971](https://github.com/eclipse-iceoryx/iceoryx/issues/971)
- Remove creation design pattern class with in place implementation [\#1036](https://github.com/eclipse-iceoryx/iceoryx/issues/1036)
- posix wrapper `SharedMemoryObject` uses builder pattern instead of creation
- Builder pattern extracted from `helplets.hpp` into `iox/builder.hpp`
- the following classes use the builder pattern instead of creation
- `SharedMemoryObject`
- `MemoryMap`
- `SharedMemory`
- `MessageQueue`
- `FileLock`
- Add the ability to adjust path and file permissions of the file lock
- `Mutex`
- `NamedSemaphore`
- `UnnamedSemaphore`
- Builder pattern extracted from `helplets.hpp` into `iox/builder.hpp`
- Uninteresting mock function calls in tests [\#1341](https://github.com/eclipse-iceoryx/iceoryx/issues/1341)
- `cxx::unique_ptr` owns deleter, remove all deleter classes [\#1143](https://github.com/eclipse-iceoryx/iceoryx/issues/1143)
- Remove `iox::posix::Timer` [\#337](https://github.com/eclipse-iceoryx/iceoryx/issues/337)
Expand All @@ -125,7 +132,6 @@
- Rename `algorithm::max` and `algorithm::min` to `algorithm::maxVal` and `algorithm::minVal` [\#1394](https://github.com/eclipse-iceoryx/iceoryx/issues/1394)
- Extract `iceoryx_hoofs/platform` into separate package `iceoryx_platform` [\#1615](https://github.com/eclipse-iceoryx/iceoryx/issues/1615)
- `cxx::unique_ptr` is no longer nullable [\#1104](https://github.com/eclipse-iceoryx/iceoryx/issues/1104)
- Use builder pattern in mutex [\#1036](https://github.com/eclipse-iceoryx/iceoryx/issues/1036)
- Change return type of `vector::erase` to bool [\#1662](https://github.com/eclipse-iceoryx/iceoryx/issues/1662)
- `ReleativePointer::registerPtr` returns `iox::optional` [\#605](https://github.com/eclipse-iceoryx/iceoryx/issues/605)
- `iox::function` is no longer nullable [\#1104](https://github.com/eclipse-iceoryx/iceoryx/issues/1104)
Expand Down Expand Up @@ -155,26 +161,21 @@

**API Breaking Changes:**

1. Builder pattern in `SharedMemoryObject` instead of creation pattern
1. Builder pattern instead of creation pattern

```cpp
// before
auto sharedMemory = iox::posix::SharedMemoryObject::create("shmAllocate",
16,
iox::posix::AccessMode::READ_WRITE,
iox::posix::OpenMode::PURGE_AND_CREATE,
iox::posix::SharedMemoryObject::NO_ADDRESS_HINT);
auto fooObject = iox::Foo::create("Bar", 42);

// after
auto sharedMemory = iox::posix::SharedMemoryObjectBuilder()
.name("shmAllocate")
.memorySizeInBytes(16)
.accessMode(iox::posix::AccessMode::READ_WRITE)
.openMode(iox::posix::OpenMode::PURGE_AND_CREATE)
.permissions(iox::perms::owner_all)
auto fooObject = iox::FooBuilder()
.name("Bar")
.memorySizeInBytes(42)
.create();
```

The **refactoring** section has a list with all the affected classes. Have a look at the documentation of these classes for more details.

2. Builder pattern extracted from `helplets.hpp` into `iox/builder.hpp`

```cpp
Expand Down
71 changes: 52 additions & 19 deletions iceoryx_dust/include/iceoryx_dust/posix_wrapper/message_queue.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2019 - 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 @@ -17,12 +18,13 @@
#ifndef IOX_DUST_POSIX_WRAPPER_MESSAGE_QUEUE_HPP
#define IOX_DUST_POSIX_WRAPPER_MESSAGE_QUEUE_HPP

#include "iceoryx_dust/design/creation.hpp"
#include "iceoryx_hoofs/internal/posix_wrapper/ipc_channel.hpp"
#include "iceoryx_platform/fcntl.hpp"
#include "iceoryx_platform/mqueue.hpp"
#include "iceoryx_platform/stat.hpp"
#include "iox/builder.hpp"
#include "iox/duration.hpp"
#include "iox/expected.hpp"
#include "iox/optional.hpp"

namespace iox
Expand All @@ -31,11 +33,11 @@ namespace posix
{
/// @brief Wrapper class for posix message queue
///
/// @tparam NON_BLOCKING specifies the type of message queue. A non-blocking message queue will immediately return from
/// a send/receive call if the queue is full/empty. A blocking message has member functions timedSend and timedReceive
/// which allow to specify a maximum timeout duration.
/// @code
/// auto mq = posix::MessageQueue<true>::CreateMessageQueue("/MqName123");
/// auto mq = iox::posix::MessageQueueBuilder()
/// .name("/MqName123")
/// .channelSide(iox::posix::IpcChannelSide::CLIENT)
/// .create();
/// if (mq.has_value())
/// {
/// mq->send("important message, bla.");
Expand All @@ -44,29 +46,36 @@ namespace posix
/// mq->receive(str);
/// }
/// @endcode
class MessageQueue : public DesignPattern::Creation<MessageQueue, IpcChannelError>
class MessageQueue
{
public:
static constexpr mqd_t INVALID_DESCRIPTOR = std::numeric_limits<mqd_t>::max();
static constexpr int32_t ERROR_CODE = -1;
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;

/// for calling private constructor in create method
friend class DesignPattern::Creation<MessageQueue, IpcChannelError>;

/// default constructor. The result is an invalid MessageQueue object which can be reassigned later by using the
/// move constructor.
MessageQueue() noexcept;

MessageQueue() noexcept = delete;
MessageQueue(const MessageQueue& other) = delete;
MessageQueue(MessageQueue&& other) noexcept;
MessageQueue& operator=(const MessageQueue& other) = delete;
MessageQueue& operator=(MessageQueue&& other) noexcept;

~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 @@ -90,12 +99,15 @@ class MessageQueue : public DesignPattern::Creation<MessageQueue, IpcChannelErro
static expected<bool, IpcChannelError> isOutdated() noexcept;

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

expected<mqd_t, IpcChannelError> open(const IpcChannelName_t& name, const IpcChannelSide channelSide) noexcept;
MessageQueue(const IpcChannelName_t&& name,
const mq_attr attributes,
mqd_t mqDescriptor,
const IpcChannelSide channelSide) noexcept;

static expected<mqd_t, IpcChannelError>
open(const IpcChannelName_t& name, mq_attr& attributes, const IpcChannelSide channelSide) noexcept;

expected<void, IpcChannelError> close() noexcept;
expected<void, IpcChannelError> unlink() noexcept;
Expand All @@ -119,8 +131,29 @@ class MessageQueue : public DesignPattern::Creation<MessageQueue, IpcChannelErro
/// NOLINTJUSTIFICATION used inside the wrapper so that the user does not have to use this
/// construct from outside
/// NOLINTNEXTLINE(hicpp-signed-bitwise)
static constexpr mode_t m_filemode{S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH};
static constexpr mode_t FILE_MODE{S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH};
};

class MessageQueueBuilder
{
/// @brief Defines the message queue name
IOX_BUILDER_PARAMETER(IpcChannelName_t, name, "")

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

/// @brief Defines the max message size of the message queue
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)

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

} // namespace posix
} // namespace iox

Expand Down
Loading

0 comments on commit e70767a

Please sign in to comment.