Skip to content

Commit

Permalink
iox-#218 Adapt to new unique_ptr API.
Browse files Browse the repository at this point in the history
Signed-off-by: Ithier Jeff (CC-AD/EYF1) <[email protected]>
  • Loading branch information
orecham committed Sep 29, 2020
1 parent 9359acb commit 80b471e
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ namespace iox
{
namespace popo
{

// ============================== BasePublisher ============================== //

template <typename T, typename port_t>
BasePublisher<T, port_t>::BasePublisher(const capro::ServiceDescription&)
inline BasePublisher<T, port_t>::BasePublisher(const capro::ServiceDescription&)
/// @todo #25 : m_port(iox::runtime::PoshRuntime::getInstance().getMiddlewareSender(service, ""))
{
}
Expand Down Expand Up @@ -90,13 +93,24 @@ inline bool BasePublisher<T, port_t>::hasSubscribers() const noexcept
template <typename T, typename port_t>
inline Sample<T> BasePublisher<T, port_t>::convertChunkHeaderToSample(const mepoo::ChunkHeader* const header) noexcept
{
return Sample<T>(cxx::unique_ptr<T>(reinterpret_cast<T*>(header->payload()),
[this](T* const p) {
auto header =
mepoo::convertPayloadPointerToChunkHeader(reinterpret_cast<void*>(p));
this->m_port.freeChunk(header);
}),
*this);
return Sample<T>(
cxx::unique_ptr<T>(reinterpret_cast<T*>(header->payload()), m_sampleDeleter),
*this);
}

// ============================== Sample Deleter ============================== //

template <typename T, typename port_t>
inline BasePublisher<T, port_t>::PublisherSampleDeleter::PublisherSampleDeleter(port_t& port)
: m_port(std::ref(port))
{}

template <typename T, typename port_t>
inline void BasePublisher<T, port_t>::PublisherSampleDeleter::operator()(T* const ptr) const
{
auto header =
mepoo::convertPayloadPointerToChunkHeader(reinterpret_cast<void*>(ptr));
m_port.get().freeChunk(header);
}

} // namespace popo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ namespace iox
{
namespace popo
{

// ============================== BaseSubscriber ============================== //

template <typename T, typename port_t>
BaseSubscriber<T, port_t>::BaseSubscriber(const capro::ServiceDescription&)
/// @todo #25 : m_port(iox::runtime::PoshRuntime::getInstance().getMiddlewareReceiver(service, ""))
Expand Down Expand Up @@ -77,10 +80,7 @@ inline cxx::expected<cxx::optional<Sample<const T>>, ChunkReceiveError> BaseSubs
if (optionalHeader.has_value())
{
auto header = optionalHeader.value();
auto samplePtr = cxx::unique_ptr<T>(reinterpret_cast<T*>(header->payload()), [this](T* const allocation) {
auto header = mepoo::convertPayloadPointerToChunkHeader(allocation);
this->m_port.releaseChunk(header);
});
auto samplePtr = cxx::unique_ptr<T>(reinterpret_cast<T*>(header->payload()), m_sampleDeleter);
return cxx::success<cxx::optional<Sample<const T>>>(
cxx::make_optional<Sample<const T>>(std::move(samplePtr)));
}
Expand Down Expand Up @@ -116,6 +116,21 @@ inline bool BaseSubscriber<T, port_t>::hasTriggered() const noexcept
return m_port.hasNewChunks();
}

// ============================== Sample Deleter ============================== //

template <typename T, typename port_t>
inline BaseSubscriber<T, port_t>::SubscriberSampleDeleter::SubscriberSampleDeleter(port_t& port)
: m_port(std::ref(port))
{}

template <typename T, typename port_t>
inline void BaseSubscriber<T, port_t>::SubscriberSampleDeleter::operator()(T* const ptr) const
{
auto header =
mepoo::convertPayloadPointerToChunkHeader(reinterpret_cast<void*>(ptr));
m_port.get().releaseChunk(header);
}

} // namespace popo
} // namespace iox

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,10 @@ class PublisherInterface
PublisherInterface() = default;
};


///
/// @brief The BasePublisher class contains the common implementation for the different publisher specializations.
///
template <typename T, typename port_t = PublisherPortUser>
template <typename T, typename port_t = iox::PublisherPortUserType>
class BasePublisher : public PublisherInterface<T>
{
protected:
Expand Down Expand Up @@ -107,6 +106,24 @@ class BasePublisher : public PublisherInterface<T>
BasePublisher(const capro::ServiceDescription& service);

private:

///
/// @brief The PublisherSampleDeleter struct is a custom deleter in functor form which releases laons to a sample's
/// underlying memory chunk via a publishers publisher port.
/// Each publisher should create its own instance of this deleter struct to work with its specific port.
///
/// @note As this deleter is coupled to the Publisher implementation, it should only be used within the publisher
/// context.
///
struct PublisherSampleDeleter
{
public:
PublisherSampleDeleter(port_t& port);
void operator()(T* const ptr) const;
private:
std::reference_wrapper<port_t> m_port;
};

///
/// @brief convertChunkHeaderToSample Helper function that wraps the payload of a ChunkHeader in an Sample.
/// @param header The chunk header describing the allocated memory chunk to use in the sample.
Expand All @@ -117,6 +134,8 @@ class BasePublisher : public PublisherInterface<T>
protected:
port_t m_port{nullptr};
bool m_useDynamicPayloadSize = true;

PublisherSampleDeleter m_sampleDeleter{m_port};
};

} // namespace popo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace popo
{
using uid_t = UniquePortId;

template <typename T, typename port_t = popo::SubscriberPortUser>
template <typename T, typename port_t = iox::SubscriberPortUserType>
class BaseSubscriber : public Condition
{
public:
Expand Down Expand Up @@ -95,8 +95,28 @@ class BaseSubscriber : public Condition
protected:
BaseSubscriber(const capro::ServiceDescription& service);

private:

///
/// @brief The SubscriberSampleDeleter struct is a custom deleter in functor form which releases laons to a sample's
/// underlying memory chunk via a subscriber's subscriber port.
/// Each subscriber should create its own instance of this deleter struct to work with its specific port.
///
/// @note As this deleter is coupled to the Subscriber implementation, it should only be used within the subscriber
/// context.
///
struct SubscriberSampleDeleter
{
public:
SubscriberSampleDeleter(port_t& port);
void operator()(T* const ptr) const;
private:
std::reference_wrapper<port_t> m_port;
};

protected:
port_t m_port{nullptr};
SubscriberSampleDeleter m_sampleDeleter{m_port};
};

} // namespace popo
Expand Down
4 changes: 2 additions & 2 deletions iceoryx_posh/include/iceoryx_posh/popo/modern_api/sample.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class Sample
void publish() noexcept;

protected:
cxx::unique_ptr<T> m_samplePtr{nullptr};
cxx::unique_ptr<T> m_samplePtr{[](T* const){}}; // Placeholder. This is overwritten on sample construction.
std::reference_wrapper<PublisherInterface<T>> m_publisherRef;
};

Expand All @@ -93,7 +93,7 @@ class Sample<const T>
const mepoo::ChunkHeader* getHeader() noexcept;

private:
cxx::unique_ptr<T> m_samplePtr{nullptr};
cxx::unique_ptr<T> m_samplePtr{[](T* const){}}; // Placeholder. This is overwritten on sample construction.
};

} // namespace popo
Expand Down
19 changes: 18 additions & 1 deletion iceoryx_posh/test/moduletests/test_popo_base_subscriber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ TEST_F(BaseSubscriberTest, HasNewSamplesCallForwardedToUnderlyingSubscriberPort)
// ===== Cleanup ===== //
}

TEST_F(BaseSubscriberTest, ReceiveReturnsAllocatedMemoryChunksInSamples)
TEST_F(BaseSubscriberTest, ReceiveReturnsAllocatedMemoryChunksWrappedInSample)
{
// ===== Setup ===== //
auto chunk =
Expand All @@ -172,6 +172,23 @@ TEST_F(BaseSubscriberTest, ReceiveReturnsAllocatedMemoryChunksInSamples)
// ===== Cleanup ===== //
}

TEST_F(BaseSubscriberTest, ReceivedSamplesAreAutomaticallyDeletedWhenOutOfScope)
{
// ===== Setup ===== //
auto chunk =
reinterpret_cast<iox::mepoo::ChunkHeader*>(iox::cxx::alignedAlloc(32, sizeof(iox::mepoo::ChunkHeader)));
EXPECT_CALL(sut.getMockedPort(), tryGetChunk)
.WillOnce(Return(ByMove(iox::cxx::success<iox::cxx::optional<const iox::mepoo::ChunkHeader*>>(
const_cast<const iox::mepoo::ChunkHeader*>(chunk)))));
EXPECT_CALL(sut.getMockedPort(), releaseChunk).Times(AtLeast(1));
// ===== Test ===== //
{
auto result = sut.receive();
}
// ===== Verify ===== //
// ===== Cleanup ===== //
}

TEST_F(BaseSubscriberTest, ReceiveForwardsErrorsFromUnderlyingPort)
{
// ===== Setup ===== //
Expand Down

0 comments on commit 80b471e

Please sign in to comment.