pub fn multi_receive<T: Copy, W: Fn(&[(Option<&AtomicU64>, u64)]), R: Fn(&[Option<&AtomicU64>])>(
    queues: &[&RawQueue<T>],
    output: &mut [Option<QueueEntry<T>>],
    multi_wait: W,
    multi_ring: R,
    flags: ReceiveFlags
) -> Result<usize, QueueError>
Expand description

Wait for receiving on multiple raw queues. If any of the passed raw queues can return data, they will do so by writing it into the output array at the same index that they are in the queues variable. The queues and output arrays must be the same length. If no data is available in any queues, then the function will call back on multi_wait, which it expects to wait until any of the pairs (&x, y) meet the condition that *x != y. Before returning any data, the function will callback on multi_ring, to inform multiple queues that data was taken from them. It expects the multi_ring function to wake up any waiting threads on the supplied words of memory.

Note that both call backs specify the pointers as Option. In the case that an entry is None, there was no requested wait or wake operation for that queue, and that entry should be ignored.

If flags specifies ReceiveFlags::NON_BLOCK, then if no data is available, the function returns immediately with Err(QueueError::WouldBlock).

Rationale

This function is here to implement poll or select like functionality, wherein a given thread or program wants to wait on multiple incoming request channels and handle them itself, thus cutting down on the number of threads required. The maximum number of queues to use here is a trade-off — more means fewer threads, but since this function is linear in the number of queues, each thread could take longer to service requests.

The complexity of the multi_wait and multi_ring callbacks is present to avoid calling into the kernel often for high-contention queues.