@@ -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