Skip to content

Commit 211a8c2

Browse files
authored
Merge pull request #60 from yoshuawuyts/pch/input_stream_ready_retry
AsyncInputStream: if input-stream.read returns empty, try again.
2 parents b44737c + 3981ca6 commit 211a8c2

File tree

1 file changed

+17
-13
lines changed

1 file changed

+17
-13
lines changed

src/io/streams.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,23 @@ impl AsyncInputStream {
2828
}
2929
/// Like [`AsyncRead::read`], but doesn't require a `&mut self`.
3030
pub async fn read(&self, buf: &mut [u8]) -> Result<usize> {
31-
self.ready().await;
32-
// Ideally, the ABI would be able to read directly into buf. However, with the default
33-
// generated bindings, it returns a newly allocated vec, which we need to copy into buf.
34-
let read = match self.stream.read(buf.len() as u64) {
35-
// We don't need to special-case 0 here: a value of 0 bytes from
36-
// WASI's `read` doesn't mean end-of-stream as it does in Rust,
37-
// however since we called `self.ready()`, we'll always get at
38-
// least one byte.
39-
Ok(r) => r,
40-
// 0 bytes from Rust's `read` means end-of-stream.
41-
Err(StreamError::Closed) => return Ok(0),
42-
Err(StreamError::LastOperationFailed(err)) => {
43-
return Err(std::io::Error::other(err.to_debug_string()))
31+
let read = loop {
32+
self.ready().await;
33+
// Ideally, the ABI would be able to read directly into buf.
34+
// However, with the default generated bindings, it returns a
35+
// newly allocated vec, which we need to copy into buf.
36+
match self.stream.read(buf.len() as u64) {
37+
// A read of 0 bytes from WASI's `read` doesn't mean
38+
// end-of-stream as it does in Rust. However, `self.ready()`
39+
// cannot guarantee that at least one byte is ready for
40+
// reading, so in this case we try again.
41+
Ok(r) if r.is_empty() => continue,
42+
Ok(r) => break r,
43+
// 0 bytes from Rust's `read` means end-of-stream.
44+
Err(StreamError::Closed) => return Ok(0),
45+
Err(StreamError::LastOperationFailed(err)) => {
46+
return Err(std::io::Error::other(err.to_debug_string()))
47+
}
4448
}
4549
};
4650
let len = read.len();

0 commit comments

Comments
 (0)