Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/platform/inprocess/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ impl OsIpcReceiver {
Ok(MpscChannelMessage(d,c,s)) => Ok((d,
c.into_iter().map(OsOpaqueIpcChannel::new).collect(),
s)),
Err(_) => Err(MpscError::ChannelClosedError),
Err(mpsc::TryRecvError::Disconnected) => Err(MpscError::ChannelClosedError),
Err(_) => Err(MpscError::UnknownError),
}
}
}
Expand Down Expand Up @@ -141,7 +142,7 @@ impl OsIpcSender {
-> Result<(),MpscError>
{
match self.sender.borrow().send(MpscChannelMessage(data.to_vec(), ports, shared_memory_regions)) {
Err(_) => Err(MpscError::ChannelClosedError),
Err(_) => Err(MpscError::BrokenPipeError),
Ok(_) => Ok(()),
}
}
Expand Down Expand Up @@ -376,6 +377,7 @@ impl OsIpcSharedMemory {
#[derive(Debug, PartialEq)]
pub enum MpscError {
ChannelClosedError,
BrokenPipeError,
UnknownError,
}

Expand All @@ -396,7 +398,10 @@ impl From<MpscError> for Error {
fn from(mpsc_error: MpscError) -> Error {
match mpsc_error {
MpscError::ChannelClosedError => {
Error::new(ErrorKind::BrokenPipe, "MPSC channel closed")
Error::new(ErrorKind::ConnectionReset, "MPSC channel sender closed")
}
MpscError::BrokenPipeError => {
Error::new(ErrorKind::BrokenPipe, "MPSC channel receiver closed")
}
MpscError::UnknownError => Error::new(ErrorKind::Other, "Other MPSC channel error"),
}
Expand Down
31 changes: 31 additions & 0 deletions src/platform/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,20 @@ fn no_senders_notification() {
assert!(result.unwrap_err().channel_is_closed());
}

/// Checks that a broken pipe notification is returned by `send()`
/// after the receive end was closed.
#[test]
fn no_receiver_notification() {
let (sender, receiver) = platform::channel().unwrap();
drop(receiver);
let data: &[u8] = b"1234567";
let result = sender.send(data, vec![], vec![]);
assert!(result.is_err());
// We don't have an actual method for distinguishing a "broken pipe" error --
// but at least it's not supposed to signal the same condition as closing the sender.
assert!(!result.unwrap_err().channel_is_closed());
}

#[test]
fn shared_memory() {
let (tx, rx) = platform::channel().unwrap();
Expand Down Expand Up @@ -730,6 +744,23 @@ fn try_recv() {
assert!(rx.try_recv().is_err());
}

/// Checks that a channel closed notification is returned by `try_recv()`.
///
/// Also checks that the "no data" notification returned by `try_recv()`
/// when no data is pending but before the channel is closed,
/// is distinguishable from the actual "channel closed" notification.
#[test]
fn no_senders_notification_try_recv() {
let (sender, receiver) = platform::channel().unwrap();
let result = receiver.try_recv();
assert!(result.is_err());
assert!(!result.unwrap_err().channel_is_closed());
drop(sender);
let result = receiver.try_recv();
assert!(result.is_err());
assert!(result.unwrap_err().channel_is_closed());
}

#[test]
fn try_recv_large() {
let (tx, rx) = platform::channel().unwrap();
Expand Down