Skip to content

Commit a8fc10c

Browse files
authored
wasi/pipe: fix AsyncReadStream returning empty list when closed (#12816)
After the inner stream returns `0` the StreamError::Closed is sent to the channel, and after picking it up in read() the stream is set as closed, and the error is returned to the caller. If the caller however tries to recv() after the socket is closed, AsyncReadStream is going to return empty list and not StreamError::Closed which is ambiguous.
1 parent ab78bd8 commit a8fc10c

1 file changed

Lines changed: 18 additions & 1 deletion

File tree

crates/wasi/src/p2/pipe.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,15 @@ impl InputStream for AsyncReadStream {
239239
self.closed = true;
240240
Err(e)
241241
}
242-
Err(TryRecvError::Empty) => Ok(Bytes::new()),
242+
Err(TryRecvError::Empty) => {
243+
if self.closed {
244+
// Note: if the stream is already closed it should return an error,
245+
// returning empty list would break the wasi contract (returning 0 and ready)
246+
Err(StreamError::Closed)
247+
} else {
248+
Ok(Bytes::new())
249+
}
250+
}
243251
Err(TryRecvError::Disconnected) => Err(StreamError::Trap(format_err!(
244252
"AsyncReadStream sender died - should be impossible"
245253
))),
@@ -382,6 +390,11 @@ mod test {
382390
assert!(bs.is_empty());
383391
resolves_immediately(reader.ready()).await;
384392
assert!(matches!(reader.read(0), Err(StreamError::Closed)));
393+
394+
// Try again to make sure it keeps returning `StreamError::Closed`
395+
resolves_immediately(reader.ready()).await;
396+
assert!(matches!(reader.read(0), Err(StreamError::Closed)));
397+
assert!(matches!(reader.read(0), Err(StreamError::Closed)));
385398
}
386399
res => panic!("unexpected: {res:?}"),
387400
}
@@ -445,6 +458,10 @@ mod test {
445458
}
446459
res => panic!("unexpected: {res:?}"),
447460
}
461+
462+
// Make sure it stays closed
463+
resolves_immediately(reader.ready()).await;
464+
assert!(matches!(reader.read(0), Err(StreamError::Closed)));
448465
}
449466

450467
#[test_log::test(tokio::test(flavor = "multi_thread"))]

0 commit comments

Comments
 (0)