This is an automated email from the ASF dual-hosted git repository.
chenBright pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brpc.git
The following commit(s) were added to refs/heads/master by this push:
new 81c15259 Fix ResourcePool block item count race (#3640)
81c15259 is described below
commit 81c15259750a9659865a1fae307aaf7614459630
Author: nkysg <[email protected]>
AuthorDate: Fri Oct 23 10:37:01 2026 +0800
Fix ResourcePool block item count race (#3640)
* Fix ResourcePool block item count race
* Optimize ResourcePool nitem publication
---
src/butil/resource_pool_inl.h | 36 ++++++++++++++++++++++--------------
1 file changed, 22 insertions(+), 14 deletions(-)
diff --git a/src/butil/resource_pool_inl.h b/src/butil/resource_pool_inl.h
index 163b0334..57134c90 100644
--- a/src/butil/resource_pool_inl.h
+++ b/src/butil/resource_pool_inl.h
@@ -116,7 +116,10 @@ public:
// To support cache-aligned objects, align Block.items by cacheline.
struct BAIDU_CACHELINE_ALIGNMENT Block {
BlockItem items[BLOCK_NITEM];
- size_t nitem;
+ // Written by the owning LocalPool and read by address_resource() from
+ // other threads. Publishing the increment after construction keeps the
+ // bounds check data-race-free.
+ butil::atomic<size_t> nitem;
Block() : nitem(0) {}
};
@@ -184,28 +187,32 @@ public:
} \
T* p = nullptr;
\
/* Fetch memory from local block */ \
- if (_cur_block && _cur_block->nitem < BLOCK_NITEM) { \
- id->value = _cur_block_index * BLOCK_NITEM + _cur_block->nitem; \
- auto item = _cur_block->items + _cur_block->nitem; \
- p = new (item->void_data()) T CTOR_ARGS; \
- if (!ResourcePoolValidator<T>::validate(p)) { \
- p->~T(); \
- return nullptr;
\
+ if (_cur_block) { \
+ const size_t nitem =
_cur_block->nitem.load(butil::memory_order_relaxed); \
+ if (nitem < BLOCK_NITEM) { \
+ id->value = _cur_block_index * BLOCK_NITEM + nitem; \
+ auto item = _cur_block->items + nitem; \
+ p = new (item->void_data()) T CTOR_ARGS; \
+ if (!ResourcePoolValidator<T>::validate(p)) { \
+ p->~T(); \
+ return nullptr; \
+ } \
+ _cur_block->nitem.store(nitem + 1,
butil::memory_order_release); \
+ return p; \
} \
- ++_cur_block->nitem; \
- return p; \
} \
/* Fetch a Block from global */ \
_cur_block = add_block(&_cur_block_index); \
if (_cur_block != nullptr) {
\
- id->value = _cur_block_index * BLOCK_NITEM + _cur_block->nitem; \
- auto item = _cur_block->items + _cur_block->nitem; \
+ const size_t nitem =
_cur_block->nitem.load(butil::memory_order_relaxed); \
+ id->value = _cur_block_index * BLOCK_NITEM + nitem; \
+ auto item = _cur_block->items + nitem; \
p = new (item->void_data()) T CTOR_ARGS; \
if (!ResourcePoolValidator<T>::validate(p)) { \
p->~T(); \
return nullptr;
\
} \
- ++_cur_block->nitem; \
+ _cur_block->nitem.store(nitem + 1, butil::memory_order_release); \
return p; \
} \
return nullptr;
\
@@ -267,7 +274,8 @@ public:
.load(butil::memory_order_consume);
if (__builtin_expect(b != nullptr, 1)) {
const size_t offset = id.value - block_index * BLOCK_NITEM;
- if (__builtin_expect(offset < b->nitem, 1)) {
+ if (__builtin_expect(
+ offset <
b->nitem.load(butil::memory_order_acquire), 1)) {
return (T*)b->items + offset;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]