Skip to content

Commit

Permalink
iox-eclipse-iceoryx#2128 Add a name to the MePooSegment data struct…
Browse files Browse the repository at this point in the history
…ure and allow multiple write-access segments to be mapped
  • Loading branch information
Graham Palmer committed Jan 10, 2024
1 parent 5410bc9 commit bee8a00
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ namespace iox
error(MEPOO__MEMPOOL_GETCHUNK_POOL_IS_RUNNING_OUT_OF_CHUNKS) \
error(MEPOO__MEMPOOL_CHUNKSIZE_MUST_BE_MULTIPLE_OF_CHUNK_MEMORY_ALIGNMENT) \
error(MEPOO__MEMPOOL_ADDMEMPOOL_AFTER_GENERATECHUNKMANAGEMENTPOOL) \
error(MEPOO__MULTIPLE_SEGMENT_CONFIG_ENTRIES_WITH_SAME_NAME) \
error(MEPOO__TYPED_MEMPOOL_HAS_INCONSISTENT_STATE) \
error(MEPOO__TYPED_MEMPOOL_MANAGEMENT_SEGMENT_IS_BROKEN) \
error(MEPOO__USER_WITH_MORE_THAN_ONE_WRITE_SEGMENT) \
error(MEPOO__SEGMENT_COULD_NOT_APPLY_POSIX_RIGHTS_TO_SHARED_MEMORY) \
error(MEPOO__SEGMENT_UNABLE_TO_CREATE_SHARED_MEMORY_OBJECT) \
error(MEPOO__SEGMENT_INSUFFICIENT_SEGMENT_IDS) \
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
// Copyright (c) 2023 by Mathias Kraus <elboberido@m-hias.de>. All rights reserved.
// Copyright (c) 2024 by Latitude AI. 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 Down Expand Up @@ -35,7 +36,8 @@ template <typename SharedMemoryObjectType = PosixSharedMemoryObject, typename Me
class MePooSegment
{
public:
MePooSegment(const MePooConfig& mempoolConfig,
MePooSegment(const ShmName_t& name,
const MePooConfig& mempoolConfig,
BumpAllocator& managementAllocator,
const PosixGroup& readerGroup,
const PosixGroup& writerGroup,
Expand All @@ -46,15 +48,18 @@ class MePooSegment

MemoryManagerType& getMemoryManager() noexcept;

const ShmName_t& getSegmentName() const noexcept;

uint64_t getSegmentId() const noexcept;

uint64_t getSegmentSize() const noexcept;

protected:
SharedMemoryObjectType createSharedMemoryObject(const MePooConfig& mempoolConfig,
const PosixGroup& writerGroup) noexcept;
const ShmName_t& name) noexcept;

protected:
ShmName_t m_name;
PosixGroup m_readerGroup;
PosixGroup m_writerGroup;
uint64_t m_segmentId{0};
Expand Down
17 changes: 13 additions & 4 deletions iceoryx_posh/include/iceoryx_posh/internal/mepoo/mepoo_segment.inl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 - 2022 by Apex.AI Inc. All rights reserved.
// Copyright (c) 2023 by Mathias Kraus <elboberido@m-hias.de>. All rights reserved.
// Copyright (c) 2024 by Latitude AI. 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 Down Expand Up @@ -35,15 +36,17 @@ constexpr access_rights MePooSegment<SharedMemoryObjectType, MemoryManagerType>:

template <typename SharedMemoryObjectType, typename MemoryManagerType>
inline MePooSegment<SharedMemoryObjectType, MemoryManagerType>::MePooSegment(
const ShmName_t& name,
const MePooConfig& mempoolConfig,
BumpAllocator& managementAllocator,
const PosixGroup& readerGroup,
const PosixGroup& writerGroup,
const iox::mepoo::MemoryInfo& memoryInfo) noexcept
: m_readerGroup(readerGroup)
: m_name(name)
, m_readerGroup(readerGroup)
, m_writerGroup(writerGroup)
, m_memoryInfo(memoryInfo)
, m_sharedMemoryObject(createSharedMemoryObject(mempoolConfig, writerGroup))
, m_sharedMemoryObject(createSharedMemoryObject(mempoolConfig, name))
{
using namespace detail;
PosixAcl acl;
Expand All @@ -68,11 +71,11 @@ inline MePooSegment<SharedMemoryObjectType, MemoryManagerType>::MePooSegment(

template <typename SharedMemoryObjectType, typename MemoryManagerType>
inline SharedMemoryObjectType MePooSegment<SharedMemoryObjectType, MemoryManagerType>::createSharedMemoryObject(
const MePooConfig& mempoolConfig, const PosixGroup& writerGroup) noexcept
const MePooConfig& mempoolConfig, const ShmName_t& name) noexcept
{
return std::move(
typename SharedMemoryObjectType::Builder()
.name(writerGroup.getName())
.name(name)
.memorySizeInBytes(MemoryManager::requiredChunkMemorySize(mempoolConfig))
.accessMode(AccessMode::READ_WRITE)
.openMode(OpenMode::PURGE_AND_CREATE)
Expand Down Expand Up @@ -116,6 +119,12 @@ inline MemoryManagerType& MePooSegment<SharedMemoryObjectType, MemoryManagerType
return m_memoryManager;
}

template <typename SharedMemoryObjectType, typename MemoryManagerType>
inline const ShmName_t& MePooSegment<SharedMemoryObjectType, MemoryManagerType>::getSegmentName() const noexcept
{
return m_name;
}

template <typename SharedMemoryObjectType, typename MemoryManagerType>
inline uint64_t MePooSegment<SharedMemoryObjectType, MemoryManagerType>::getSegmentId() const noexcept
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 - 2022 by Apex.AI Inc. All rights reserved.
// Copyright (c) 2024 by Latitude AI. 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 Down Expand Up @@ -54,12 +55,12 @@ class SegmentManager
struct SegmentMapping
{
public:
SegmentMapping(const ShmName_t& sharedMemoryName,
SegmentMapping(const ShmName_t& name,
uint64_t size,
bool isWritable,
uint64_t segmentId,
const iox::mepoo::MemoryInfo& memoryInfo = iox::mepoo::MemoryInfo()) noexcept
: m_sharedMemoryName(sharedMemoryName)
: m_name(name)
, m_size(size)
, m_isWritable(isWritable)
, m_segmentId(segmentId)
Expand All @@ -68,7 +69,7 @@ class SegmentManager
{
}

ShmName_t m_sharedMemoryName{""};
ShmName_t m_name{""};
uint64_t m_size{0};
bool m_isWritable{false};
uint64_t m_segmentId{0};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
// Copyright (c) 2023 by Mathias Kraus <elboberido@m-hias.de>. All rights reserved.
// Copyright (c) 2024 by Latitude AI. 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 Down Expand Up @@ -41,10 +42,19 @@ inline SegmentManager<SegmentType>::SegmentManager(const SegmentConfig& segmentC
template <typename SegmentType>
inline void SegmentManager<SegmentType>::createSegment(const SegmentConfig::SegmentEntry& segmentEntry) noexcept
{
if (std::find_if(
m_segmentContainer.begin(),
m_segmentContainer.end(),
[&segmentEntry](const SegmentType& segment){ return segment.getSegmentName() == segmentEntry.m_name;}
) != m_segmentContainer.end())
{
errorHandler(PoshError::MEPOO__MULTIPLE_SEGMENT_CONFIG_ENTRIES_WITH_SAME_NAME);
return;
}
auto readerGroup = PosixGroup(segmentEntry.m_readerGroup);
auto writerGroup = PosixGroup(segmentEntry.m_writerGroup);
m_segmentContainer.emplace_back(
segmentEntry.m_mempoolConfig, *m_managementAllocator, readerGroup, writerGroup, segmentEntry.m_memoryInfo);
segmentEntry.m_name, segmentEntry.m_mempoolConfig, *m_managementAllocator, readerGroup, writerGroup, segmentEntry.m_memoryInfo);
}

template <typename SegmentType>
Expand All @@ -55,44 +65,17 @@ SegmentManager<SegmentType>::getSegmentMappings(const PosixUser& user) noexcept
auto groupContainer = user.getGroups();

SegmentManager::SegmentMappingContainer mappingContainer;
bool foundInWriterGroup = false;

// with the groups we can get all the segments (read or write) for the user
for (const auto& groupID : groupContainer)
{
for (const auto& segment : m_segmentContainer)
{
if (segment.getWriterGroup() == groupID)
{
// a user is allowed to be only in one writer group, as we currently only support one memory manager per
// process
if (!foundInWriterGroup)
{
mappingContainer.emplace_back(
segment.getWriterGroup().getName(), segment.getSegmentSize(), true, segment.getSegmentId());
foundInWriterGroup = true;
}
else
{
errorHandler(PoshError::MEPOO__USER_WITH_MORE_THAN_ONE_WRITE_SEGMENT);
return SegmentManager::SegmentMappingContainer();
}
}
}
}

for (const auto& groupID : groupContainer)
for (const auto& segment : m_segmentContainer)
{
for (const auto& segment : m_segmentContainer)
for (const auto& groupID : groupContainer)
{
// only add segments which are not yet added as writer
if (segment.getReaderGroup() == groupID
&& std::find_if(mappingContainer.begin(), mappingContainer.end(), [&](const SegmentMapping& mapping) {
return mapping.m_segmentId == segment.getSegmentId();
}) == mappingContainer.end())
bool isWritable = (segment.getWriterGroup() == groupID);
bool isReadable = (segment.getReaderGroup() == groupID);
if (isWritable || isReadable)
{
mappingContainer.emplace_back(
segment.getWriterGroup().getName(), segment.getSegmentSize(), false, segment.getSegmentId());
mappingContainer.emplace_back(segment.getSegmentName(), segment.getSegmentSize(), isWritable, segment.getSegmentId());
break;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion iceoryx_posh/source/runtime/shared_memory_user.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void SharedMemoryUser::openDataSegments(const uint64_t segmentId,
{
auto accessMode = segment.m_isWritable ? AccessMode::READ_WRITE : AccessMode::READ_ONLY;
PosixSharedMemoryObjectBuilder()
.name(segment.m_sharedMemoryName)
.name(segment.m_name)
.memorySizeInBytes(segment.m_size)
.accessMode(accessMode)
.openMode(OpenMode::OPEN_EXISTING)
Expand Down
15 changes: 12 additions & 3 deletions iceoryx_posh/test/moduletests/test_mepoo_segment.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 - 2022 by Apex.AI Inc. All rights reserved.
// Copyright (c) 2023 by Mathias Kraus <elboberido@m-hias.de>. All rights reserved.
// Copyright (c) 2024 by Latitude AI. 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 Down Expand Up @@ -138,7 +139,7 @@ class MePooSegment_test : public Test
std::unique_ptr<SUT> createSut()
{
return std::make_unique<SUT>(
mepooConfig, m_managementAllocator, PosixGroup{"iox_roudi_test1"}, PosixGroup{"iox_roudi_test2"});
"segment_name", mepooConfig, m_managementAllocator, PosixGroup{"iox_roudi_test1"}, PosixGroup{"iox_roudi_test2"});
}
};
MePooSegment_test::SharedMemoryObject_MOCK::createFct MePooSegment_test::SharedMemoryObject_MOCK::createVerificator;
Expand All @@ -160,15 +161,23 @@ TEST_F(MePooSegment_test, SharedMemoryCreationParameter)
const iox::OpenMode openMode,
const void*,
const iox::access_rights) {
EXPECT_THAT(f_name, Eq(detail::PosixSharedMemory::Name_t("iox_roudi_test2")));
EXPECT_THAT(f_name.c_str(), StrEq(detail::PosixSharedMemory::Name_t("segment_name").c_str()));
EXPECT_THAT(f_accessMode, Eq(iox::AccessMode::READ_WRITE));
EXPECT_THAT(openMode, Eq(iox::OpenMode::PURGE_AND_CREATE));
};
SUT sut{mepooConfig, m_managementAllocator, PosixGroup{"iox_roudi_test1"}, PosixGroup{"iox_roudi_test2"}};
SUT sut{"segment_name", mepooConfig, m_managementAllocator, PosixGroup{"iox_roudi_test1"}, PosixGroup{"iox_roudi_test2"}};
MePooSegment_test::SharedMemoryObject_MOCK::createVerificator =
MePooSegment_test::SharedMemoryObject_MOCK::createFct();
}

TEST_F(MePooSegment_test, GetSegmentName)
{
::testing::Test::RecordProperty("TEST_ID", "3508ab9c-a59b-48e4-a3f9-da9c0a2742e6");

auto sut = createSut();
EXPECT_THAT(sut->getSegmentName(), Eq(iox::ShmName_t("segment_name")));
}

TEST_F(MePooSegment_test, GetSegmentSize)
{
::testing::Test::RecordProperty("TEST_ID", "0eee50c0-251e-4313-bb35-d83a0de27ce2");
Expand Down
37 changes: 24 additions & 13 deletions iceoryx_posh/test/moduletests/test_mepoo_segment_management.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "iceoryx_posh/mepoo/mepoo_config.hpp"
#include "iceoryx_posh/mepoo/segment_config.hpp"
#include "iox/bump_allocator.hpp"
#include "iox/detail/serialization.hpp"
#include "iox/posix_group.hpp"
#include "iox/posix_shared_memory_object.hpp"
#include "iox/posix_user.hpp"
Expand All @@ -38,13 +39,23 @@ using namespace iox::mepoo;
class MePooSegmentMock
{
public:
MePooSegmentMock(const MePooConfig& mempoolConfig [[maybe_unused]],
MePooSegmentMock(const ShmName_t& name,
const MePooConfig& mempoolConfig [[maybe_unused]],
iox::BumpAllocator& managementAllocator [[maybe_unused]],
const PosixGroup& readerGroup [[maybe_unused]],
const PosixGroup& writerGroup [[maybe_unused]],
const MemoryInfo& memoryInfo [[maybe_unused]]) noexcept
: m_name(name)
{
}

const ShmName_t& getSegmentName() const noexcept
{
return m_name;
}

private:
ShmName_t m_name;
};

class SegmentManager_test : public Test
Expand All @@ -70,15 +81,15 @@ class SegmentManager_test : public Test
{
SegmentConfig config;
config.m_sharedMemorySegments.emplace_back("segment_name1", "iox_roudi_test1", "iox_roudi_test2", mepooConfig);
config.m_sharedMemorySegments.emplace_back("segment_name2", "iox_roudi_test2", "iox_roudi_test3", mepooConfig);
config.m_sharedMemorySegments.emplace_back("segment_name2", "iox_roudi_test3", "iox_roudi_test2", mepooConfig);
return config;
}

SegmentConfig getInvalidSegmentConfig()
SegmentConfig getSegmentConfigWithSameNameEntries()
{
SegmentConfig config;
config.m_sharedMemorySegments.emplace_back("segment_name1", "iox_roudi_test1", "iox_roudi_test1", mepooConfig);
config.m_sharedMemorySegments.emplace_back("segment_name2", "iox_roudi_test3", "iox_roudi_test1", mepooConfig);
config.m_sharedMemorySegments.emplace_back("duplicate_name", "iox_roudi_test1", "iox_roudi_test2", mepooConfig);
config.m_sharedMemorySegments.emplace_back("duplicate_name", "iox_roudi_test2", "iox_roudi_test3", mepooConfig);
return config;
}

Expand All @@ -87,7 +98,8 @@ class SegmentManager_test : public Test
SegmentConfig config;
for (uint64_t i = 0U; i < iox::MAX_SHM_SEGMENTS; ++i)
{
config.m_sharedMemorySegments.emplace_back("segment_name1", "iox_roudi_test1", "iox_roudi_test1", mepooConfig);
auto serial = Serialization::create("segment_name", i);
config.m_sharedMemorySegments.emplace_back(ShmName_t(TruncateToCapacity, serial.toString().c_str()), "iox_roudi_test1", "iox_roudi_test1", mepooConfig);
}
return config;
}
Expand Down Expand Up @@ -124,7 +136,7 @@ TEST_F(SegmentManager_test, getSegmentMappingsForWriteUser)
auto sut = createSut();
auto mapping = sut->getSegmentMappings(PosixUser{"iox_roudi_test2"});
ASSERT_THAT(mapping.size(), Eq(2u));
EXPECT_THAT(mapping[0].m_isWritable == mapping[1].m_isWritable, Eq(false));
EXPECT_THAT(mapping[0].m_isWritable == mapping[1].m_isWritable, Eq(true));
}

TEST_F(SegmentManager_test, getSegmentMappingsEmptyForNonRegisteredUser)
Expand Down Expand Up @@ -182,13 +194,12 @@ TEST_F(SegmentManager_test, getMemoryManagerForUserFailWithNonExistingUser)
EXPECT_FALSE(sut->getSegmentInformationWithWriteAccessForUser(PosixUser{"no_user"}).m_memoryManager.has_value());
}

TEST_F(SegmentManager_test, addingMoreThanOneWriterGroupFails)
TEST_F(SegmentManager_test, addingMoreThanOneEntryWithSameNameFails)
{
::testing::Test::RecordProperty("TEST_ID", "3fa29560-7341-43bf-a22e-2d3550b49e4e");
::testing::Test::RecordProperty("TEST_ID", "7ab2a78a-c9de-4e1d-a2da-6381f9a5a730");
GTEST_SKIP_FOR_ADDITIONAL_USER() << "This test requires the -DTEST_WITH_ADDITIONAL_USER=ON cmake argument";

SegmentConfig segmentConfig = getInvalidSegmentConfig();
SUT sut{segmentConfig, &allocator};
SegmentConfig segmentConfig = getSegmentConfigWithSameNameEntries();

iox::optional<iox::PoshError> detectedError;
auto errorHandlerGuard = iox::ErrorHandlerMock::setTemporaryErrorHandler<iox::PoshError>(
Expand All @@ -197,10 +208,10 @@ TEST_F(SegmentManager_test, addingMoreThanOneWriterGroupFails)
EXPECT_THAT(errorLevel, Eq(iox::ErrorLevel::FATAL));
});

sut.getSegmentMappings(PosixUser("iox_roudi_test1"));
SUT sut{segmentConfig, &allocator};

ASSERT_TRUE(detectedError.has_value());
EXPECT_THAT(detectedError.value(), Eq(iox::PoshError::MEPOO__USER_WITH_MORE_THAN_ONE_WRITE_SEGMENT));
EXPECT_THAT(detectedError.value(), Eq(iox::PoshError::MEPOO__MULTIPLE_SEGMENT_CONFIG_ENTRIES_WITH_SAME_NAME));
}

TEST_F(SegmentManager_test, addingMaximumNumberOfSegmentsWorks)
Expand Down

0 comments on commit bee8a00

Please sign in to comment.