explicite producer inner call set_many_empty lead to assert(false)
inline bool set_many_empty(MOODYCAMEL_MAYBE_UNUSED index_t i, size_t count)
{
MOODYCAMEL_CONSTEXPR_IF (context == explicit_context && BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) {
// Set flags
std::atomic_thread_fence(std::memory_order_release);
i = BLOCK_SIZE - 1 - static_cast<size_t>(i & static_cast<index_t>(BLOCK_SIZE - 1)) - count + 1;
for (size_t j = 0; j != count; ++j) {
assert(!emptyFlags[i + j].load(std::memory_order_relaxed)); @marked 1
emptyFlags[i + j].store(true, std::memory_order_relaxed);
}
return false;
}
else {
// Increment counter
auto prevVal = elementsCompletelyDequeued.fetch_add(count, std::memory_order_release);
assert(prevVal + count <= BLOCK_SIZE);
return prevVal + count == BLOCK_SIZE;
}
}
code at @marked 1, if the block has been marked true, it will trigger assert(false) and coredump the program. i wonder:
- how can it be?
- can comment such code, actually, the block just marked rue once more
Obviously the assertion should not fire. Can you share an example that reproduces this?
Obviously the assertion should not fire. Can you share an example that reproduces this?
sorry too late, example as below:
int main(int argc, char** argv) { moodycamel::ConcurrentQueuestd::string que; std::vectormoodycamel::ProducerToken vecP;
std::string data("string");
for( int i=0; i<3; i++ )
{
vecP.emplace_back(moodycamel::ProducerToken(que));
std::thread th([&]{
std::vector<std::string> dataBuck(100);
size_t num;
for(;;)
{
num = que.try_dequeue_bulk_from_producer(vecP[i], &dataBuck[0], 100);
if ( num > 0 )
{
for ( size_t j=0; j<num; j++)
{
// do something else
}
}
}
});
th.detach();
}
for( int i=0; i<8; i++)
{
std::thread th([=,&que]{
for(;;)
{
std::hash<std::string> h;
que.enqueue(vecP[h(data + std::to_string(i))/3], data);
}
});
th.detach();
}
getchar();
return 0;
}
In this example, multiple producer threads are sharing the same producer tokens concurrently, which breaks the contract of the API.
In this example, multiple producer threads are sharing the same producer tokens concurrently, which breaks the contract of the API.
get it, thanks