mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-24 00:00:11 +02:00
A more appealing model is actually just automatically inferring what needs to be scheduled based on what actions are done during poll. For example if during a poll you check a oneshot channel, then the current task is registered for being woken up if it's not ready. Similarly this will apply to I/O where if I/O is attempted but we see EAGAIN then we'll schedule the task to get notified when it's ready. This may also have performance benefits in some niche situations because you don't need to recompute where you are in the state machine both during poll and during schedule. Instead, it now happens all at once.
52 lines
1.3 KiB
Rust
52 lines
1.3 KiB
Rust
extern crate env_logger;
|
|
extern crate futures;
|
|
extern crate futures_io;
|
|
extern crate futures_mio;
|
|
|
|
use std::net::TcpStream;
|
|
use std::thread;
|
|
use std::io::{Read, Write};
|
|
|
|
use futures::Future;
|
|
use futures::stream::Stream;
|
|
use futures_io::{copy, TaskIo};
|
|
|
|
macro_rules! t {
|
|
($e:expr) => (match $e {
|
|
Ok(e) => e,
|
|
Err(e) => panic!("{} failed with {:?}", stringify!($e), e),
|
|
})
|
|
}
|
|
|
|
#[test]
|
|
fn echo_server() {
|
|
drop(env_logger::init());
|
|
|
|
let mut l = t!(futures_mio::Loop::new());
|
|
let srv = l.handle().tcp_listen(&"127.0.0.1:0".parse().unwrap());
|
|
let srv = t!(l.run(srv));
|
|
let addr = t!(srv.local_addr());
|
|
|
|
let msg = "foo bar baz";
|
|
let t = thread::spawn(move || {
|
|
let mut s = TcpStream::connect(&addr).unwrap();
|
|
|
|
for _i in 0..1024 {
|
|
assert_eq!(t!(s.write(msg.as_bytes())), msg.len());
|
|
let mut buf = [0; 1024];
|
|
assert_eq!(t!(s.read(&mut buf)), msg.len());
|
|
assert_eq!(&buf[..msg.len()], msg.as_bytes());
|
|
}
|
|
});
|
|
|
|
let clients = srv.incoming();
|
|
let client = clients.into_future().map(|e| e.0.unwrap()).map_err(|e| e.0);
|
|
let halves = client.and_then(|s| TaskIo::new(s.0)).map(|i| i.split());
|
|
let copied = halves.and_then(|(a, b)| copy(a, b));
|
|
|
|
let amt = t!(l.run(copied));
|
|
t.join().unwrap();
|
|
|
|
assert_eq!(amt, msg.len() as u64 * 1024);
|
|
}
|