Skip to content

Commit 50ca128

Browse files
fix: improve state transitions of Windows named pipes (#1903)
When we've previously failed to read, we may be in a failed state. Inspired by how `schedule_read` handles this case, we simply reset the state to `Err` and notify that we are able to deliver the error.
1 parent d7873b2 commit 50ca128

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

src/sys/windows/named_pipe.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -872,11 +872,24 @@ fn read_done(status: &OVERLAPPED_ENTRY, events: Option<&mut Vec<Event>>) {
872872
// `schedule_read` above.
873873
let me = unsafe { Arc::from_raw(Inner::ptr_from_read_overlapped(status.overlapped())) };
874874

875-
// Move from the `Pending` to `Ok` state.
876875
let mut io = me.io.lock().unwrap();
877876
let mut buf = match mem::replace(&mut io.read, State::None) {
877+
State::Ok(buf, pos) => {
878+
io.read = State::Ok(buf, pos);
879+
880+
// Flag readiness that we have undelivered data to be read.
881+
io.notify_readable(&me, events);
882+
return;
883+
}
878884
State::Pending(buf, _) => buf,
879-
_ => unreachable!(),
885+
State::Err(e) => {
886+
io.read = State::Err(e);
887+
888+
// Flag readiness that the error needs to be delivered.
889+
io.notify_readable(&me, events);
890+
return;
891+
}
892+
State::None => unreachable!(),
880893
};
881894
unsafe {
882895
match me.result(status.overlapped()) {
@@ -909,13 +922,21 @@ fn write_done(status: &OVERLAPPED_ENTRY, events: Option<&mut Vec<Event>>) {
909922
let mut io = me.io.lock().unwrap();
910923
let (buf, pos) = match mem::replace(&mut io.write, State::None) {
911924
// `Ok` here means, that the operation was completed immediately
912-
// `bytes_transferred` is already reported to a client
925+
// `bytes_transferred` is already reported to a client.
926+
// Hence, we don't reset the state to `Ok` but leave it in `None`.
913927
State::Ok(..) => {
914928
io.notify_writable(&me, events);
915929
return;
916930
}
917931
State::Pending(buf, pos) => (buf, pos),
918-
_ => unreachable!(),
932+
State::Err(e) => {
933+
io.write = State::Err(e);
934+
935+
// Flag readiness that the error needs to be delivered.
936+
io.notify_writable(&me, events);
937+
return;
938+
}
939+
State::None => unreachable!(),
919940
};
920941

921942
unsafe {

0 commit comments

Comments
 (0)