Consider the following structure:
struct T {
~T() { delete[] buff; }
int* buff = nullptr; };
T* t = new T();
auto queue = boost::lockfree::queue<T*>(0);
// Thread A
t->buff = int[10];
queue.push(t);
// Thread Z
T* t = nullptr;
while(true)
if(queue.pop(t))
delete t; // Is this OK? If not, what kind of synchronization I need to make it OK?
The general problem is that different threads (A to Y) work together on shared pointers (not std::shared_ptr). At some point, no one but Thread A works with a pointer t
and Thread A sees everything others have done to *t
, so Thread A can safely call delete t
. Instead, it pushes t
into a queue and Thread Z pops from the queue and does the delete t
. The question is how do we make sure Thread Z sees the last value assigned to t->buff
? Is there any synchronization in boost::lockfree::queue
that guarantees this? or we need to do something ourselves (what)?
Yes, this is safe! You have sole ownership over the value popped from the queue. push
has to use memory_order_release
(or stronger) and pop
has to use memory_order_acquire
(or stronger), because otherwise the implementation would be completely useless (you could do nothing with the pointer you just popped from the queue). I haven't checked the code, but you say that the implementation uses memory_order_seq_cst
, so you should be good!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With