zio.blocks.streams.queues

Members list

Type members

Classlikes

final class BlockingMpmcQueue[A <: AnyRef](capacity: Int)

A blocking MPMC (multi-producer, multi-consumer) queue.

A blocking MPMC (multi-producer, multi-consumer) queue.

Backed by MpmcRingBuffer for the fast path; uses LockSupport.parkNanos for blocking when the buffer is full or empty.

Multiple threads may call offer and take concurrently.

==Single-Waiter Design==

Only one producer and one consumer can be fast-path woken at a time. The queue maintains a single producerWaiter and consumerWaiter volatile slot. When a thread blocks, it registers itself in the appropriate slot and calls LockSupport.parkNanos(this, 1000L) (1 microsecond timeout). When the opposite side has data/space, it unparks the registered waiter. Other waiting threads wake up within 1 microsecond via the timeout and retry.

This design is virtual-thread friendly: parkNanos does not OS-block on virtual threads, allowing bounded re-checks without risk of permanent parking.

==Happens-Before Guarantee==

The pattern producerWaiter = Thread.currentThread() (volatile write) followed by if (closed) return false (volatile read) ensures that a close() call setting closed = true is always visible before the thread parks. This prevents the race where a thread parks after close() has already been called.

==close() Behavior==

close() unparks only the registered producerWaiter and consumerWaiter. Other waiting threads wake up within 1 microsecond via parkNanos timeout and detect the closed flag on retry. This is intentional and documented.

Null elements are not permitted.

Value parameters

capacity

The logical capacity. Rounded up to the next power of two >= 2 internally.

Attributes

Source
BlockingMpmcQueue.scala
Supertypes
class Object
trait Matchable
class Any
final class BlockingMpscQueue[A <: AnyRef](capacity: Int)

A blocking MPSC (multi-producer, single-consumer) queue.

A blocking MPSC (multi-producer, single-consumer) queue.

Backed by MpscRingBuffer for the fast path; uses LockSupport.park and LockSupport.unpark for blocking when the buffer is full or empty.

Multiple threads may call offer concurrently. Only a single thread may call take, drain, isEmpty, or isClosed.

Multi-producer parking: a single producerWaiter volatile slot is used. One producer registers and gets fast-path unpark from consumer. Others use parkNanos(1000) (1µs) to retry — VT-friendly, no starvation.

Null elements are not permitted.

Value parameters

capacity

The logical capacity. Rounded up to the next power of two internally.

Attributes

Source
BlockingMpscQueue.scala
Supertypes
class Object
trait Matchable
class Any
final class BlockingSpscQueue[A <: AnyRef](capacity: Int)

A blocking single-producer single-consumer queue.

A blocking single-producer single-consumer queue.

Backed by SpscRingBuffer for the fast path; uses LockSupport.park and LockSupport.unpark for blocking when the buffer is full or empty.

Two separate waiter slots are maintained — consumerWaiter and producerWaiter — so that each side registers in its own slot without overwriting the other side's registration. A single shared slot would introduce a lost-wakeup race: the producer could overwrite the consumer's registration before the consumer parks, causing the consumer's park to return via stale permit and then clear the producer's registration, leaving the producer permanently blocked.

Null elements are not permitted.

Value parameters

capacity

The logical capacity. Rounded up to the next power of two internally.

Attributes

Source
BlockingSpscQueue.scala
Supertypes
class Object
trait Matchable
class Any