There is an intrusive blocking, an intrusive non-blocking, and non-intrusive blocking version in the src/MPSCQ.h. For all cases consumer only spins if the producer is blocked before
prev->next = &first;.
The while loops can be replaced with
return statements to avoid unnecessary spinning
(e.g., to check other queues or perform other work until the producer is unblocked).
Blocking queues only return true and false pop which indicates whether the queue is empty or not, and thus whether the caller should block or not (blocking is done by the caller). There are examples in test directory.