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.