-
Notifications
You must be signed in to change notification settings - Fork 152
Description
IPC channel multiplexing needs non-blocking variants of IpcReceiverSet::select to support SubReceiverSet (and thereby routing). Non-blocking variants of select may also be useful more generally and we should avoid biasing the variants towards multiplexing.
glyn/ipc-channel-mux#4 requires non-blocking select (without a timeout) whereas glyn/ipc-channel-mux#2 and glyn/ipc-channel-mux#5 require non-blocking select with timeout.
The API and semantics of these variants should be a cross between the API/semantics of IpcReceiverSet::select and the non-blocking API/semantics of IpcReceiver::try_recv and IpcReceiver::try_recv_timeout (see "Existing APIs" below), probably along the following lines:
#[derive(Debug)]
pub enum TrySelectError {
IoError(io::Error),
Empty,
}
impl IpcReceiverSet {
pub fn try_select(&mut self) -> Result<Vec<IpcSelectionResult>, TrySelectError> {...}
pub fn try_select_timeout(&mut self, duration: Duration) -> Result<Vec<IpcSelectionResult>, TrySelectError> {...}
...
}
Existing APIs
Existing select API:
impl IpcReceiverSet {
/// Wait for IPC messages received on any of the receivers in the set. The
/// method will return multiple events. An event may be either a message
/// received or a channel closed event.
///
/// [IpcReceiver]: struct.IpcReceiver.html
pub fn select(&mut self) -> Result<Vec<IpcSelectionResult>, io::Error> {...}
...
}
Existing IpcReceiver blocking and non-blocking API:
#[derive(Debug)]
pub enum TryRecvError {
IpcError(IpcError),
Empty,
}
impl<T> IpcReceiver<T>
where
T: for<'de> Deserialize<'de> + Serialize,
{
/// Blocking receive.
pub fn recv(&self) -> Result<T, IpcError> {
self.os_receiver.recv()?.to().map_err(IpcError::Bincode)
}
/// Non-blocking receive
pub fn try_recv(&self) -> Result<T, TryRecvError> {...}
/// Blocks for up to the specified duration attempting to receive a message.
///
/// This may block for longer than the specified duration if the channel is busy. If your timeout
/// exceeds the duration that your operating system can represent in milliseconds, this may
/// block forever. At the time of writing, the smallest duration that may trigger this behavior
/// is over 24 days.
pub fn try_recv_timeout(&self, duration: Duration) -> Result<T, TryRecvError> {...}
...
}