[ Thread Safety ] boost::lockfree::queue<T> data race when T is a pointer type
- Dominant language
- C++
- Stars
- 160
- Forks
- 99
- PR merge metrics
- No merged PRs in 30d
Description
**Issue Summary**
When using `boost::lockfree::queue` with `T` as a pointer type (e.g., `PGconn*`), concurrent `pop()` operations may return the same front node to multiple threads, even if the return value is checked. This violates the queue's thread-safety guarantee.
**Reproduction Steps**
1. Define a queue with pointer type (e.g., `PGconn*` pointers): `boost::lockfree::queue unsafe_queue(1024);`
2. Concurrently call `push()` and `pop()` from multiple threads and track the number of times each `PGconn*` is popped and pushed.
**Expected Behavior**
Each enqueued `PGconn*` should be pushed and popped equal times.
**Actual Behavior**
For `boost::lockfree::queue`, some `PGconn*` pointers are popped much more times than they are pushed.
For `boost::lockfree::queue` (where `Conn` wraps `PGconn*`), the behavior is correct (`pop count == push count`).
**Example Code**
```cpp
// Thread-unsafe case
boost::lockfree::queue unsafe_queue(1024);
// Concurrent pushes and pops will yield duplicate PGconn* pointers.
// Thread-safe case
struct Conn { PGconn* pgconn; };
boost::lockfree::queue safe_queue(1024);
// Concurrent pushes and pops behave correctly.
```
**Root Cause Analysis**
The issue likely stems from how pointer types are handled internally in `boost::lockfree::queue`. The queue may fail to atomically update the head node when `T` is a pointer, leading to race conditions. This does not occur when `T` is a user-defined type (e.g., `Conn`), possibly due to stricter memory ordering or type-specific handling.
Every time an element is dequeued, its number of entries and exits is counted once. The number of pops is **always greater than or equal to** pushes. There has **never** been a situation where the number of pops is less than pushes. **Therefore, the problem is likely to lie in the** `pop()`.
**Environment**
`Boost version: 1.83.0`
`Compiler: gcc/g++ 13.3`
`OS: Linux x86_64`
**Additional Notes**
The bug may also affect other pointer types (`int*`, custom class pointers, etc.), but only `PGconn*` is explicitly tested.
The lock-free context used for `push()` and `pop()` operations is confirmed to be correct (no external races).
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.