Skip to content

Commit c3fb5d7

Browse files
author
bors-servo
authored
Auto merge of #176 - antrik:fix-inprocess-error_handling, r=jdm
Fix error handling in `inprocess` back-end Two fixes (along with test cases) for handling of sender/receiver closed conditions.
2 parents d22d044 + e438c8a commit c3fb5d7

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

src/platform/inprocess/mod.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ impl OsIpcReceiver {
100100
Ok(MpscChannelMessage(d,c,s)) => Ok((d,
101101
c.into_iter().map(OsOpaqueIpcChannel::new).collect(),
102102
s)),
103-
Err(_) => Err(MpscError::ChannelClosedError),
103+
Err(mpsc::TryRecvError::Disconnected) => Err(MpscError::ChannelClosedError),
104+
Err(_) => Err(MpscError::UnknownError),
104105
}
105106
}
106107
}
@@ -141,7 +142,7 @@ impl OsIpcSender {
141142
-> Result<(),MpscError>
142143
{
143144
match self.sender.borrow().send(MpscChannelMessage(data.to_vec(), ports, shared_memory_regions)) {
144-
Err(_) => Err(MpscError::ChannelClosedError),
145+
Err(_) => Err(MpscError::BrokenPipeError),
145146
Ok(_) => Ok(()),
146147
}
147148
}
@@ -376,6 +377,7 @@ impl OsIpcSharedMemory {
376377
#[derive(Debug, PartialEq)]
377378
pub enum MpscError {
378379
ChannelClosedError,
380+
BrokenPipeError,
379381
UnknownError,
380382
}
381383

@@ -396,7 +398,10 @@ impl From<MpscError> for Error {
396398
fn from(mpsc_error: MpscError) -> Error {
397399
match mpsc_error {
398400
MpscError::ChannelClosedError => {
399-
Error::new(ErrorKind::BrokenPipe, "MPSC channel closed")
401+
Error::new(ErrorKind::ConnectionReset, "MPSC channel sender closed")
402+
}
403+
MpscError::BrokenPipeError => {
404+
Error::new(ErrorKind::BrokenPipe, "MPSC channel receiver closed")
400405
}
401406
MpscError::UnknownError => Error::new(ErrorKind::Other, "Other MPSC channel error"),
402407
}

src/platform/test.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,20 @@ fn no_senders_notification() {
699699
assert!(result.unwrap_err().channel_is_closed());
700700
}
701701

702+
/// Checks that a broken pipe notification is returned by `send()`
703+
/// after the receive end was closed.
704+
#[test]
705+
fn no_receiver_notification() {
706+
let (sender, receiver) = platform::channel().unwrap();
707+
drop(receiver);
708+
let data: &[u8] = b"1234567";
709+
let result = sender.send(data, vec![], vec![]);
710+
assert!(result.is_err());
711+
// We don't have an actual method for distinguishing a "broken pipe" error --
712+
// but at least it's not supposed to signal the same condition as closing the sender.
713+
assert!(!result.unwrap_err().channel_is_closed());
714+
}
715+
702716
#[test]
703717
fn shared_memory() {
704718
let (tx, rx) = platform::channel().unwrap();
@@ -730,6 +744,23 @@ fn try_recv() {
730744
assert!(rx.try_recv().is_err());
731745
}
732746

747+
/// Checks that a channel closed notification is returned by `try_recv()`.
748+
///
749+
/// Also checks that the "no data" notification returned by `try_recv()`
750+
/// when no data is pending but before the channel is closed,
751+
/// is distinguishable from the actual "channel closed" notification.
752+
#[test]
753+
fn no_senders_notification_try_recv() {
754+
let (sender, receiver) = platform::channel().unwrap();
755+
let result = receiver.try_recv();
756+
assert!(result.is_err());
757+
assert!(!result.unwrap_err().channel_is_closed());
758+
drop(sender);
759+
let result = receiver.try_recv();
760+
assert!(result.is_err());
761+
assert!(result.unwrap_err().channel_is_closed());
762+
}
763+
733764
#[test]
734765
fn try_recv_large() {
735766
let (tx, rx) = platform::channel().unwrap();

0 commit comments

Comments
 (0)