From 347b9ba83ab840100ed9f217f95629cacb90d8cd Mon Sep 17 00:00:00 2001 From: "Aode (lion)" Date: Wed, 16 Feb 2022 11:12:58 -0500 Subject: [PATCH] Change example to use non-blocking io --- examples/async-echo-server.rs | 53 +++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/examples/async-echo-server.rs b/examples/async-echo-server.rs index 2d74b88..3de19b4 100644 --- a/examples/async-echo-server.rs +++ b/examples/async-echo-server.rs @@ -1,5 +1,8 @@ use async_join::join_all; -use foxtrot::Async; +use foxtrot::{ + io::{Nonblocking, ReadBytes, Readiness}, + Async, +}; async fn echo(port: u16) -> Result<(), foxtrot::Error> { let listener = Async::bind([127, 0, 0, 1].into(), port).await?; @@ -9,21 +12,47 @@ async fn echo(port: u16) -> Result<(), foxtrot::Error> { let (stream, _addr) = listener.accept().await?; println!("Accepted connection"); - loop { - let mut buf = [0; 1024]; - if let Err(e) = stream.read(&mut buf).await { - if e == rustix::io::Error::PIPE { - break; - } + let mut bytes = vec![]; + let mut interests = Readiness::read(); + let mut buf = [0; 1024]; - return Err(e.into()); + 'l2: loop { + let readiness = stream.ready(interests).await?; + + if readiness.is_hangup() { + break; } - if let Err(e) = stream.write_all(&buf).await { - if e == rustix::io::Error::PIPE { - break; + + if readiness.is_read() { + loop { + match stream.read_nonblocking(&mut buf)? { + Nonblocking::Ready(ReadBytes::Read(n)) => { + let n: usize = n.into(); + bytes.extend_from_slice(&buf[0..n]); + if n < buf.len() { + break; + } + } + Nonblocking::Ready(ReadBytes::EOF) if bytes.is_empty() => break 'l2, + Nonblocking::Ready(ReadBytes::EOF) | Nonblocking::WouldBlock => break, + } } - return Err(e.into()); + if !bytes.is_empty() { + interests = Readiness::read() | Readiness::write(); + } + } + + if readiness.is_write() { + match stream.write_nonblocking(&bytes)? { + Nonblocking::Ready(n) => { + bytes = bytes.split_off(n); + if bytes.is_empty() { + interests = Readiness::read(); + } + } + Nonblocking::WouldBlock => {} + } } }