Skip to content

Commit f3ccf20

Browse files
authored
Merge pull request #2443 from gpalmer-latai/iox-2440-chunk-management-race
iox-#2440 Fix race condition that can cause failed chunk management a…
2 parents 2fc7a5f + 9baed66 commit f3ccf20

5 files changed

Lines changed: 25 additions & 9 deletions

File tree

doc/website/release-notes/iceoryx-unreleased.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@
156156
- Fix windows performance issue [#2377](https://github.com/eclipse-iceoryx/iceoryx/issues/2377)
157157
- Max Client and Server cannot be configured independently of Max Publisher and Subscriber [#2394](https://github.com/eclipse-iceoryx/iceoryx/issues/2394)
158158
- Fix call to non-existing `getService` in channel.inl [#2426](https://github.com/eclipse-iceoryx/iceoryx/issues/2426)
159+
- Fix chunk management race condition causing failed management allocation [#2440](https://github.com/eclipse-iceoryx/iceoryx/issues/2440)
159160

160161
**Refactoring:**
161162

iceoryx_posh/include/iceoryx_posh/internal/mepoo/memory_manager.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Copyright (c) 2019 - 2020 by Robert Bosch GmbH. All rights reserved.
22
// Copyright (c) 2021 - 2022 by Apex.AI Inc. All rights reserved.
3+
// Copyright (c) 2025 by Latitude AI. All rights reserved.
34
//
45
// Licensed under the Apache License, Version 2.0 (the "License");
56
// you may not use this file except in compliance with the License.
@@ -72,6 +73,10 @@ class MemoryManager
7273
/// @return a SharedChunk if successful, otherwise a MemoryManager::Error
7374
expected<SharedChunk, Error> getChunk(const ChunkSettings& chunkSettings) noexcept;
7475

76+
/// @brief Release a chunk back to the mempools
77+
/// @param[in] chunkManagement Management for the chunk
78+
static void freeChunk(ChunkManagement& chunkManagement) noexcept;
79+
7580
uint32_t getNumberOfMemPools() const noexcept;
7681

7782
MemPoolInfo getMemPoolInfo(const uint32_t index) const noexcept;

iceoryx_posh/include/iceoryx_posh/internal/mepoo/shared_chunk.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
22
// Copyright (c) 2021 - 2022 by Apex.AI Inc. All rights reserved.
3+
// Copyright (c) 2025 by Latitude AI. All rights reserved.
34
//
45
// Licensed under the Apache License, Version 2.0 (the "License");
56
// you may not use this file except in compliance with the License.
@@ -64,7 +65,6 @@ class SharedChunk
6465
private:
6566
void decrementReferenceCounter() noexcept;
6667
void incrementReferenceCounter() noexcept;
67-
void freeChunk() noexcept;
6868

6969
private:
7070
ChunkManagement* m_chunkManagement{nullptr};

iceoryx_posh/source/mepoo/memory_manager.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Copyright (c) 2019 - 2020 by Robert Bosch GmbH. All rights reserved.
22
// Copyright (c) 2020 - 2022 by Apex.AI Inc. All rights reserved.
3+
// Copyright (c) 2025 by Latitude AI. All rights reserved.
34
//
45
// Licensed under the Apache License, Version 2.0 (the "License");
56
// you may not use this file except in compliance with the License.
@@ -206,6 +207,19 @@ expected<SharedChunk, MemoryManager::Error> MemoryManager::getChunk(const ChunkS
206207
}
207208
}
208209

210+
void MemoryManager::freeChunk(ChunkManagement& chunkManagement) noexcept
211+
{
212+
const auto* chunkHeader = static_cast<void*>(chunkManagement.m_chunkHeader.get());
213+
const auto mempool = chunkManagement.m_mempool;
214+
215+
// Here the chunk management must be freed before the chunk itself to maintain
216+
// the invariant that there are always at least as many chunk management chunks available as payload chunks
217+
chunkManagement.m_chunkManagementPool->freeChunk(&chunkManagement);
218+
// NOTE: chunkManagement is a dangling reference from here on out
219+
220+
mempool->freeChunk(chunkHeader);
221+
}
222+
209223
std::ostream& operator<<(std::ostream& stream, const MemoryManager::Error value) noexcept
210224
{
211225
stream << asStringLiteral(value);

iceoryx_posh/source/mepoo/shared_chunk.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
22
// Copyright (c) 2021 - 2022 by Apex.AI Inc. All rights reserved.
3+
// Copyright (c) 2025 by Latitude AI. All rights reserved.
34
//
45
// Licensed under the Apache License, Version 2.0 (the "License");
56
// you may not use this file except in compliance with the License.
@@ -16,6 +17,7 @@
1617
// SPDX-License-Identifier: Apache-2.0
1718

1819
#include "iceoryx_posh/internal/mepoo/shared_chunk.hpp"
20+
#include "iceoryx_posh/internal/mepoo/memory_manager.hpp"
1921

2022
namespace iox
2123
{
@@ -54,17 +56,11 @@ void SharedChunk::decrementReferenceCounter() noexcept
5456
if ((m_chunkManagement != nullptr)
5557
&& (m_chunkManagement->m_referenceCounter.fetch_sub(1U, std::memory_order_relaxed) == 1U))
5658
{
57-
freeChunk();
59+
MemoryManager::freeChunk(*m_chunkManagement);
60+
m_chunkManagement = nullptr;
5861
}
5962
}
6063

61-
void SharedChunk::freeChunk() noexcept
62-
{
63-
m_chunkManagement->m_mempool->freeChunk(static_cast<void*>(m_chunkManagement->m_chunkHeader.get()));
64-
m_chunkManagement->m_chunkManagementPool->freeChunk(m_chunkManagement);
65-
m_chunkManagement = nullptr;
66-
}
67-
6864
SharedChunk& SharedChunk::operator=(const SharedChunk& rhs) noexcept
6965
{
7066
if (this != &rhs)

0 commit comments

Comments
 (0)