chore: apply rustfmt to all crates (#917)

This commit is contained in:
Carl Lerche
2019-02-21 11:56:15 -08:00
committed by GitHub
parent ab595d0825
commit 80162306e7
253 changed files with 3710 additions and 3407 deletions
+2 -1
View File
@@ -25,9 +25,10 @@ matrix:
script: |
cargo check --all
# Test combinations of enabled features.
# Test combinations of enabled features and rustfmt
- rust: stable
script: |
cargo fmt --all -- --check
shopt -s expand_aliases
alias check="cargo check --no-default-features"
check
+1 -3
View File
@@ -10,8 +10,8 @@ use std::io;
use std::net::SocketAddr;
use std::thread;
use futures::sync::oneshot;
use futures::sync::mpsc;
use futures::sync::oneshot;
use futures::{Future, Poll, Sink, Stream};
use test::Bencher;
use tokio::net::UdpSocket;
@@ -57,7 +57,6 @@ fn udp_echo_latency(b: &mut Bencher) {
let (tx, rx) = oneshot::channel();
let child = thread::spawn(move || {
let socket = tokio::net::UdpSocket::bind(&any_addr).unwrap();
tx.send(socket.local_addr().unwrap()).unwrap();
@@ -67,7 +66,6 @@ fn udp_echo_latency(b: &mut Bencher) {
server.wait().unwrap();
});
let client = std::net::UdpSocket::bind(&any_addr).unwrap();
let server_addr = rx.wait().unwrap();
+8 -9
View File
@@ -3,14 +3,13 @@
#![feature(test)]
#![deny(warnings)]
extern crate test;
extern crate mio;
extern crate test;
use test::Bencher;
use mio::tcp::TcpListener;
use mio::{Token, Ready, PollOpt};
use mio::{PollOpt, Ready, Token};
#[bench]
fn mio_register_deregister(b: &mut Bencher) {
@@ -22,8 +21,8 @@ fn mio_register_deregister(b: &mut Bencher) {
const CLIENT: Token = Token(1);
b.iter(|| {
poll.register(&sock, CLIENT, Ready::readable(),
PollOpt::edge()).unwrap();
poll.register(&sock, CLIENT, Ready::readable(), PollOpt::edge())
.unwrap();
poll.deregister(&sock).unwrap();
});
}
@@ -36,12 +35,12 @@ fn mio_reregister(b: &mut Bencher) {
let poll = mio::Poll::new().unwrap();
const CLIENT: Token = Token(1);
poll.register(&sock, CLIENT, Ready::readable(),
PollOpt::edge()).unwrap();
poll.register(&sock, CLIENT, Ready::readable(), PollOpt::edge())
.unwrap();
b.iter(|| {
poll.reregister(&sock, CLIENT, Ready::readable(),
PollOpt::edge()).unwrap();
poll.reregister(&sock, CLIENT, Ready::readable(), PollOpt::edge())
.unwrap();
});
poll.deregister(&sock).unwrap();
}
+62 -49
View File
@@ -11,18 +11,18 @@ pub extern crate test;
mod prelude {
pub use futures::*;
pub use tokio::reactor::Reactor;
pub use tokio::net::{TcpListener, TcpStream};
pub use tokio::reactor::Reactor;
pub use tokio_io::io::read_to_end;
pub use test::{self, Bencher};
pub use std::io::{self, Read, Write};
pub use std::thread;
pub use std::time::Duration;
pub use std::io::{self, Read, Write};
pub use test::{self, Bencher};
}
mod connect_churn {
use ::prelude::*;
use prelude::*;
const NUM: usize = 300;
const CONCURRENT: usize = 8;
@@ -36,25 +36,29 @@ mod connect_churn {
let addr = listener.local_addr().unwrap();
// Spawn a single future that accepts & drops connections
let serve_incomings = listener.incoming()
let serve_incomings = listener
.incoming()
.map_err(|e| panic!("server err: {:?}", e))
.for_each(|_| Ok(()));
let connects = stream::iter_result((0..NUM).map(|_| {
Ok(TcpStream::connect(&addr)
.and_then(|sock| {
sock.set_linger(Some(Duration::from_secs(0))).unwrap();
read_to_end(sock, vec![])
}))
Ok(TcpStream::connect(&addr).and_then(|sock| {
sock.set_linger(Some(Duration::from_secs(0))).unwrap();
read_to_end(sock, vec![])
}))
}));
let connects_concurrent = connects.buffer_unordered(CONCURRENT)
let connects_concurrent = connects
.buffer_unordered(CONCURRENT)
.map_err(|e| panic!("client err: {:?}", e))
.for_each(|_| Ok(()));
serve_incomings.select(connects_concurrent)
.map(|_| ()).map_err(|_| ())
.wait().unwrap();
serve_incomings
.select(connects_concurrent)
.map(|_| ())
.map_err(|_| ())
.wait()
.unwrap();
});
}
@@ -65,8 +69,7 @@ mod connect_churn {
// Spawn reactor thread
let server_thread = thread::spawn(move || {
// Bind the TCP listener
let listener = TcpListener::bind(
&"127.0.0.1:0".parse().unwrap()).unwrap();
let listener = TcpListener::bind(&"127.0.0.1:0".parse().unwrap()).unwrap();
// Get the address being listened on.
let addr = listener.local_addr().unwrap();
@@ -75,47 +78,56 @@ mod connect_churn {
addr_tx.send(addr).unwrap();
// Spawn a single future that accepts & drops connections
let serve_incomings = listener.incoming()
let serve_incomings = listener
.incoming()
.map_err(|e| panic!("server err: {:?}", e))
.for_each(|_| Ok(()));
// Run server
serve_incomings.select(shutdown_rx)
.map(|_| ()).map_err(|_| ())
.wait().unwrap();
serve_incomings
.select(shutdown_rx)
.map(|_| ())
.map_err(|_| ())
.wait()
.unwrap();
});
// Get the bind addr of the server
let addr = addr_rx.wait().unwrap();
b.iter(move || {
use std::sync::{Barrier, Arc};
use std::sync::{Arc, Barrier};
// Create a barrier to coordinate threads
let barrier = Arc::new(Barrier::new(n + 1));
// Spawn worker threads
let threads: Vec<_> = (0..n).map(|_| {
let barrier = barrier.clone();
let addr = addr.clone();
let threads: Vec<_> = (0..n)
.map(|_| {
let barrier = barrier.clone();
let addr = addr.clone();
thread::spawn(move || {
let connects = stream::iter_result((0..(NUM / n)).map(|_| {
Ok(TcpStream::connect(&addr)
.map_err(|e| panic!("connect err: {:?}", e))
.and_then(|sock| {
sock.set_linger(Some(Duration::from_secs(0))).unwrap();
read_to_end(sock, vec![])
}))
}));
thread::spawn(move || {
let connects = stream::iter_result((0..(NUM / n)).map(|_| {
Ok(TcpStream::connect(&addr)
.map_err(|e| panic!("connect err: {:?}", e))
.and_then(|sock| {
sock.set_linger(Some(Duration::from_secs(0))).unwrap();
read_to_end(sock, vec![])
}))
}));
barrier.wait();
barrier.wait();
connects.buffer_unordered(CONCURRENT)
.map_err(|e| panic!("client err: {:?}", e))
.for_each(|_| Ok(())).wait().unwrap();
connects
.buffer_unordered(CONCURRENT)
.map_err(|e| panic!("client err: {:?}", e))
.for_each(|_| Ok(()))
.wait()
.unwrap();
})
})
}).collect();
.collect();
barrier.wait();
@@ -141,7 +153,7 @@ mod connect_churn {
}
mod transfer {
use ::prelude::*;
use prelude::*;
use std::{cmp, mem};
const MB: usize = 3 * 1024 * 1024;
@@ -200,7 +212,8 @@ mod transfer {
let addr = listener.local_addr().unwrap();
// Spawn a single future that accepts 1 connection, Drain it and drops
let server = listener.incoming()
let server = listener
.incoming()
.into_future() // take the first connection
.map_err(|(e, _other_incomings)| e)
.map(|(connection, _other_incomings)| connection.unwrap())
@@ -210,17 +223,17 @@ mod transfer {
sock: sock,
chunk: read_size,
};
drain.map(|_| ()).map_err(|e| panic!("server error: {:?}", e))
drain
.map(|_| ())
.map_err(|e| panic!("server error: {:?}", e))
})
.map_err(|e| panic!("server err: {:?}", e));
let client = TcpStream::connect(&addr)
.and_then(move |sock| {
Transfer {
sock: sock,
rem: MB,
chunk: write_size,
}
.and_then(move |sock| Transfer {
sock: sock,
rem: MB,
chunk: write_size,
})
.map_err(|e| panic!("client err: {:?}", e));
@@ -229,7 +242,7 @@ mod transfer {
}
mod small_chunks {
use ::prelude::*;
use prelude::*;
#[bench]
fn one_thread(b: &mut Bencher) {
@@ -238,7 +251,7 @@ mod transfer {
}
mod big_chunks {
use ::prelude::*;
use prelude::*;
#[bench]
fn one_thread(b: &mut Bencher) {
+27 -22
View File
@@ -26,21 +26,20 @@
#![deny(warnings)]
extern crate tokio;
extern crate futures;
extern crate tokio;
use tokio::io;
use tokio::net::TcpListener;
use tokio::prelude::*;
use tokio::runtime::current_thread::{Runtime, TaskExecutor};
use std::collections::HashMap;
use std::iter;
use std::env;
use std::io::{BufReader};
use std::rc::Rc;
use std::cell::RefCell;
use std::collections::HashMap;
use std::env;
use std::io::BufReader;
use std::iter;
use std::rc::Rc;
fn main() -> Result<(), Box<std::error::Error>> {
let mut runtime = Runtime::new().unwrap();
@@ -58,8 +57,12 @@ fn main() -> Result<(), Box<std::error::Error>> {
// The server task asynchronously iterates over and processes each incoming
// connection.
let srv = socket.incoming()
.map_err(|e| {println!("failed to accept socket; error = {:?}", e); e})
let srv = socket
.incoming()
.map_err(|e| {
println!("failed to accept socket; error = {:?}", e);
e
})
.for_each(move |stream| {
// The client's socket address
let addr = stream.peer_addr()?;
@@ -102,9 +105,7 @@ fn main() -> Result<(), Box<std::error::Error>> {
// Convert the bytes we read into a string, and then send that
// string to all other connected clients.
let line = line.map(|(reader, vec)| {
(reader, String::from_utf8(vec))
});
let line = line.map(|(reader, vec)| (reader, String::from_utf8(vec)));
// Move the connection state into the closure below.
let connections = connections_inner.clone();
@@ -116,15 +117,17 @@ fn main() -> Result<(), Box<std::error::Error>> {
if let Ok(msg) = message {
// For each open connection except the sender, send the
// string via the channel.
let iter = conns.iter_mut()
.filter(|&(&k, _)| k != addr)
.map(|(_, v)| v);
let iter = conns
.iter_mut()
.filter(|&(&k, _)| k != addr)
.map(|(_, v)| v);
for tx in iter {
tx.unbounded_send(format!("{}: {}", addr, msg)).unwrap();
}
} else {
let tx = conns.get_mut(&addr).unwrap();
tx.unbounded_send("You didn't send valid UTF-8.".to_string()).unwrap();
tx.unbounded_send("You didn't send valid UTF-8.".to_string())
.unwrap();
}
reader
@@ -147,12 +150,14 @@ fn main() -> Result<(), Box<std::error::Error>> {
let connection = socket_reader.map(|_| ()).select(socket_writer.map(|_| ()));
// Spawn locally a task to process the connection
TaskExecutor::current().spawn_local(Box::new(connection.then(move |_| {
let mut conns = connections.borrow_mut();
conns.remove(&addr);
println!("Connection {} closed.", addr);
Ok(())
}))).unwrap();
TaskExecutor::current()
.spawn_local(Box::new(connection.then(move |_| {
let mut conns = connections.borrow_mut();
conns.remove(&addr);
println!("Connection {} closed.", addr);
Ok(())
})))
.unwrap();
Ok(())
})
+16 -12
View File
@@ -21,17 +21,17 @@
#![deny(warnings)]
extern crate tokio;
extern crate futures;
extern crate tokio;
use tokio::io;
use tokio::net::TcpListener;
use tokio::prelude::*;
use std::collections::HashMap;
use std::iter;
use std::env;
use std::io::{BufReader};
use std::io::BufReader;
use std::iter;
use std::sync::{Arc, Mutex};
fn main() -> Result<(), Box<std::error::Error>> {
@@ -48,8 +48,12 @@ fn main() -> Result<(), Box<std::error::Error>> {
// The server task asynchronously iterates over and processes each incoming
// connection.
let srv = socket.incoming()
.map_err(|e| {println!("failed to accept socket; error = {:?}", e); e})
let srv = socket
.incoming()
.map_err(|e| {
println!("failed to accept socket; error = {:?}", e);
e
})
.for_each(move |stream| {
// The client's socket address
let addr = stream.peer_addr()?;
@@ -91,9 +95,7 @@ fn main() -> Result<(), Box<std::error::Error>> {
// Convert the bytes we read into a string, and then send that
// string to all other connected clients.
let line = line.map(|(reader, vec)| {
(reader, String::from_utf8(vec))
});
let line = line.map(|(reader, vec)| (reader, String::from_utf8(vec)));
// Move the connection state into the closure below.
let connections = connections_inner.clone();
@@ -105,15 +107,17 @@ fn main() -> Result<(), Box<std::error::Error>> {
if let Ok(msg) = message {
// For each open connection except the sender, send the
// string via the channel.
let iter = conns.iter_mut()
.filter(|&(&k, _)| k != addr)
.map(|(_, v)| v);
let iter = conns
.iter_mut()
.filter(|&(&k, _)| k != addr)
.map(|(_, v)| v);
for tx in iter {
tx.unbounded_send(format!("{}: {}", addr, msg)).unwrap();
}
} else {
let tx = conns.get_mut(&addr).unwrap();
tx.unbounded_send("You didn't send valid UTF-8.".to_string()).unwrap();
tx.unbounded_send("You didn't send valid UTF-8.".to_string())
.unwrap();
}
reader
+28 -30
View File
@@ -31,12 +31,12 @@ extern crate tokio;
extern crate futures;
extern crate bytes;
use bytes::{BufMut, Bytes, BytesMut};
use futures::future::{self, Either};
use futures::sync::mpsc;
use tokio::io;
use tokio::net::{TcpListener, TcpStream};
use tokio::prelude::*;
use futures::sync::mpsc;
use futures::future::{self, Either};
use bytes::{BytesMut, Bytes, BufMut};
use std::collections::HashMap;
use std::net::SocketAddr;
@@ -131,10 +131,7 @@ impl Shared {
impl Peer {
/// Create a new instance of `Peer`.
fn new(name: BytesMut,
state: Arc<Mutex<Shared>>,
lines: Lines) -> Peer
{
fn new(name: BytesMut, state: Arc<Mutex<Shared>>, lines: Lines) -> Peer {
// Get the client socket address
let addr = lines.socket.peer_addr().unwrap();
@@ -142,8 +139,7 @@ impl Peer {
let (tx, rx) = mpsc::unbounded();
// Add an entry for this `Peer` in the shared state map.
state.lock().unwrap()
.peers.insert(addr, tx);
state.lock().unwrap().peers.insert(addr, tx);
Peer {
name,
@@ -198,7 +194,7 @@ impl Future for Peer {
// though there could still be lines to read. Because we did
// not reach `Async::NotReady`, we have to notify ourselves
// in order to tell the executor to schedule the task again.
if i+1 == LINES_PER_TICK {
if i + 1 == LINES_PER_TICK {
task::current().notify();
}
}
@@ -256,8 +252,7 @@ impl Future for Peer {
impl Drop for Peer {
fn drop(&mut self) {
self.state.lock().unwrap().peers
.remove(&self.addr);
self.state.lock().unwrap().peers.remove(&self.addr);
}
}
@@ -333,7 +328,10 @@ impl Stream for Lines {
let sock_closed = self.fill_read_buf()?.is_ready();
// Now, try finding lines
let pos = self.rd.windows(2).enumerate()
let pos = self
.rd
.windows(2)
.enumerate()
.find(|&(_, bytes)| bytes == b"\r\n")
.map(|(i, _)| i);
@@ -373,7 +371,8 @@ fn process(socket: TcpStream, state: Arc<Mutex<Shared>>) {
// We use the `into_future` combinator to extract the first item from the
// lines stream. `into_future` takes a `Stream` and converts it to a future
// of `(first, rest)` where `rest` is the original stream instance.
let connection = lines.into_future()
let connection = lines
.into_future()
// `into_future` doesn't have the right error type, so map the error to
// make it work.
.map_err(|(e, _)| e)
@@ -408,10 +407,7 @@ fn process(socket: TcpStream, state: Arc<Mutex<Shared>>) {
//
// This is also a future that processes the connection, only
// completing when the socket closes.
let peer = Peer::new(
name,
state,
lines);
let peer = Peer::new(name, state, lines);
// Wrap `peer` with `Either::B` to make the return type fit.
Either::B(peer)
@@ -443,18 +439,20 @@ pub fn main() -> Result<(), Box<std::error::Error>> {
// The server task asynchronously iterates over and processes each
// incoming connection.
let server = listener.incoming().for_each(move |socket| {
// Spawn a task to process the connection
process(socket, state.clone());
Ok(())
})
.map_err(|err| {
// All tasks must have an `Error` type of `()`. This forces error
// handling and helps avoid silencing failures.
//
// In our example, we are only going to log the error to STDOUT.
println!("accept error = {:?}", err);
});
let server = listener
.incoming()
.for_each(move |socket| {
// Spawn a task to process the connection
process(socket, state.clone());
Ok(())
})
.map_err(|err| {
// All tasks must have an `Error` type of `()`. This forces error
// handling and helps avoid silencing failures.
//
// In our example, we are only going to log the error to STDOUT.
println!("accept error = {:?}", err);
});
println!("server running on localhost:6142");
+48 -44
View File
@@ -16,18 +16,18 @@
#![deny(warnings)]
extern crate bytes;
extern crate futures;
extern crate tokio;
extern crate tokio_io;
extern crate futures;
extern crate bytes;
use std::env;
use std::io::{self, Read, Write};
use std::net::SocketAddr;
use std::thread;
use tokio::prelude::*;
use futures::sync::mpsc;
use tokio::prelude::*;
fn main() -> Result<(), Box<std::error::Error>> {
// Determine if we're going to run in TCP or UDP mode
@@ -73,18 +73,16 @@ fn main() -> Result<(), Box<std::error::Error>> {
tokio::run({
stdout
.for_each(move |chunk| {
out.write_all(&chunk)
})
.for_each(move |chunk| out.write_all(&chunk))
.map_err(|e| println!("error reading stdout; error = {:?}", e))
});
Ok(())
}
mod codec {
use std::io;
use bytes::{BufMut, BytesMut};
use tokio::codec::{Encoder, Decoder};
use std::io;
use tokio::codec::{Decoder, Encoder};
/// A simple `Codec` implementation that just ships bytes around.
///
@@ -122,9 +120,9 @@ mod codec {
mod tcp {
use tokio;
use tokio::codec::Decoder;
use tokio::net::TcpStream;
use tokio::prelude::*;
use tokio::codec::Decoder;
use bytes::BytesMut;
use codec::Bytes;
@@ -133,10 +131,10 @@ mod tcp {
use std::io;
use std::net::SocketAddr;
pub fn connect(addr: &SocketAddr,
stdin: Box<Stream<Item = Vec<u8>, Error = io::Error> + Send>)
-> Result<Box<Stream<Item = BytesMut, Error = io::Error> + Send>, Box<Error>>
{
pub fn connect(
addr: &SocketAddr,
stdin: Box<Stream<Item = Vec<u8>, Error = io::Error> + Send>,
) -> Result<Box<Stream<Item = BytesMut, Error = io::Error> + Send>, Box<Error>> {
let tcp = TcpStream::connect(addr);
// After the TCP connection has been established, we set up our client
@@ -154,18 +152,21 @@ mod tcp {
// You'll also note that we *spawn* the work to read stdin and write it
// to the TCP stream. This is done to ensure that happens concurrently
// with us reading data from the stream.
let stream = Box::new(tcp.map(move |stream| {
let (sink, stream) = Bytes.framed(stream).split();
let stream = Box::new(
tcp.map(move |stream| {
let (sink, stream) = Bytes.framed(stream).split();
tokio::spawn(stdin.forward(sink).then(|result| {
if let Err(e) = result {
println!("failed to write to socket: {}", e)
}
Ok(())
}));
tokio::spawn(stdin.forward(sink).then(|result| {
if let Err(e) = result {
println!("failed to write to socket: {}", e)
}
Ok(())
}));
stream
}).flatten_stream());
stream
})
.flatten_stream(),
);
Ok(stream)
}
}
@@ -175,17 +176,17 @@ mod udp {
use std::io;
use std::net::SocketAddr;
use tokio;
use tokio::net::{UdpSocket, UdpFramed};
use tokio::prelude::*;
use bytes::BytesMut;
use tokio;
use tokio::net::{UdpFramed, UdpSocket};
use tokio::prelude::*;
use codec::Bytes;
pub fn connect(&addr: &SocketAddr,
stdin: Box<Stream<Item = Vec<u8>, Error = io::Error> + Send>)
-> Result<Box<Stream<Item = BytesMut, Error = io::Error> + Send>, Box<Error>>
{
pub fn connect(
&addr: &SocketAddr,
stdin: Box<Stream<Item = Vec<u8>, Error = io::Error> + Send>,
) -> Result<Box<Stream<Item = BytesMut, Error = io::Error> + Send>, Box<Error>> {
// We'll bind our UDP socket to a local IP/port, but for now we
// basically let the OS pick both of those.
let addr_to_bind = if addr.ip().is_ipv4() {
@@ -206,14 +207,15 @@ mod udp {
// All bytes from `stdin` will go to the `addr` specified in our
// argument list. Like with TCP this is spawned concurrently
let forward_stdin = stdin.map(move |chunk| {
(chunk, addr)
}).forward(sink).then(|result| {
if let Err(e) = result {
println!("failed to write to socket: {}", e)
}
Ok(())
});
let forward_stdin = stdin
.map(move |chunk| (chunk, addr))
.forward(sink)
.then(|result| {
if let Err(e) = result {
println!("failed to write to socket: {}", e)
}
Ok(())
});
// With UDP we could receive data from any source, so filter out
// anything coming from a different address
@@ -225,10 +227,13 @@ mod udp {
}
});
let stream = Box::new(future::lazy(|| {
tokio::spawn(forward_stdin);
future::ok(receive)
}).flatten_stream());
let stream = Box::new(
future::lazy(|| {
tokio::spawn(forward_stdin);
future::ok(receive)
})
.flatten_stream(),
);
Ok(stream)
}
}
@@ -240,8 +245,7 @@ fn read_stdin(mut tx: mpsc::Sender<Vec<u8>>) {
loop {
let mut buf = vec![0; 1024];
let n = match stdin.read(&mut buf) {
Err(_) |
Ok(0) => break,
Err(_) | Ok(0) => break,
Ok(n) => n,
};
buf.truncate(n);
+2 -2
View File
@@ -16,11 +16,11 @@
extern crate futures;
extern crate tokio;
use std::{env, io};
use std::net::SocketAddr;
use std::{env, io};
use tokio::prelude::*;
use tokio::net::UdpSocket;
use tokio::prelude::*;
struct Server {
socket: UdpSocket,
+2 -2
View File
@@ -54,7 +54,8 @@ fn main() -> Result<(), Box<std::error::Error>> {
// connections made to the server). The return value of the `for_each`
// method is itself a future representing processing the entire stream of
// connections, and ends up being our server.
let done = socket.incoming()
let done = socket
.incoming()
.map_err(|e| println!("failed to accept socket; error = {:?}", e))
.for_each(move |socket| {
// Once we're inside this closure this represents an accepted client
@@ -89,7 +90,6 @@ fn main() -> Result<(), Box<std::error::Error>> {
Ok(())
});
// And this is where much of the magic of this server happens. We
// crucially want all clients to make progress concurrently, rather than
// blocking one on completion of another. To achieve this we use the
+14 -13
View File
@@ -25,20 +25,21 @@ pub fn main() -> Result<(), Box<std::error::Error>> {
// Open a TCP stream to the socket address.
//
// Note that this is the Tokio TcpStream, which is fully async.
let client = TcpStream::connect(&addr).and_then(|stream| {
println!("created stream");
io::write_all(stream, "hello world\n").then(|result| {
println!("wrote to stream; success={:?}", result.is_ok());
Ok(())
let client = TcpStream::connect(&addr)
.and_then(|stream| {
println!("created stream");
io::write_all(stream, "hello world\n").then(|result| {
println!("wrote to stream; success={:?}", result.is_ok());
Ok(())
})
})
})
.map_err(|err| {
// All tasks must have an `Error` type of `()`. This forces error
// handling and helps avoid silencing failures.
//
// In our example, we are only going to log the error to STDOUT.
println!("connection error = {:?}", err);
});
.map_err(|err| {
// All tasks must have an `Error` type of `()`. This forces error
// handling and helps avoid silencing failures.
//
// In our example, we are only going to log the error to STDOUT.
println!("connection error = {:?}", err);
});
// Start the Tokio runtime.
//
+2 -2
View File
@@ -57,10 +57,10 @@
extern crate tokio;
extern crate tokio_codec;
use tokio_codec::BytesCodec;
use tokio::codec::Decoder;
use tokio::net::TcpListener;
use tokio::prelude::*;
use tokio::codec::Decoder;
use tokio_codec::BytesCodec;
use std::env;
use std::net::SocketAddr;
+17 -16
View File
@@ -24,10 +24,10 @@
extern crate tokio;
use std::sync::{Arc, Mutex};
use std::env;
use std::net::{Shutdown, SocketAddr};
use std::io::{self, Read, Write};
use std::net::{Shutdown, SocketAddr};
use std::sync::{Arc, Mutex};
use tokio::io::{copy, shutdown};
use tokio::net::{TcpListener, TcpStream};
@@ -45,7 +45,8 @@ fn main() -> Result<(), Box<std::error::Error>> {
println!("Listening on: {}", listen_addr);
println!("Proxying to: {}", server_addr);
let done = socket.incoming()
let done = socket
.incoming()
.map_err(|e| println!("error accepting socket; error = {:?}", e))
.for_each(move |client| {
let server = TcpStream::connect(&server_addr);
@@ -68,25 +69,25 @@ fn main() -> Result<(), Box<std::error::Error>> {
// After the copy is done we indicate to the remote side that we've
// finished by shutting down the connection.
let client_to_server = copy(client_reader, server_writer)
.and_then(|(n, _, server_writer)| {
shutdown(server_writer).map(move |_| n)
});
.and_then(|(n, _, server_writer)| shutdown(server_writer).map(move |_| n));
let server_to_client = copy(server_reader, client_writer)
.and_then(|(n, _, client_writer)| {
shutdown(client_writer).map(move |_| n)
});
.and_then(|(n, _, client_writer)| shutdown(client_writer).map(move |_| n));
client_to_server.join(server_to_client)
});
let msg = amounts.map(move |(from_client, from_server)| {
println!("client wrote {} bytes and received {} bytes",
from_client, from_server);
}).map_err(|e| {
// Don't panic. Maybe the client just disconnected too soon.
println!("error: {}", e);
});
let msg = amounts
.map(move |(from_client, from_server)| {
println!(
"client wrote {} bytes and received {} bytes",
from_client, from_server
);
})
.map_err(|e| {
// Don't panic. Maybe the client just disconnected too soon.
println!("error: {}", e);
});
tokio::spawn(msg);
+44 -24
View File
@@ -44,8 +44,8 @@
extern crate tokio;
use std::collections::HashMap;
use std::io::BufReader;
use std::env;
use std::io::BufReader;
use std::net::SocketAddr;
use std::sync::{Arc, Mutex};
@@ -69,9 +69,18 @@ enum Request {
/// Responses to the `Request` commands above
enum Response {
Value { key: String, value: String },
Set { key: String, value: String, previous: Option<String> },
Error { msg: String },
Value {
key: String,
value: String,
},
Set {
key: String,
value: String,
previous: Option<String>,
},
Error {
msg: String,
},
}
fn main() -> Result<(), Box<std::error::Error>> {
@@ -93,7 +102,8 @@ fn main() -> Result<(), Box<std::error::Error>> {
map: Mutex::new(initial_db),
});
let done = listener.incoming()
let done = listener
.incoming()
.map_err(|e| println!("error accepting socket; error = {:?}", e))
.for_each(move |socket| {
// As with many other small examples, the first thing we'll do is
@@ -124,15 +134,22 @@ fn main() -> Result<(), Box<std::error::Error>> {
let mut db = db.map.lock().unwrap();
match request {
Request::Get { key } => {
match db.get(&key) {
Some(value) => Response::Value { key, value: value.clone() },
None => Response::Error { msg: format!("no key {}", key) },
}
}
Request::Get { key } => match db.get(&key) {
Some(value) => Response::Value {
key,
value: value.clone(),
},
None => Response::Error {
msg: format!("no key {}", key),
},
},
Request::Set { key, value } => {
let previous = db.insert(key.clone(), value.clone());
Response::Set { key, value, previous }
Response::Set {
key,
value,
previous,
}
}
}
});
@@ -169,9 +186,11 @@ impl Request {
None => return Err(format!("GET must be followed by a key")),
};
if parts.next().is_some() {
return Err(format!("GET's key must not be followed by anything"))
return Err(format!("GET's key must not be followed by anything"));
}
Ok(Request::Get { key: key.to_string() })
Ok(Request::Get {
key: key.to_string(),
})
}
Some("SET") => {
let key = match parts.next() {
@@ -182,7 +201,10 @@ impl Request {
Some(value) => value,
None => return Err(format!("SET needs a value")),
};
Ok(Request::Set { key: key.to_string(), value: value.to_string() })
Ok(Request::Set {
key: key.to_string(),
value: value.to_string(),
})
}
Some(cmd) => Err(format!("unknown command: {}", cmd)),
None => Err(format!("empty input")),
@@ -193,15 +215,13 @@ impl Request {
impl Response {
fn serialize(&self) -> String {
match *self {
Response::Value { ref key, ref value } => {
format!("{} = {}", key, value)
}
Response::Set { ref key, ref value, ref previous } => {
format!("set {} = `{}`, previous: {:?}", key, value, previous)
}
Response::Error { ref msg } => {
format!("error: {}", msg)
}
Response::Value { ref key, ref value } => format!("{} = {}", key, value),
Response::Set {
ref key,
ref value,
ref previous,
} => format!("set {} = `{}`, previous: {:?}", key, value, previous),
Response::Error { ref msg } => format!("error: {}", msg),
}
}
}
+45 -33
View File
@@ -23,12 +23,12 @@ extern crate time;
extern crate tokio;
extern crate tokio_io;
use std::{env, fmt, io};
use std::net::SocketAddr;
use std::{env, fmt, io};
use tokio::net::{TcpStream, TcpListener};
use tokio::codec::{Decoder, Encoder};
use tokio::net::{TcpListener, TcpStream};
use tokio::prelude::*;
use tokio::codec::{Encoder, Decoder};
use bytes::BytesMut;
use http::header::HeaderValue;
@@ -44,7 +44,8 @@ fn main() -> Result<(), Box<std::error::Error>> {
println!("Listening on: {}", addr);
tokio::run({
listener.incoming()
listener
.incoming()
.map_err(|e| println!("failed to accept socket; error = {:?}", e))
.for_each(|socket| {
process(socket);
@@ -64,14 +65,13 @@ fn process(socket: TcpStream) {
.split();
// Map all requests into responses and send them back to the client.
let task = tx.send_all(rx.and_then(respond))
.then(|res| {
if let Err(e) = res {
println!("failed to process connection; error = {:?}", e);
}
let task = tx.send_all(rx.and_then(respond)).then(|res| {
if let Err(e) = res {
println!("failed to process connection; error = {:?}", e);
}
Ok(())
});
Ok(())
});
// Spawn the task that handles the connection.
tokio::spawn(task);
@@ -82,9 +82,7 @@ fn process(socket: TcpStream) {
/// This function is a map from and HTTP request to a future of a response and
/// represents the various handling a server might do. Currently the contents
/// here are pretty uninteresting.
fn respond(req: Request<()>)
-> Box<Future<Item = Response<String>, Error = io::Error> + Send>
{
fn respond(req: Request<()>) -> Box<Future<Item = Response<String>, Error = io::Error> + Send> {
let f = future::lazy(move || {
let mut response = Response::builder();
let body = match req.uri().path() {
@@ -99,14 +97,18 @@ fn respond(req: Request<()>)
struct Message {
message: &'static str,
}
serde_json::to_string(&Message { message: "Hello, World!" })?
serde_json::to_string(&Message {
message: "Hello, World!",
})?
}
_ => {
response.status(StatusCode::NOT_FOUND);
String::new()
}
};
let response = response.body(body).map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
let response = response
.body(body)
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
Ok(response)
});
@@ -124,12 +126,19 @@ impl Encoder for Http {
fn encode(&mut self, item: Response<String>, dst: &mut BytesMut) -> io::Result<()> {
use std::fmt::Write;
write!(BytesWrite(dst), "\
HTTP/1.1 {}\r\n\
Server: Example\r\n\
Content-Length: {}\r\n\
Date: {}\r\n\
", item.status(), item.body().len(), date::now()).unwrap();
write!(
BytesWrite(dst),
"\
HTTP/1.1 {}\r\n\
Server: Example\r\n\
Content-Length: {}\r\n\
Date: {}\r\n\
",
item.status(),
item.body().len(),
date::now()
)
.unwrap();
for (k, v) in item.headers() {
dst.extend_from_slice(k.as_str().as_bytes());
@@ -198,13 +207,18 @@ impl Decoder for Http {
headers[i] = Some((k, v));
}
(toslice(r.method.unwrap().as_bytes()),
toslice(r.path.unwrap().as_bytes()),
r.version.unwrap(),
amt)
(
toslice(r.method.unwrap().as_bytes()),
toslice(r.path.unwrap().as_bytes()),
r.version.unwrap(),
amt,
)
};
if version != 1 {
return Err(io::Error::new(io::ErrorKind::Other, "only HTTP/1.1 accepted"))
return Err(io::Error::new(
io::ErrorKind::Other,
"only HTTP/1.1 accepted",
));
}
let data = src.split_to(amt).freeze();
let mut ret = Request::builder();
@@ -216,15 +230,13 @@ impl Decoder for Http {
Some((ref k, ref v)) => (k, v),
None => break,
};
let value = unsafe {
HeaderValue::from_shared_unchecked(data.slice(v.0, v.1))
};
let value = unsafe { HeaderValue::from_shared_unchecked(data.slice(v.0, v.1)) };
ret.header(&data[k.0..k.1], value);
}
let req = ret.body(()).map_err(|e| {
io::Error::new(io::ErrorKind::Other, e)
})?;
let req = ret
.body(())
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
Ok(Some(req))
}
}
+2 -1
View File
@@ -51,7 +51,8 @@ fn main() -> Result<(), Box<std::error::Error>> {
"0.0.0.0:0"
} else {
"[::]:0"
}.parse()?;
}
.parse()?;
let socket = UdpSocket::bind(&local_addr)?;
const MAX_DATAGRAM_SIZE: usize = 65_507;
socket
+2 -2
View File
@@ -8,15 +8,15 @@
#![deny(warnings)]
extern crate env_logger;
extern crate tokio;
extern crate tokio_codec;
extern crate tokio_io;
extern crate env_logger;
use std::net::SocketAddr;
use tokio::net::{UdpFramed, UdpSocket};
use tokio::prelude::*;
use tokio::net::{UdpSocket, UdpFramed};
use tokio_codec::BytesCodec;
fn main() -> Result<(), Box<std::error::Error>> {
+5 -3
View File
@@ -1,4 +1,4 @@
use std::future::{Future as StdFuture};
use std::future::Future as StdFuture;
async fn map_ok<T: StdFuture>(future: T) -> Result<(), ()> {
let _ = await!(future);
@@ -7,7 +7,8 @@ async fn map_ok<T: StdFuture>(future: T) -> Result<(), ()> {
/// Like `tokio::run`, but takes an `async` block
pub fn run_async<F>(future: F)
where F: StdFuture<Output = ()> + Send + 'static,
where
F: StdFuture<Output = ()> + Send + 'static,
{
use tokio_async_await::compat::backward;
let future = backward::Compat::new(map_ok(future));
@@ -17,7 +18,8 @@ where F: StdFuture<Output = ()> + Send + 'static,
/// Like `tokio::spawn`, but takes an `async` block
pub fn spawn_async<F>(future: F)
where F: StdFuture<Output = ()> + Send + 'static,
where
F: StdFuture<Output = ()> + Send + 'static,
{
use tokio_async_await::compat::backward;
let future = backward::Compat::new(map_ok(future));
+38 -33
View File
@@ -355,19 +355,15 @@
//! [`BytesMut`]: https://docs.rs/bytes/0.4/bytes/struct.BytesMut.html
use {
codec::{
Decoder, Encoder, FramedRead, FramedWrite, Framed
},
io::{
AsyncRead, AsyncWrite
},
codec::{Decoder, Encoder, Framed, FramedRead, FramedWrite},
io::{AsyncRead, AsyncWrite},
};
use bytes::{Buf, BufMut, Bytes, BytesMut, IntoBuf};
use std::{cmp, fmt};
use std::error::Error as StdError;
use std::io::{self, Cursor};
use std::{cmp, fmt};
/// Configure length delimited `LengthDelimitedCodec`s.
///
@@ -476,9 +472,10 @@ impl LengthDelimitedCodec {
};
if n > self.builder.max_frame_len as u64 {
return Err(io::Error::new(io::ErrorKind::InvalidData, FrameTooBig {
_priv: (),
}));
return Err(io::Error::new(
io::ErrorKind::InvalidData,
FrameTooBig { _priv: () },
));
}
// The check above ensures there is no overflow
@@ -494,7 +491,12 @@ impl LengthDelimitedCodec {
// Error handling
match n {
Some(n) => n,
None => return Err(io::Error::new(io::ErrorKind::InvalidInput, "provided length would overflow after adjustment")),
None => {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"provided length would overflow after adjustment",
));
}
}
};
@@ -528,15 +530,13 @@ impl Decoder for LengthDelimitedCodec {
fn decode(&mut self, src: &mut BytesMut) -> io::Result<Option<BytesMut>> {
let n = match self.state {
DecodeState::Head => {
match try!(self.decode_head(src)) {
Some(n) => {
self.state = DecodeState::Data(n);
n
}
None => return Ok(None),
DecodeState::Head => match try!(self.decode_head(src)) {
Some(n) => {
self.state = DecodeState::Data(n);
n
}
}
None => return Ok(None),
},
DecodeState::Data(n) => n,
};
@@ -563,9 +563,10 @@ impl Encoder for LengthDelimitedCodec {
let n = (&data).into_buf().remaining();
if n > self.builder.max_frame_len {
return Err(io::Error::new(io::ErrorKind::InvalidInput, FrameTooBig {
_priv: (),
}));
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
FrameTooBig { _priv: () },
));
}
// Adjust `n` with bounds checking
@@ -575,10 +576,12 @@ impl Encoder for LengthDelimitedCodec {
n.checked_sub(self.builder.length_adjustment as usize)
};
let n = n.ok_or_else(|| io::Error::new(
io::ErrorKind::InvalidInput,
"provided length would overflow after adjustment",
))?;
let n = n.ok_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"provided length would overflow after adjustment",
)
})?;
// Reserve capacity in the destination buffer to fit the frame and
// length field (plus adjustment).
@@ -892,7 +895,8 @@ impl Builder {
/// # pub fn main() {}
/// ```
pub fn new_read<T>(&self, upstream: T) -> FramedRead<T, LengthDelimitedCodec>
where T: AsyncRead,
where
T: AsyncRead,
{
FramedRead::new(upstream, self.new_codec())
}
@@ -915,7 +919,8 @@ impl Builder {
/// # pub fn main() {}
/// ```
pub fn new_write<T>(&self, inner: T) -> FramedWrite<T, LengthDelimitedCodec>
where T: AsyncWrite,
where
T: AsyncWrite,
{
FramedWrite::new(inner, self.new_codec())
}
@@ -939,7 +944,8 @@ impl Builder {
/// # pub fn main() {}
/// ```
pub fn new_framed<T>(&self, inner: T) -> Framed<T, LengthDelimitedCodec>
where T: AsyncRead + AsyncWrite,
where
T: AsyncRead + AsyncWrite,
{
Framed::new(inner, self.new_codec())
}
@@ -950,17 +956,16 @@ impl Builder {
}
fn get_num_skip(&self) -> usize {
self.num_skip.unwrap_or(self.length_field_offset + self.length_field_len)
self.num_skip
.unwrap_or(self.length_field_offset + self.length_field_len)
}
}
// ===== impl FrameTooBig =====
impl fmt::Debug for FrameTooBig {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("FrameTooBig")
.finish()
f.debug_struct("FrameTooBig").finish()
}
}
+1 -8
View File
@@ -11,14 +11,7 @@
//! [transports]: https://tokio.rs/docs/going-deeper/frames/
pub use tokio_codec::{
Decoder,
Encoder,
Framed,
FramedParts,
FramedRead,
FramedWrite,
BytesCodec,
LinesCodec,
BytesCodec, Decoder, Encoder, Framed, FramedParts, FramedRead, FramedWrite, LinesCodec,
};
pub mod length_delimited;
+4 -2
View File
@@ -7,7 +7,9 @@
//! the context of the Tokio runtime as they require Tokio specific features to
//! function.
pub use tokio_fs::{create_dir, create_dir_all, file, hard_link, metadata, os, read_dir, read_link};
pub use tokio_fs::{remove_dir, remove_file, rename, set_permissions, symlink_metadata, File};
pub use tokio_fs::OpenOptions;
pub use tokio_fs::{
create_dir, create_dir_all, file, hard_link, metadata, os, read_dir, read_link,
};
pub use tokio_fs::{read, write, ReadFile, WriteFile};
pub use tokio_fs::{remove_dir, remove_file, rename, set_permissions, symlink_metadata, File};
+5 -38
View File
@@ -45,51 +45,18 @@
//! [`ErrorKind`]: enum.ErrorKind.html
//! [`Result`]: type.Result.html
pub use tokio_io::{
AsyncRead,
AsyncWrite,
};
pub use tokio_io::{AsyncRead, AsyncWrite};
// standard input, output, and error
#[cfg(feature = "fs")]
pub use tokio_fs::{
stdin,
Stdin,
stdout,
Stdout,
stderr,
Stderr,
};
pub use tokio_fs::{stderr, stdin, stdout, Stderr, Stdin, Stdout};
// Utils
pub use tokio_io::io::{
copy,
Copy,
flush,
Flush,
lines,
Lines,
read,
read_exact,
ReadExact,
read_to_end,
ReadToEnd,
read_until,
ReadUntil,
ReadHalf,
shutdown,
Shutdown,
write_all,
WriteAll,
WriteHalf,
copy, flush, lines, read, read_exact, read_to_end, read_until, shutdown, write_all, Copy,
Flush, Lines, ReadExact, ReadHalf, ReadToEnd, ReadUntil, Shutdown, WriteAll, WriteHalf,
};
// Re-export io::Error so that users don't have to deal
// with conflicts when `use`ing `futures::io` and `std::io`.
pub use ::std::io::{
Error,
ErrorKind,
Result,
Read,
Write,
};
pub use std::io::{Error, ErrorKind, Read, Result, Write};
+12 -13
View File
@@ -1,10 +1,9 @@
#![doc(html_root_url = "https://docs.rs/tokio/0.1.15")]
#![deny(missing_docs, warnings, missing_debug_implementations)]
#![cfg_attr(feature = "async-await-preview", feature(
async_await,
await_macro,
futures_api,
))]
#![cfg_attr(
feature = "async-await-preview",
feature(async_await, await_macro, futures_api,)
)]
//! A runtime for writing reliable, asynchronous, and slim applications.
//!
@@ -88,24 +87,24 @@ extern crate bytes;
extern crate mio;
#[cfg(feature = "rt-full")]
extern crate num_cpus;
#[cfg(feature = "rt-full")]
extern crate tokio_current_thread;
#[cfg(feature = "io")]
extern crate tokio_io;
#[cfg(feature = "codec")]
extern crate tokio_codec;
#[cfg(feature = "rt-full")]
extern crate tokio_current_thread;
#[cfg(feature = "fs")]
extern crate tokio_fs;
#[cfg(feature = "io")]
extern crate tokio_io;
#[cfg(feature = "reactor")]
extern crate tokio_reactor;
#[cfg(feature = "rt-full")]
extern crate tokio_threadpool;
#[cfg(feature = "sync")]
extern crate tokio_sync;
#[cfg(feature = "timer")]
extern crate tokio_timer;
#[cfg(feature = "tcp")]
extern crate tokio_tcp;
#[cfg(feature = "rt-full")]
extern crate tokio_threadpool;
#[cfg(feature = "timer")]
extern crate tokio_timer;
#[cfg(feature = "udp")]
extern crate tokio_udp;
+7 -34
View File
@@ -11,45 +11,18 @@
//! The prelude may grow over time as additional items see ubiquitous use.
#[cfg(feature = "io")]
pub use tokio_io::{
AsyncRead,
AsyncWrite,
};
pub use tokio_io::{AsyncRead, AsyncWrite};
pub use util::{
FutureExt,
StreamExt,
};
pub use util::{FutureExt, StreamExt};
pub use ::std::io::{
Read,
Write,
};
pub use std::io::{Read, Write};
pub use futures::{
Future,
future,
Stream,
stream,
Sink,
IntoFuture,
Async,
AsyncSink,
Poll,
task,
};
pub use futures::{future, stream, task, Async, AsyncSink, Future, IntoFuture, Poll, Sink, Stream};
#[cfg(feature = "async-await-preview")]
#[doc(inline)]
pub use tokio_async_await::{
io::{
AsyncReadExt,
AsyncWriteExt,
},
sink::{
SinkExt,
},
stream::{
StreamExt as StreamAsyncExt,
},
io::{AsyncReadExt, AsyncWriteExt},
sink::SinkExt,
stream::StreamExt as StreamAsyncExt,
};
+1 -6
View File
@@ -136,12 +136,7 @@
//! [`std::io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
pub use tokio_reactor::{
Reactor,
Handle,
Background,
Turn,
Registration,
PollEvented as PollEvented2,
Background, Handle, PollEvented as PollEvented2, Reactor, Registration, Turn,
};
mod poll_evented;
+30 -22
View File
@@ -10,9 +10,9 @@
use std::fmt;
use std::io::{self, Read, Write};
use std::sync::Mutex;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::Relaxed;
use std::sync::Mutex;
use futures::{task, Async, Poll};
use mio::event::Evented;
@@ -41,9 +41,7 @@ struct Inner {
impl<E: fmt::Debug> fmt::Debug for PollEvented<E> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("PollEvented")
.field("io", &self.io)
.finish()
f.debug_struct("PollEvented").field("io", &self.io).finish()
}
}
@@ -51,7 +49,8 @@ impl<E> PollEvented<E> {
/// Creates a new readiness stream associated with the provided
/// `loop_handle` and for the given `source`.
pub fn new(io: E, handle: &Handle) -> io::Result<PollEvented<E>>
where E: Evented,
where
E: Evented,
{
let registration = Registration::new();
registration.register(&io)?;
@@ -153,7 +152,9 @@ impl<E> PollEvented<E> {
};
// Cache the value
self.inner.write_readiness.store(ready2usize(ready), Relaxed);
self.inner
.write_readiness
.store(ready2usize(ready), Relaxed);
().into()
}
@@ -334,17 +335,17 @@ impl<E> PollEvented<E> {
/// method is called, and will likely return an error if this `PollEvented`
/// was created on a separate event loop from the `handle` specified.
pub fn deregister(&self) -> io::Result<()>
where E: Evented,
where
E: Evented,
{
self.inner.registration.lock().unwrap()
.deregister(&self.io)
self.inner.registration.lock().unwrap().deregister(&self.io)
}
}
impl<E: Read> Read for PollEvented<E> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
if let Async::NotReady = self.poll_read() {
return Err(io::ErrorKind::WouldBlock.into())
return Err(io::ErrorKind::WouldBlock.into());
}
let r = self.get_mut().read(buf);
@@ -353,14 +354,14 @@ impl<E: Read> Read for PollEvented<E> {
self.need_read()?;
}
return r
return r;
}
}
impl<E: Write> Write for PollEvented<E> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
if let Async::NotReady = self.poll_write() {
return Err(io::ErrorKind::WouldBlock.into())
return Err(io::ErrorKind::WouldBlock.into());
}
let r = self.get_mut().write(buf);
@@ -369,12 +370,12 @@ impl<E: Write> Write for PollEvented<E> {
self.need_write()?;
}
return r
return r;
}
fn flush(&mut self) -> io::Result<()> {
if let Async::NotReady = self.poll_write() {
return Err(io::ErrorKind::WouldBlock.into())
return Err(io::ErrorKind::WouldBlock.into());
}
let r = self.get_mut().flush();
@@ -383,12 +384,11 @@ impl<E: Write> Write for PollEvented<E> {
self.need_write()?;
}
return r
return r;
}
}
impl<E: Read> AsyncRead for PollEvented<E> {
}
impl<E: Read> AsyncRead for PollEvented<E> {}
impl<E: Write> AsyncWrite for PollEvented<E> {
fn shutdown(&mut self) -> Poll<(), io::Error> {
@@ -430,8 +430,8 @@ fn usize2ready(bits: usize) -> Ready {
#[cfg(unix)]
mod platform {
use mio::Ready;
use mio::unix::UnixReady;
use mio::Ready;
const HUP: usize = 1 << 2;
const ERROR: usize = 1 << 3;
@@ -476,14 +476,22 @@ mod platform {
bits
}
#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios",
target_os = "macos"))]
#[cfg(any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "ios",
target_os = "macos"
))]
fn usize2ready_aio(ready: &mut UnixReady) {
ready.insert(UnixReady::aio());
}
#[cfg(not(any(target_os = "dragonfly",
target_os = "freebsd", target_os = "ios", target_os = "macos")))]
#[cfg(not(any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "ios",
target_os = "macos"
)))]
fn usize2ready_aio(_ready: &mut UnixReady) {
// aio not available here → empty
}
+1 -4
View File
@@ -10,7 +10,4 @@
//! - [mpsc](mpsc/index.html), a multi-producer, single-consumer channel for
//! sending values between tasks.
pub use tokio_sync::{
mpsc,
oneshot,
};
pub use tokio_sync::{mpsc, oneshot};
+1 -9
View File
@@ -82,15 +82,7 @@
//! [Interval]: struct.Interval.html
//! [`DelayQueue`]: struct.DelayQueue.html
pub use tokio_timer::{
delay_queue,
DelayQueue,
Error,
Interval,
Delay,
Timeout,
timeout,
};
pub use tokio_timer::{delay_queue, timeout, Delay, DelayQueue, Error, Interval, Timeout};
#[deprecated(since = "0.1.8", note = "use Timeout instead")]
#[allow(deprecated)]
+7 -3
View File
@@ -1,4 +1,4 @@
use futures::{Async, Poll, Stream, Sink, StartSend};
use futures::{Async, Poll, Sink, StartSend, Stream};
/// A stream combinator which combines the yields the current item
/// plus its count starting from 0.
@@ -13,7 +13,10 @@ pub struct Enumerate<T> {
impl<T> Enumerate<T> {
pub(crate) fn new(stream: T) -> Self {
Self { inner: stream, count: 0 }
Self {
inner: stream,
count: 0,
}
}
/// Acquires a reference to the underlying stream that this combinator is
@@ -61,7 +64,8 @@ where
// Forwarding impl of Sink from the underlying stream
impl<T> Sink for Enumerate<T>
where T: Sink
where
T: Sink,
{
type SinkItem = T::SinkItem;
type SinkError = T::SinkError;
+5 -5
View File
@@ -7,8 +7,7 @@ use tokio_timer::Timeout;
use futures::Future;
#[cfg(feature = "timer")]
use std::time::{Instant, Duration};
use std::time::{Duration, Instant};
/// An extension trait for `Future` that provides a variety of convenient
/// combinator functions.
@@ -24,7 +23,6 @@ use std::time::{Instant, Duration};
///
/// [`timeout`]: #method.timeout
pub trait FutureExt: Future {
/// Creates a new future which allows `self` until `timeout`.
///
/// This combinator creates a new future which wraps the receiving future
@@ -60,7 +58,8 @@ pub trait FutureExt: Future {
/// ```
#[cfg(feature = "timer")]
fn timeout(self, timeout: Duration) -> Timeout<Self>
where Self: Sized,
where
Self: Sized,
{
Timeout::new(self, timeout)
}
@@ -70,7 +69,8 @@ pub trait FutureExt: Future {
#[allow(deprecated)]
#[doc(hidden)]
fn deadline(self, deadline: Instant) -> Deadline<Self>
where Self: Sized,
where
Self: Sized,
{
Deadline::new(self, deadline)
}
+1 -1
View File
@@ -7,9 +7,9 @@
//! [`FutureExt`]: trait.FutureExt.html
//! [`StreamExt`]: trait.StreamExt.html
mod enumerate;
mod future;
mod stream;
mod enumerate;
pub use self::future::FutureExt;
pub use self::stream::StreamExt;
+7 -7
View File
@@ -1,8 +1,5 @@
#[cfg(feature = "timer")]
use tokio_timer::{
throttle::Throttle,
Timeout,
};
use tokio_timer::{throttle::Throttle, Timeout};
use futures::Stream;
@@ -29,7 +26,8 @@ pub trait StreamExt: Stream {
/// Errors are also delayed.
#[cfg(feature = "timer")]
fn throttle(self, duration: Duration) -> Throttle<Self>
where Self: Sized
where
Self: Sized,
{
Throttle::new(self, duration)
}
@@ -47,7 +45,8 @@ pub trait StreamExt: Stream {
/// an iterator with more than [`std::usize::MAX`] elements either produces the
/// wrong result or panics.
fn enumerate(self) -> Enumerate<Self>
where Self: Sized,
where
Self: Sized,
{
Enumerate::new(self)
}
@@ -86,7 +85,8 @@ pub trait StreamExt: Stream {
/// ```
#[cfg(feature = "timer")]
fn timeout(self, timeout: Duration) -> Timeout<Self>
where Self: Sized,
where
Self: Sized,
{
Timeout::new(self, timeout)
}
+9 -7
View File
@@ -3,20 +3,22 @@ extern crate futures;
extern crate tokio;
extern crate tokio_io;
use std::io::{BufReader, BufWriter, Read, Write};
use std::net::TcpStream;
use std::thread;
use std::io::{Read, Write, BufReader, BufWriter};
use futures::Future;
use futures::stream::Stream;
use tokio_io::io::copy;
use futures::Future;
use tokio::net::TcpListener;
use tokio_io::io::copy;
macro_rules! t {
($e:expr) => (match $e {
Ok(e) => e,
Err(e) => panic!("{} failed with {:?}", stringify!($e), e),
})
($e:expr) => {
match $e {
Ok(e) => e,
Err(e) => panic!("{} failed with {:?}", stringify!($e), e),
}
};
}
#[test]
+5 -10
View File
@@ -1,7 +1,7 @@
extern crate env_logger;
extern crate futures;
extern crate tokio;
extern crate tokio_timer;
extern crate env_logger;
use tokio::prelude::*;
use tokio::runtime::{self, current_thread};
@@ -26,10 +26,7 @@ fn clock_and_timer_concurrent() {
let when = Instant::now() + Duration::from_millis(5_000);
let clock = Clock::new_with_now(MockNow(when));
let mut rt = runtime::Builder::new()
.clock(clock)
.build()
.unwrap();
let mut rt = runtime::Builder::new().clock(clock).build().unwrap();
let (tx, rx) = mpsc::channel();
@@ -53,10 +50,7 @@ fn clock_and_timer_single_threaded() {
let when = Instant::now() + Duration::from_millis(5_000);
let clock = Clock::new_with_now(MockNow(when));
let mut rt = current_thread::Builder::new()
.clock(clock)
.build()
.unwrap();
let mut rt = current_thread::Builder::new().clock(clock).build().unwrap();
rt.block_on({
Delay::new(when)
@@ -65,5 +59,6 @@ fn clock_and_timer_single_threaded() {
assert!(Instant::now() < when);
Ok(())
})
}).unwrap();
})
.unwrap();
}
+2 -2
View File
@@ -1,8 +1,8 @@
extern crate tokio;
extern crate futures;
extern crate tokio;
use std::thread;
use std::net;
use std::thread;
use futures::future;
use futures::prelude::*;
-1
View File
@@ -23,5 +23,4 @@ fn enumerate() {
result.wait(),
Ok(vec![(0, 0), (1, 2), (2, 4), (3, 6), (4, 8)])
);
}
+27 -22
View File
@@ -1,42 +1,48 @@
extern crate env_logger;
extern crate futures;
extern crate tokio;
extern crate tokio_io;
extern crate env_logger;
use std::{io, thread};
use std::sync::Arc;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::Relaxed;
use std::sync::Arc;
use std::{io, thread};
use futures::prelude::*;
use tokio::net::{TcpStream, TcpListener};
use tokio::net::{TcpListener, TcpStream};
use tokio::runtime::Runtime;
macro_rules! t {
($e:expr) => (match $e {
Ok(e) => e,
Err(e) => panic!("{} failed with {:?}", stringify!($e), e),
})
($e:expr) => {
match $e {
Ok(e) => e,
Err(e) => panic!("{} failed with {:?}", stringify!($e), e),
}
};
}
#[test]
fn hammer_old() {
let _ = env_logger::try_init();
let threads = (0..10).map(|_| {
thread::spawn(|| {
let srv = t!(TcpListener::bind(&"127.0.0.1:0".parse().unwrap()));
let addr = t!(srv.local_addr());
let mine = TcpStream::connect(&addr);
let theirs = srv.incoming().into_future()
.map(|(s, _)| s.unwrap())
.map_err(|(s, _)| s);
let (mine, theirs) = t!(mine.join(theirs).wait());
let threads = (0..10)
.map(|_| {
thread::spawn(|| {
let srv = t!(TcpListener::bind(&"127.0.0.1:0".parse().unwrap()));
let addr = t!(srv.local_addr());
let mine = TcpStream::connect(&addr);
let theirs = srv
.incoming()
.into_future()
.map(|(s, _)| s.unwrap())
.map_err(|(s, _)| s);
let (mine, theirs) = t!(mine.join(theirs).wait());
assert_eq!(t!(mine.local_addr()), t!(theirs.peer_addr()));
assert_eq!(t!(theirs.local_addr()), t!(mine.peer_addr()));
assert_eq!(t!(mine.local_addr()), t!(theirs.peer_addr()));
assert_eq!(t!(theirs.local_addr()), t!(mine.peer_addr()));
})
})
}).collect::<Vec<_>>();
.collect::<Vec<_>>();
for thread in threads {
thread.join().unwrap();
}
@@ -51,8 +57,7 @@ impl io::Read for Rd {
}
}
impl tokio_io::AsyncRead for Rd {
}
impl tokio_io::AsyncRead for Rd {}
impl io::Write for Wr {
fn write(&mut self, src: &[u8]) -> io::Result<usize> {
+190 -143
View File
@@ -1,16 +1,16 @@
extern crate tokio;
extern crate futures;
extern crate bytes;
extern crate futures;
extern crate tokio;
use tokio::io::{AsyncRead, AsyncWrite};
use tokio::codec::*;
use tokio::io::{AsyncRead, AsyncWrite};
use bytes::{Bytes, BytesMut, BufMut};
use futures::{Stream, Sink, Poll};
use bytes::{BufMut, Bytes, BytesMut};
use futures::Async::*;
use futures::{Poll, Sink, Stream};
use std::io;
use std::collections::VecDeque;
use std::io;
macro_rules! mock {
($($x:expr,)*) => {{
@@ -20,7 +20,6 @@ macro_rules! mock {
}};
}
#[test]
fn read_empty_io_yields_nothing() {
let mut io = FramedRead::new(mock!(), LengthDelimitedCodec::new());
@@ -30,9 +29,12 @@ fn read_empty_io_yields_nothing() {
#[test]
fn read_single_frame_one_packet() {
let mut io = FramedRead::new(mock! {
Ok(b"\x00\x00\x00\x09abcdefghi"[..].into()),
}, LengthDelimitedCodec::new());
let mut io = FramedRead::new(
mock! {
Ok(b"\x00\x00\x00\x09abcdefghi"[..].into()),
},
LengthDelimitedCodec::new(),
);
assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
assert_eq!(io.poll().unwrap(), Ready(None));
@@ -74,9 +76,12 @@ fn read_single_multi_frame_one_packet() {
data.extend_from_slice(b"\x00\x00\x00\x03123");
data.extend_from_slice(b"\x00\x00\x00\x0bhello world");
let mut io = FramedRead::new(mock! {
Ok(data.into()),
}, LengthDelimitedCodec::new());
let mut io = FramedRead::new(
mock! {
Ok(data.into()),
},
LengthDelimitedCodec::new(),
);
assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
assert_eq!(io.poll().unwrap(), Ready(Some(b"123"[..].into())));
@@ -86,11 +91,14 @@ fn read_single_multi_frame_one_packet() {
#[test]
fn read_single_frame_multi_packet() {
let mut io = FramedRead::new(mock! {
Ok(b"\x00\x00"[..].into()),
Ok(b"\x00\x09abc"[..].into()),
Ok(b"defghi"[..].into()),
}, LengthDelimitedCodec::new());
let mut io = FramedRead::new(
mock! {
Ok(b"\x00\x00"[..].into()),
Ok(b"\x00\x09abc"[..].into()),
Ok(b"defghi"[..].into()),
},
LengthDelimitedCodec::new(),
);
assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
assert_eq!(io.poll().unwrap(), Ready(None));
@@ -98,13 +106,16 @@ fn read_single_frame_multi_packet() {
#[test]
fn read_multi_frame_multi_packet() {
let mut io = FramedRead::new(mock! {
Ok(b"\x00\x00"[..].into()),
Ok(b"\x00\x09abc"[..].into()),
Ok(b"defghi"[..].into()),
Ok(b"\x00\x00\x00\x0312"[..].into()),
Ok(b"3\x00\x00\x00\x0bhello world"[..].into()),
}, LengthDelimitedCodec::new());
let mut io = FramedRead::new(
mock! {
Ok(b"\x00\x00"[..].into()),
Ok(b"\x00\x09abc"[..].into()),
Ok(b"defghi"[..].into()),
Ok(b"\x00\x00\x00\x0312"[..].into()),
Ok(b"3\x00\x00\x00\x0bhello world"[..].into()),
},
LengthDelimitedCodec::new(),
);
assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
assert_eq!(io.poll().unwrap(), Ready(Some(b"123"[..].into())));
@@ -114,14 +125,17 @@ fn read_multi_frame_multi_packet() {
#[test]
fn read_single_frame_multi_packet_wait() {
let mut io = FramedRead::new(mock! {
Ok(b"\x00\x00"[..].into()),
Err(would_block()),
Ok(b"\x00\x09abc"[..].into()),
Err(would_block()),
Ok(b"defghi"[..].into()),
Err(would_block()),
}, LengthDelimitedCodec::new());
let mut io = FramedRead::new(
mock! {
Ok(b"\x00\x00"[..].into()),
Err(would_block()),
Ok(b"\x00\x09abc"[..].into()),
Err(would_block()),
Ok(b"defghi"[..].into()),
Err(would_block()),
},
LengthDelimitedCodec::new(),
);
assert_eq!(io.poll().unwrap(), NotReady);
assert_eq!(io.poll().unwrap(), NotReady);
@@ -132,19 +146,21 @@ fn read_single_frame_multi_packet_wait() {
#[test]
fn read_multi_frame_multi_packet_wait() {
let mut io = FramedRead::new(mock! {
Ok(b"\x00\x00"[..].into()),
Err(would_block()),
Ok(b"\x00\x09abc"[..].into()),
Err(would_block()),
Ok(b"defghi"[..].into()),
Err(would_block()),
Ok(b"\x00\x00\x00\x0312"[..].into()),
Err(would_block()),
Ok(b"3\x00\x00\x00\x0bhello world"[..].into()),
Err(would_block()),
}, LengthDelimitedCodec::new());
let mut io = FramedRead::new(
mock! {
Ok(b"\x00\x00"[..].into()),
Err(would_block()),
Ok(b"\x00\x09abc"[..].into()),
Err(would_block()),
Ok(b"defghi"[..].into()),
Err(would_block()),
Ok(b"\x00\x00\x00\x0312"[..].into()),
Err(would_block()),
Ok(b"3\x00\x00\x00\x0bhello world"[..].into()),
Err(would_block()),
},
LengthDelimitedCodec::new(),
);
assert_eq!(io.poll().unwrap(), NotReady);
assert_eq!(io.poll().unwrap(), NotReady);
@@ -159,20 +175,26 @@ fn read_multi_frame_multi_packet_wait() {
#[test]
fn read_incomplete_head() {
let mut io = FramedRead::new(mock! {
Ok(b"\x00\x00"[..].into()),
}, LengthDelimitedCodec::new());
let mut io = FramedRead::new(
mock! {
Ok(b"\x00\x00"[..].into()),
},
LengthDelimitedCodec::new(),
);
assert!(io.poll().is_err());
}
#[test]
fn read_incomplete_head_multi() {
let mut io = FramedRead::new(mock! {
Err(would_block()),
Ok(b"\x00"[..].into()),
Err(would_block()),
}, LengthDelimitedCodec::new());
let mut io = FramedRead::new(
mock! {
Err(would_block()),
Ok(b"\x00"[..].into()),
Err(would_block()),
},
LengthDelimitedCodec::new(),
);
assert_eq!(io.poll().unwrap(), NotReady);
assert_eq!(io.poll().unwrap(), NotReady);
@@ -181,12 +203,15 @@ fn read_incomplete_head_multi() {
#[test]
fn read_incomplete_payload() {
let mut io = FramedRead::new(mock! {
Ok(b"\x00\x00\x00\x09ab"[..].into()),
Err(would_block()),
Ok(b"cd"[..].into()),
Err(would_block()),
}, LengthDelimitedCodec::new());
let mut io = FramedRead::new(
mock! {
Ok(b"\x00\x00\x00\x09ab"[..].into()),
Err(would_block()),
Ok(b"cd"[..].into()),
Err(would_block()),
},
LengthDelimitedCodec::new(),
);
assert_eq!(io.poll().unwrap(), NotReady);
assert_eq!(io.poll().unwrap(), NotReady);
@@ -206,11 +231,10 @@ fn read_max_frame_len() {
#[test]
fn read_update_max_frame_len_at_rest() {
let mut io = length_delimited::Builder::new()
.new_read(mock! {
Ok(b"\x00\x00\x00\x09abcdefghi"[..].into()),
Ok(b"\x00\x00\x00\x09abcdefghi"[..].into()),
});
let mut io = length_delimited::Builder::new().new_read(mock! {
Ok(b"\x00\x00\x00\x09abcdefghi"[..].into()),
Ok(b"\x00\x00\x00\x09abcdefghi"[..].into()),
});
assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
io.decoder_mut().set_max_frame_length(5);
@@ -219,13 +243,12 @@ fn read_update_max_frame_len_at_rest() {
#[test]
fn read_update_max_frame_len_in_flight() {
let mut io = length_delimited::Builder::new()
.new_read(mock! {
Ok(b"\x00\x00\x00\x09abcd"[..].into()),
Err(would_block()),
Ok(b"efghi"[..].into()),
Ok(b"\x00\x00\x00\x09abcdefghi"[..].into()),
});
let mut io = length_delimited::Builder::new().new_read(mock! {
Ok(b"\x00\x00\x00\x09abcd"[..].into()),
Err(would_block()),
Ok(b"efghi"[..].into()),
Ok(b"\x00\x00\x00\x09abcdefghi"[..].into()),
});
assert_eq!(io.poll().unwrap(), NotReady);
io.decoder_mut().set_max_frame_length(5);
@@ -274,9 +297,15 @@ fn read_single_multi_frame_one_packet_skip_none_adjusted() {
Ok(data.into()),
});
assert_eq!(io.poll().unwrap(), Ready(Some(b"xx\x00\x09abcdefghi"[..].into())));
assert_eq!(
io.poll().unwrap(),
Ready(Some(b"xx\x00\x09abcdefghi"[..].into()))
);
assert_eq!(io.poll().unwrap(), Ready(Some(b"yy\x00\x03123"[..].into())));
assert_eq!(io.poll().unwrap(), Ready(Some(b"zz\x00\x0bhello world"[..].into())));
assert_eq!(
io.poll().unwrap(),
Ready(Some(b"zz\x00\x0bhello world"[..].into()))
);
assert_eq!(io.poll().unwrap(), Ready(None));
}
@@ -316,20 +345,20 @@ fn write_single_frame_length_adjusted() {
#[test]
fn write_nothing_yields_nothing() {
let mut io = FramedWrite::new(
mock!(),
LengthDelimitedCodec::new()
);
let mut io = FramedWrite::new(mock!(), LengthDelimitedCodec::new());
assert!(io.poll_complete().unwrap().is_ready());
}
#[test]
fn write_single_frame_one_packet() {
let mut io = FramedWrite::new(mock! {
Ok(b"\x00\x00\x00\x09"[..].into()),
Ok(b"abcdefghi"[..].into()),
Ok(Flush),
}, LengthDelimitedCodec::new());
let mut io = FramedWrite::new(
mock! {
Ok(b"\x00\x00\x00\x09"[..].into()),
Ok(b"abcdefghi"[..].into()),
Ok(Flush),
},
LengthDelimitedCodec::new(),
);
assert!(io.start_send(Bytes::from("abcdefghi")).unwrap().is_ready());
assert!(io.poll_complete().unwrap().is_ready());
@@ -338,56 +367,71 @@ fn write_single_frame_one_packet() {
#[test]
fn write_single_multi_frame_one_packet() {
let mut io = FramedWrite::new(mock! {
Ok(b"\x00\x00\x00\x09"[..].into()),
Ok(b"abcdefghi"[..].into()),
Ok(b"\x00\x00\x00\x03"[..].into()),
Ok(b"123"[..].into()),
Ok(b"\x00\x00\x00\x0b"[..].into()),
Ok(b"hello world"[..].into()),
Ok(Flush),
}, LengthDelimitedCodec::new());
let mut io = FramedWrite::new(
mock! {
Ok(b"\x00\x00\x00\x09"[..].into()),
Ok(b"abcdefghi"[..].into()),
Ok(b"\x00\x00\x00\x03"[..].into()),
Ok(b"123"[..].into()),
Ok(b"\x00\x00\x00\x0b"[..].into()),
Ok(b"hello world"[..].into()),
Ok(Flush),
},
LengthDelimitedCodec::new(),
);
assert!(io.start_send(Bytes::from("abcdefghi")).unwrap().is_ready());
assert!(io.start_send(Bytes::from("123")).unwrap().is_ready());
assert!(io.start_send(Bytes::from("hello world")).unwrap().is_ready());
assert!(io
.start_send(Bytes::from("hello world"))
.unwrap()
.is_ready());
assert!(io.poll_complete().unwrap().is_ready());
assert!(io.get_ref().calls.is_empty());
}
#[test]
fn write_single_multi_frame_multi_packet() {
let mut io = FramedWrite::new(mock! {
Ok(b"\x00\x00\x00\x09"[..].into()),
Ok(b"abcdefghi"[..].into()),
Ok(Flush),
Ok(b"\x00\x00\x00\x03"[..].into()),
Ok(b"123"[..].into()),
Ok(Flush),
Ok(b"\x00\x00\x00\x0b"[..].into()),
Ok(b"hello world"[..].into()),
Ok(Flush),
}, LengthDelimitedCodec::new());
let mut io = FramedWrite::new(
mock! {
Ok(b"\x00\x00\x00\x09"[..].into()),
Ok(b"abcdefghi"[..].into()),
Ok(Flush),
Ok(b"\x00\x00\x00\x03"[..].into()),
Ok(b"123"[..].into()),
Ok(Flush),
Ok(b"\x00\x00\x00\x0b"[..].into()),
Ok(b"hello world"[..].into()),
Ok(Flush),
},
LengthDelimitedCodec::new(),
);
assert!(io.start_send(Bytes::from("abcdefghi")).unwrap().is_ready());
assert!(io.poll_complete().unwrap().is_ready());
assert!(io.start_send(Bytes::from("123")).unwrap().is_ready());
assert!(io.poll_complete().unwrap().is_ready());
assert!(io.start_send(Bytes::from("hello world")).unwrap().is_ready());
assert!(io
.start_send(Bytes::from("hello world"))
.unwrap()
.is_ready());
assert!(io.poll_complete().unwrap().is_ready());
assert!(io.get_ref().calls.is_empty());
}
#[test]
fn write_single_frame_would_block() {
let mut io = FramedWrite::new(mock! {
Err(would_block()),
Ok(b"\x00\x00"[..].into()),
Err(would_block()),
Ok(b"\x00\x09"[..].into()),
Ok(b"abcdefghi"[..].into()),
Ok(Flush),
}, LengthDelimitedCodec::new());
let mut io = FramedWrite::new(
mock! {
Err(would_block()),
Ok(b"\x00\x00"[..].into()),
Err(would_block()),
Ok(b"\x00\x09"[..].into()),
Ok(b"abcdefghi"[..].into()),
Ok(Flush),
},
LengthDelimitedCodec::new(),
);
assert!(io.start_send(Bytes::from("abcdefghi")).unwrap().is_ready());
assert!(!io.poll_complete().unwrap().is_ready());
@@ -412,7 +456,6 @@ fn write_single_frame_little_endian() {
assert!(io.get_ref().calls.is_empty());
}
#[test]
fn write_single_frame_with_short_length_field() {
let mut io = length_delimited::Builder::new()
@@ -432,54 +475,63 @@ fn write_single_frame_with_short_length_field() {
fn write_max_frame_len() {
let mut io = length_delimited::Builder::new()
.max_frame_length(5)
.new_write(mock! { });
.new_write(mock! {});
assert_eq!(io.start_send(Bytes::from("abcdef")).unwrap_err().kind(), io::ErrorKind::InvalidInput);
assert_eq!(
io.start_send(Bytes::from("abcdef")).unwrap_err().kind(),
io::ErrorKind::InvalidInput
);
assert!(io.get_ref().calls.is_empty());
}
#[test]
fn write_update_max_frame_len_at_rest() {
let mut io = length_delimited::Builder::new()
.new_write(mock! {
Ok(b"\x00\x00\x00\x06"[..].into()),
Ok(b"abcdef"[..].into()),
Ok(Flush),
});
let mut io = length_delimited::Builder::new().new_write(mock! {
Ok(b"\x00\x00\x00\x06"[..].into()),
Ok(b"abcdef"[..].into()),
Ok(Flush),
});
assert!(io.start_send(Bytes::from("abcdef")).unwrap().is_ready());
assert!(io.poll_complete().unwrap().is_ready());
io.encoder_mut().set_max_frame_length(5);
assert_eq!(io.start_send(Bytes::from("abcdef")).unwrap_err().kind(), io::ErrorKind::InvalidInput);
assert_eq!(
io.start_send(Bytes::from("abcdef")).unwrap_err().kind(),
io::ErrorKind::InvalidInput
);
assert!(io.get_ref().calls.is_empty());
}
#[test]
fn write_update_max_frame_len_in_flight() {
let mut io = length_delimited::Builder::new()
.new_write(mock! {
Ok(b"\x00\x00\x00\x06"[..].into()),
Ok(b"ab"[..].into()),
Err(would_block()),
Ok(b"cdef"[..].into()),
Ok(Flush),
});
let mut io = length_delimited::Builder::new().new_write(mock! {
Ok(b"\x00\x00\x00\x06"[..].into()),
Ok(b"ab"[..].into()),
Err(would_block()),
Ok(b"cdef"[..].into()),
Ok(Flush),
});
assert!(io.start_send(Bytes::from("abcdef")).unwrap().is_ready());
assert!(!io.poll_complete().unwrap().is_ready());
io.encoder_mut().set_max_frame_length(5);
assert!(io.poll_complete().unwrap().is_ready());
assert_eq!(io.start_send(Bytes::from("abcdef")).unwrap_err().kind(), io::ErrorKind::InvalidInput);
assert_eq!(
io.start_send(Bytes::from("abcdef")).unwrap_err().kind(),
io::ErrorKind::InvalidInput
);
assert!(io.get_ref().calls.is_empty());
}
#[test]
fn write_zero() {
let mut io = length_delimited::Builder::new()
.new_write(mock! { });
let mut io = length_delimited::Builder::new().new_write(mock! {});
assert!(io.start_send(Bytes::from("abcdef")).unwrap().is_ready());
assert_eq!(io.poll_complete().unwrap_err().kind(), io::ErrorKind::WriteZero);
assert_eq!(
io.poll_complete().unwrap_err().kind(),
io::ErrorKind::WriteZero
);
assert!(io.get_ref().calls.is_empty());
}
@@ -490,9 +542,7 @@ fn encode_overflow() {
let mut buf = BytesMut::with_capacity(1024);
// Put some data into the buffer without resizing it to hold more.
let some_as = std::iter::repeat(b'a')
.take(1024)
.collect::<Vec<_>>();
let some_as = std::iter::repeat(b'a').take(1024).collect::<Vec<_>>();
buf.put_slice(&some_as[..]);
// Trying to encode the length header should resize the buffer if it won't fit.
@@ -531,8 +581,7 @@ impl io::Read for Mock {
}
}
impl AsyncRead for Mock {
}
impl AsyncRead for Mock {}
impl io::Write for Mock {
fn write(&mut self, src: &[u8]) -> io::Result<usize> {
@@ -551,9 +600,7 @@ impl io::Write for Mock {
fn flush(&mut self) -> io::Result<()> {
match self.calls.pop_front() {
Some(Ok(Op::Flush)) => {
Ok(())
}
Some(Ok(Op::Flush)) => Ok(()),
Some(Ok(_)) => panic!(),
Some(Err(e)) => Err(e),
None => Ok(()),
+12 -10
View File
@@ -1,19 +1,19 @@
extern crate bytes;
extern crate env_logger;
extern crate futures;
extern crate tokio;
extern crate tokio_codec;
extern crate tokio_io;
extern crate tokio_threadpool;
extern crate bytes;
use std::io;
use std::net::Shutdown;
use bytes::{BytesMut, BufMut};
use futures::{Future, Stream, Sink};
use bytes::{BufMut, BytesMut};
use futures::{Future, Sink, Stream};
use tokio::net::{TcpListener, TcpStream};
use tokio_codec::{Encoder, Decoder};
use tokio_io::io::{write_all, read};
use tokio_codec::{Decoder, Encoder};
use tokio_io::io::{read, write_all};
use tokio_threadpool::Builder;
pub struct LineCodec;
@@ -53,20 +53,22 @@ impl Encoder for LineCodec {
fn echo() {
drop(env_logger::try_init());
let pool = Builder::new()
.pool_size(1)
.build();
let pool = Builder::new().pool_size(1).build();
let listener = TcpListener::bind(&"127.0.0.1:0".parse().unwrap()).unwrap();
let addr = listener.local_addr().unwrap();
let sender = pool.sender().clone();
let srv = listener.incoming().for_each(move |socket| {
let (sink, stream) = LineCodec.framed(socket).split();
sender.spawn(sink.send_all(stream).map(|_| ()).map_err(|_| ())).unwrap();
sender
.spawn(sink.send_all(stream).map(|_| ()).map_err(|_| ()))
.unwrap();
Ok(())
});
pool.sender().spawn(srv.map_err(|e| panic!("srv error: {}", e))).unwrap();
pool.sender()
.spawn(srv.map_err(|e| panic!("srv error: {}", e)))
.unwrap();
let client = TcpStream::connect(&addr);
let client = client.wait().unwrap();
+27 -12
View File
@@ -13,18 +13,20 @@ use std::os::unix::io::{AsRawFd, FromRawFd};
use std::thread;
use std::time::Duration;
use futures::Future;
use mio::event::Evented;
use mio::unix::{UnixReady, EventedFd};
use mio::unix::{EventedFd, UnixReady};
use mio::{PollOpt, Ready, Token};
use tokio::reactor::{Handle, PollEvented2};
use tokio_io::io::read_to_end;
use futures::Future;
macro_rules! t {
($e:expr) => (match $e {
Ok(e) => e,
Err(e) => panic!("{} failed with {:?}", stringify!($e), e),
})
($e:expr) => {
match $e {
Ok(e) => e,
Err(e) => panic!("{} failed with {:?}", stringify!($e), e),
}
};
}
struct MyFile(File);
@@ -46,13 +48,23 @@ impl io::Read for MyFile {
}
impl Evented for MyFile {
fn register(&self, poll: &mio::Poll, token: Token, interest: Ready, opts: PollOpt)
-> io::Result<()> {
fn register(
&self,
poll: &mio::Poll,
token: Token,
interest: Ready,
opts: PollOpt,
) -> io::Result<()> {
let hup: Ready = UnixReady::hup().into();
EventedFd(&self.0.as_raw_fd()).register(poll, token, interest | hup, opts)
}
fn reregister(&self, poll: &mio::Poll, token: Token, interest: Ready, opts: PollOpt)
-> io::Result<()> {
fn reregister(
&self,
poll: &mio::Poll,
token: Token,
interest: Ready,
opts: PollOpt,
) -> io::Result<()> {
let hup: Ready = UnixReady::hup().into();
EventedFd(&self.0.as_raw_fd()).reregister(poll, token, interest | hup, opts)
}
@@ -68,8 +80,11 @@ fn hup() {
let handle = Handle::default();
unsafe {
let mut pipes = [0; 2];
assert!(libc::pipe(pipes.as_mut_ptr()) != -1,
"pipe error: {}", io::Error::last_os_error());
assert!(
libc::pipe(pipes.as_mut_ptr()) != -1,
"pipe error: {}",
io::Error::last_os_error()
);
let read = File::from_raw_fd(pipes[0]);
let mut write = File::from_raw_fd(pipes[1]);
let t = thread::spawn(move || {
+5 -3
View File
@@ -6,8 +6,8 @@ extern crate tokio_tcp;
use tokio_reactor::Reactor;
use tokio_tcp::TcpListener;
use futures::{Future, Stream};
use futures::executor::{spawn, Notify, Spawn};
use futures::{Future, Stream};
use std::mem;
use std::net::TcpStream;
@@ -62,7 +62,8 @@ fn test_drop_on_notify() {
// Define a task that just drains the listener
let task = Box::new({
listener.incoming()
listener
.incoming()
.for_each(|_| Ok(()))
.map_err(|_| panic!())
}) as Box<Future<Item = (), Error = ()>>;
@@ -75,7 +76,8 @@ fn test_drop_on_notify() {
tokio_reactor::with_default(&reactor.handle(), &mut enter, |_| {
let id = &*task as *const Task as usize;
task.lock().unwrap()
task.lock()
.unwrap()
.poll_future_notify(&notify, id)
.unwrap();
});
+83 -67
View File
@@ -1,12 +1,12 @@
extern crate tokio;
extern crate env_logger;
extern crate futures;
extern crate tokio;
use futures::sync::oneshot;
use std::sync::{Arc, Mutex, atomic};
use std::sync::{atomic, Arc, Mutex};
use std::thread;
use tokio::io;
use tokio::net::{TcpStream, TcpListener};
use tokio::net::{TcpListener, TcpStream};
use tokio::prelude::future::lazy;
use tokio::prelude::*;
use tokio::runtime::Runtime;
@@ -17,18 +17,22 @@ use tokio::runtime::Runtime;
pub use futures::future::Executor;
macro_rules! t {
($e:expr) => (match $e {
Ok(e) => e,
Err(e) => panic!("{} failed with {:?}", stringify!($e), e),
})
($e:expr) => {
match $e {
Ok(e) => e,
Err(e) => panic!("{} failed with {:?}", stringify!($e), e),
}
};
}
fn create_client_server_future() -> Box<Future<Item=(), Error=()> + Send> {
fn create_client_server_future() -> Box<Future<Item = (), Error = ()> + Send> {
let server = t!(TcpListener::bind(&"127.0.0.1:0".parse().unwrap()));
let addr = t!(server.local_addr());
let client = TcpStream::connect(&addr);
let server = server.incoming().take(1)
let server = server
.incoming()
.take(1)
.map_err(|e| panic!("accept err = {:?}", e))
.for_each(|socket| {
tokio::spawn({
@@ -48,8 +52,7 @@ fn create_client_server_future() -> Box<Future<Item=(), Error=()> + Send> {
.map_err(|e| panic!("read err = {:?}", e))
});
let future = server.join(client)
.map(|_| ());
let future = server.join(client).map(|_| ());
Box::new(future)
}
@@ -64,8 +67,7 @@ fn runtime_tokio_run() {
fn runtime_single_threaded() {
let _ = env_logger::try_init();
let mut runtime = tokio::runtime::current_thread::Runtime::new()
.unwrap();
let mut runtime = tokio::runtime::current_thread::Runtime::new().unwrap();
runtime.block_on(create_client_server_future()).unwrap();
runtime.run().unwrap();
}
@@ -82,7 +84,7 @@ mod runtime_single_threaded_block_on_all {
fn test<F>(spawn: F)
where
F: Fn(Box<Future<Item=(), Error=()> + Send>),
F: Fn(Box<Future<Item = (), Error = ()> + Send>),
{
let cnt = Arc::new(Mutex::new(0));
let c = cnt.clone();
@@ -103,7 +105,8 @@ mod runtime_single_threaded_block_on_all {
})));
Ok::<_, ()>("hello")
})).unwrap();
}))
.unwrap();
assert_eq!(2, *cnt.lock().unwrap());
assert_eq!(msg, "hello");
@@ -111,7 +114,9 @@ mod runtime_single_threaded_block_on_all {
#[test]
fn spawn() {
test(|f| { tokio::spawn(f); })
test(|f| {
tokio::spawn(f);
})
}
#[test]
@@ -128,10 +133,7 @@ mod runtime_single_threaded_racy {
use super::*;
fn test<F>(spawn: F)
where
F: Fn(
tokio::runtime::current_thread::Handle,
Box<Future<Item=(), Error=()> + Send>,
),
F: Fn(tokio::runtime::current_thread::Handle, Box<Future<Item = (), Error = ()> + Send>),
{
let (trigger, exit) = futures::sync::oneshot::channel();
let (handle_tx, handle_rx) = ::std::sync::mpsc::channel();
@@ -149,10 +151,13 @@ mod runtime_single_threaded_racy {
let (tx, rx) = futures::sync::oneshot::channel();
let handle = handle_rx.recv().unwrap();
spawn(handle, Box::new(futures::future::lazy(move || {
tx.send(()).unwrap();
Ok(())
})));
spawn(
handle,
Box::new(futures::future::lazy(move || {
tx.send(()).unwrap();
Ok(())
})),
);
// signal runtime thread to exit
trigger.send(()).unwrap();
@@ -165,12 +170,16 @@ mod runtime_single_threaded_racy {
#[test]
fn spawn() {
test(|handle, f| { handle.spawn(f).unwrap(); })
test(|handle, f| {
handle.spawn(f).unwrap();
})
}
#[test]
fn execute() {
test(|handle, f| { handle.execute(f).unwrap(); })
test(|handle, f| {
handle.execute(f).unwrap();
})
}
}
@@ -182,25 +191,28 @@ mod runtime_multi_threaded {
{
let _ = env_logger::try_init();
let mut runtime = tokio::runtime::Builder::new()
.build()
.unwrap();
let mut runtime = tokio::runtime::Builder::new().build().unwrap();
spawn(&mut runtime);
runtime.shutdown_on_idle().wait().unwrap();
}
#[test]
fn spawn() {
test(|rt| { rt.spawn(create_client_server_future()); });
test(|rt| {
rt.spawn(create_client_server_future());
});
}
#[test]
fn execute() {
test(|rt| { rt.executor().execute(create_client_server_future()).unwrap(); });
test(|rt| {
rt.executor()
.execute(create_client_server_future())
.unwrap();
});
}
}
#[test]
fn block_on_timer() {
use std::time::{Duration, Instant};
@@ -223,7 +235,7 @@ mod from_block_on {
fn test<F>(spawn: F)
where
F: Fn(Box<Future<Item=(), Error=()> + Send>) + Send + 'static,
F: Fn(Box<Future<Item = (), Error = ()> + Send>) + Send + 'static,
{
let cnt = Arc::new(Mutex::new(0));
let c = cnt.clone();
@@ -305,20 +317,23 @@ mod many {
const ITER: usize = 200;
fn test<F>(spawn: F)
where
F: Fn(&mut Runtime, Box<Future<Item=(), Error=()> + Send>),
F: Fn(&mut Runtime, Box<Future<Item = (), Error = ()> + Send>),
{
let cnt = Arc::new(Mutex::new(0));
let mut runtime = Runtime::new().unwrap();
for _ in 0..ITER {
let c = cnt.clone();
spawn(&mut runtime, Box::new(lazy(move || {
{
let mut x = c.lock().unwrap();
*x = 1 + *x;
}
Ok::<(), ()>(())
})));
spawn(
&mut runtime,
Box::new(lazy(move || {
{
let mut x = c.lock().unwrap();
*x = 1 + *x;
}
Ok::<(), ()>(())
})),
);
}
runtime.shutdown_on_idle().wait().unwrap();
@@ -327,26 +342,25 @@ mod many {
#[test]
fn spawn() {
test(|rt, f| { rt.spawn(f); })
test(|rt, f| {
rt.spawn(f);
})
}
#[test]
fn execute() {
test(|rt, f| {
rt.executor()
.execute(f)
.unwrap();
rt.executor().execute(f).unwrap();
})
}
}
mod from_block_on_all {
use super::*;
fn test<F>(spawn: F)
where
F: Fn(Box<Future<Item=(), Error=()> + Send>) + Send + 'static,
F: Fn(Box<Future<Item = (), Error = ()> + Send>) + Send + 'static,
{
let cnt = Arc::new(Mutex::new(0));
let c = cnt.clone();
@@ -387,19 +401,21 @@ mod from_block_on_all {
#[test]
fn spawn() {
test(|f| { tokio::spawn(f); })
test(|f| {
tokio::spawn(f);
})
}
}
mod nested_enter {
use super::*;
use tokio::runtime::current_thread;
use std::panic;
use tokio::runtime::current_thread;
fn test<F1, F2>(first: F1, nested: F2)
where
F1: Fn(Box<Future<Item=(), Error=()> + Send>) + Send + 'static,
F2: Fn(Box<Future<Item=(), Error=()> + Send>) + panic::UnwindSafe + Send + 'static,
F1: Fn(Box<Future<Item = (), Error = ()> + Send>) + Send + 'static,
F2: Fn(Box<Future<Item = (), Error = ()> + Send>) + panic::UnwindSafe + Send + 'static,
{
let panicked = Arc::new(Mutex::new(false));
let panicked2 = panicked.clone();
@@ -421,16 +437,18 @@ mod nested_enter {
}));
first(Box::new(lazy(move || {
panic::catch_unwind(move || {
nested(Box::new(lazy(|| { Ok::<(), ()>(()) })))
}).expect_err("nested should panic");
panic::catch_unwind(move || nested(Box::new(lazy(|| Ok::<(), ()>(())))))
.expect_err("nested should panic");
*panicked2.lock().unwrap() = true;
Ok::<(), ()>(())
})));
panic::set_hook(prev_hook);
assert!(*panicked.lock().unwrap(), "nested call should have panicked");
assert!(
*panicked.lock().unwrap(),
"nested call should have panicked"
);
}
fn threadpool_new() -> Runtime {
@@ -471,10 +489,7 @@ fn runtime_reactor_handle() {
#![allow(deprecated)]
use futures::Stream;
use std::net::{
TcpListener as StdListener,
TcpStream as StdStream,
};
use std::net::{TcpListener as StdListener, TcpStream as StdStream};
let rt = Runtime::new().unwrap();
@@ -484,10 +499,7 @@ fn runtime_reactor_handle() {
let addr = tk_listener.local_addr().unwrap();
// Spawn a thread since we are avoiding the runtime
let th = thread::spawn(|| {
for _ in tk_listener.incoming().take(1).wait() {
}
});
let th = thread::spawn(|| for _ in tk_listener.incoming().take(1).wait() {});
let _ = StdStream::connect(&addr).unwrap();
@@ -504,10 +516,14 @@ fn after_start_and_before_stop_is_called() {
let after_inner = after_start.clone();
let before_inner = before_stop.clone();
let runtime = tokio::runtime::Builder::new()
.after_start(move || { after_inner.clone().fetch_add(1, atomic::Ordering::Relaxed); })
.before_stop(move || { before_inner.clone().fetch_add(1, atomic::Ordering::Relaxed); })
.build()
.unwrap();
.after_start(move || {
after_inner.clone().fetch_add(1, atomic::Ordering::Relaxed);
})
.before_stop(move || {
before_inner.clone().fetch_add(1, atomic::Ordering::Relaxed);
})
.build()
.unwrap();
runtime.block_on_all(create_client_server_future()).unwrap();
+12 -15
View File
@@ -1,7 +1,7 @@
extern crate env_logger;
extern crate futures;
extern crate tokio;
extern crate tokio_io;
extern crate env_logger;
use tokio::prelude::*;
use tokio::timer::*;
@@ -31,7 +31,7 @@ fn timer_with_runtime() {
#[test]
fn starving() {
use futures::{task, Poll, Async};
use futures::{task, Async, Poll};
let _ = env_logger::try_init();
@@ -60,12 +60,11 @@ fn starving() {
let (tx, rx) = mpsc::channel();
tokio::run({
starve
.and_then(move |_ticks| {
assert!(Instant::now() >= when);
tx.send(()).unwrap();
Ok(())
})
starve.and_then(move |_ticks| {
assert!(Instant::now() >= when);
tx.send(()).unwrap();
Ok(())
})
});
rx.recv().unwrap();
@@ -82,13 +81,11 @@ fn deadline() {
#[allow(deprecated)]
tokio::run({
future::empty::<(), ()>()
.deadline(when)
.then(move |res| {
assert!(res.is_err());
tx.send(()).unwrap();
Ok(())
})
future::empty::<(), ()>().deadline(when).then(move |res| {
assert!(res.is_err());
tx.send(()).unwrap();
Ok(())
})
});
rx.recv().unwrap();
+4 -4
View File
@@ -2,15 +2,15 @@
#[macro_export]
macro_rules! await {
($e:expr) => {{
use $crate::std_await;
#[allow(unused_imports)]
use $crate::compat::forward::IntoAwaitable as IntoAwaitableForward;
#[allow(unused_imports)]
use $crate::compat::backward::IntoAwaitable as IntoAwaitableBackward;
#[allow(unused_imports)]
use $crate::compat::forward::IntoAwaitable as IntoAwaitableForward;
use $crate::std_await;
#[allow(unused_mut)]
let mut e = $e;
let e = e.into_awaitable();
std_await!(e)
}}
}};
}
+7 -13
View File
@@ -1,16 +1,9 @@
use futures::{Future, Poll};
use std::future::Future as StdFuture;
use std::pin::Pin;
use std::future::{
Future as StdFuture,
};
use std::ptr::NonNull;
use std::task::{
LocalWaker,
Poll as StdPoll,
UnsafeWake,
Waker,
};
use std::task::{LocalWaker, Poll as StdPoll, UnsafeWake, Waker};
/// Convert an 0.3 `Future` to an 0.1 `Future`.
#[derive(Debug)]
@@ -31,7 +24,8 @@ pub trait IntoAwaitable {
}
impl<T> IntoAwaitable for T
where T: StdFuture,
where
T: StdFuture,
{
type Awaitable = Self;
@@ -41,7 +35,8 @@ where T: StdFuture,
}
impl<T, Item, Error> Future for Compat<T>
where T: StdFuture<Output = Result<Item, Error>>,
where
T: StdFuture<Output = Result<Item, Error>>,
{
type Item = Item;
type Error = Error;
@@ -80,8 +75,7 @@ unsafe impl UnsafeWake for NoopWaker {
noop_waker()
}
unsafe fn drop_raw(&self) {
}
unsafe fn drop_raw(&self) {}
unsafe fn wake(&self) {
unimplemented!("async-await-preview currently only supports futures 0.1. Use the compatibility layer of futures 0.3 instead, if you want to use futures 0.3.");
+9 -9
View File
@@ -1,8 +1,7 @@
use futures::{Async, Future};
use futures::{Future, Async};
use std::marker::Unpin;
use std::future::Future as StdFuture;
use std::marker::Unpin;
use std::pin::Pin;
use std::task::{LocalWaker, Poll as StdPoll};
@@ -11,7 +10,7 @@ use std::task::{LocalWaker, Poll as StdPoll};
pub struct Compat<T>(T);
pub(crate) fn convert_poll<T, E>(poll: Result<Async<T>, E>) -> StdPoll<Result<T, E>> {
use futures::Async::{Ready, NotReady};
use futures::Async::{NotReady, Ready};
match poll {
Ok(Ready(val)) => StdPoll::Ready(Ok(val)),
@@ -21,9 +20,9 @@ pub(crate) fn convert_poll<T, E>(poll: Result<Async<T>, E>) -> StdPoll<Result<T,
}
pub(crate) fn convert_poll_stream<T, E>(
poll: Result<Async<Option<T>>, E>) -> StdPoll<Option<Result<T, E>>>
{
use futures::Async::{Ready, NotReady};
poll: Result<Async<Option<T>>, E>,
) -> StdPoll<Option<Result<T, E>>> {
use futures::Async::{NotReady, Ready};
match poll {
Ok(Ready(Some(val))) => StdPoll::Ready(Some(Ok(val))),
@@ -50,12 +49,13 @@ impl<T: Future + Unpin> IntoAwaitable for T {
}
impl<T> StdFuture for Compat<T>
where T: Future + Unpin
where
T: Future + Unpin,
{
type Output = Result<T::Item, T::Error>;
fn poll(mut self: Pin<&mut Self>, _lw: &LocalWaker) -> StdPoll<Self::Output> {
use futures::Async::{Ready, NotReady};
use futures::Async::{NotReady, Ready};
// TODO: wire in cx
+1 -1
View File
@@ -1,4 +1,4 @@
#![doc(hidden)]
pub mod forward;
pub mod backward;
pub mod forward;
+1 -2
View File
@@ -1,8 +1,7 @@
use tokio_io::AsyncWrite;
use std::io;
use std::future::Future;
use std::io;
use std::marker::Unpin;
use std::pin::Pin;
use std::task::{LocalWaker, Poll};
+1 -4
View File
@@ -19,10 +19,7 @@ impl<'a, T: ?Sized> Unpin for Read<'a, T> {}
impl<'a, T: AsyncRead + ?Sized> Read<'a, T> {
pub(super) fn new(reader: &'a mut T, buf: &'a mut [u8]) -> Read<'a, T> {
Read {
reader,
buf,
}
Read { reader, buf }
}
}
+2 -5
View File
@@ -20,10 +20,7 @@ impl<'a, T: ?Sized> Unpin for ReadExact<'a, T> {}
impl<'a, T: AsyncRead + ?Sized> ReadExact<'a, T> {
pub(super) fn new(reader: &'a mut T, buf: &'a mut [u8]) -> ReadExact<'a, T> {
ReadExact {
reader,
buf,
}
ReadExact { reader, buf }
}
}
@@ -47,7 +44,7 @@ impl<'a, T: AsyncRead + ?Sized> Future for ReadExact<'a, T> {
this.buf = rest;
}
if n == 0 {
return Poll::Ready(Err(eof()))
return Poll::Ready(Err(eof()));
}
}
+1 -4
View File
@@ -19,10 +19,7 @@ impl<'a, T: ?Sized> Unpin for Write<'a, T> {}
impl<'a, T: AsyncWrite + ?Sized> Write<'a, T> {
pub(super) fn new(writer: &'a mut T, buf: &'a [u8]) -> Write<'a, T> {
Write {
writer,
buf,
}
Write { writer, buf }
}
}
+2 -5
View File
@@ -20,10 +20,7 @@ impl<'a, T: ?Sized> Unpin for WriteAll<'a, T> {}
impl<'a, T: AsyncWrite + ?Sized> WriteAll<'a, T> {
pub(super) fn new(writer: &'a mut T, buf: &'a [u8]) -> WriteAll<'a, T> {
WriteAll {
writer,
buf,
}
WriteAll { writer, buf }
}
}
@@ -48,7 +45,7 @@ impl<'a, T: AsyncWrite + ?Sized> Future for WriteAll<'a, T> {
}
if n == 0 {
return Poll::Ready(Err(zero_write()))
return Poll::Ready(Err(zero_write()));
}
}
+5 -8
View File
@@ -4,9 +4,8 @@
arbitrary_self_types,
async_await,
await_macro,
futures_api,
)]
futures_api
)]
#![doc(html_root_url = "https://docs.rs/tokio-async-await/0.1.5")]
#![deny(missing_docs, missing_debug_implementations)]
#![cfg_attr(test, deny(warnings))]
@@ -23,12 +22,10 @@ macro_rules! try_ready {
($x:expr) => {
match $x {
std::task::Poll::Ready(Ok(x)) => x,
std::task::Poll::Ready(Err(e)) =>
return std::task::Poll::Ready(Err(e.into())),
std::task::Poll::Pending =>
return std::task::Poll::Pending,
std::task::Poll::Ready(Err(e)) => return std::task::Poll::Ready(Err(e.into())),
std::task::Poll::Pending => return std::task::Poll::Pending,
}
}
};
}
#[macro_use]
+1 -1
View File
@@ -30,7 +30,7 @@ impl<T: Sink + Unpin + ?Sized> Future for Send<'_, T> {
fn poll(mut self: Pin<&mut Self>, _lw: &task::LocalWaker) -> Poll<Self::Output> {
use crate::compat::forward::convert_poll;
use futures::AsyncSink::{Ready, NotReady};
use futures::AsyncSink::{NotReady, Ready};
if let Some(item) = self.item.take() {
match self.sink.start_send(item) {
+13 -16
View File
@@ -1,5 +1,5 @@
use BufStream;
use super::FromBufStream;
use BufStream;
use futures::{Future, Poll};
@@ -53,29 +53,26 @@ where
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
loop {
let res = self.stream.poll_buf()
.map_err(|err| {
let inner = Error::Stream(err);
CollectError { inner }
});
let res = self.stream.poll_buf().map_err(|err| {
let inner = Error::Stream(err);
CollectError { inner }
});
match try_ready!(res) {
Some(mut buf) => {
let builder = self.builder.as_mut().expect("cannot poll after done");
U::extend(builder, &mut buf, &self.stream.size_hint())
.map_err(|err| {
let inner = Error::Collect(err);
CollectError { inner }
})?;
U::extend(builder, &mut buf, &self.stream.size_hint()).map_err(|err| {
let inner = Error::Collect(err);
CollectError { inner }
})?;
}
None => {
let builder = self.builder.take().expect("cannot poll after done");
let value = U::build(builder)
.map_err(|err| {
let inner = Error::Collect(err);
CollectError { inner }
})?;
let value = U::build(builder).map_err(|err| {
let inner = Error::Collect(err);
CollectError { inner }
})?;
return Ok(value.into());
}
}
+4 -2
View File
@@ -43,7 +43,9 @@ pub trait FromBufStream<T: Buf>: Sized {
/// Error returned from collecting into a `Vec<u8>`
#[derive(Debug)]
pub struct CollectVecError { _p: () }
pub struct CollectVecError {
_p: (),
}
impl<T: Buf> FromBufStream<T> for Vec<u8> {
type Builder = Vec<u8>;
@@ -70,7 +72,7 @@ impl<T: Buf> FromBufStream<T> for Vec<u8> {
Some(upper) if upper <= 64 => {
reserve = upper as usize;
}
_ => {},
_ => {}
}
// hint.lower() represents the minimum amount of data that will be
+4 -4
View File
@@ -40,10 +40,10 @@ where
return Err(LimitError { inner: None });
}
let res = self.stream.poll_buf()
.map_err(|err| {
LimitError { inner: Some(err) }
});
let res = self
.stream
.poll_buf()
.map_err(|err| LimitError { inner: Some(err) });
match res {
Ok(Ready(Some(ref buf))) => {
+5 -7
View File
@@ -16,21 +16,21 @@ extern crate either;
#[macro_use]
extern crate futures;
pub mod errors;
#[cfg(feature = "ext")]
pub mod ext;
pub mod errors;
mod size_hint;
mod str;
pub use self::size_hint::SizeHint;
#[doc(inline)]
#[cfg(feature = "ext")]
pub use ext::BufStreamExt;
pub use self::size_hint::SizeHint;
use futures::Poll;
use bytes::{Buf, Bytes, BytesMut};
use std::io;
use errors::internal::Never;
use futures::Poll;
use std::io;
/// An asynchronous stream of bytes.
///
@@ -151,9 +151,7 @@ impl BufStream for BytesMut {
}
}
fn poll_bytes<T: Default>(buf: &mut T)
-> Poll<Option<io::Cursor<T>>, Never>
{
fn poll_bytes<T: Default>(buf: &mut T) -> Poll<Option<io::Cursor<T>>, Never> {
use std::mem;
let bytes = mem::replace(buf, Default::default());
+1 -1
View File
@@ -1,5 +1,5 @@
use BufStream;
use errors::internal::Never;
use BufStream;
use futures::Poll;
+2 -3
View File
@@ -1,11 +1,10 @@
extern crate tokio_buf;
extern crate bytes;
extern crate futures;
extern crate tokio_buf;
use tokio_buf::{BufStream, SizeHint};
use bytes::Buf;
use futures::Async::*;
use tokio_buf::{BufStream, SizeHint};
#[macro_use]
mod support;
+19 -32
View File
@@ -1,13 +1,13 @@
#![cfg(feature = "ext")]
extern crate tokio_buf;
extern crate bytes;
extern crate futures;
extern crate tokio_buf;
use tokio_buf::{BufStream, BufStreamExt};
use futures::Future;
use futures::Async::*;
use bytes::Buf;
use futures::Async::*;
use futures::Future;
use tokio_buf::{BufStream, BufStreamExt};
#[macro_use]
mod support;
@@ -27,8 +27,7 @@ fn chain() {
assert_none!(bs.poll_buf());
// Chain multi with multi
let mut bs = list(&["foo", "bar"])
.chain(list(&["baz", "bok"]));
let mut bs = list(&["foo", "bar"]).chain(list(&["baz", "bok"]));
assert_buf_eq!(bs.poll_buf(), "foo");
assert_buf_eq!(bs.poll_buf(), "bar");
@@ -38,11 +37,7 @@ fn chain() {
// Chain includes a not ready call
//
let mut bs = new_mock(&[
Ok(Ready("foo")),
Ok(NotReady),
Ok(Ready("bar"))
]).chain(one("baz"));
let mut bs = new_mock(&[Ok(Ready("foo")), Ok(NotReady), Ok(Ready("bar"))]).chain(one("baz"));
assert_buf_eq!(bs.poll_buf(), "foo");
assert_not_ready!(bs.poll_buf());
@@ -62,8 +57,7 @@ fn collect_vec() {
//
let bs = one("hello world");
let vec: Vec<u8> = bs.collect()
.wait().unwrap();
let vec: Vec<u8> = bs.collect().wait().unwrap();
assert_eq!(vec, b"hello world");
assert_eq!(vec.capacity(), 64);
@@ -73,8 +67,7 @@ fn collect_vec() {
let mut bs = one("hello world");
bs.size_hint.set_lower(11);
let vec: Vec<u8> = bs.collect()
.wait().unwrap();
let vec: Vec<u8> = bs.collect().wait().unwrap();
assert_eq!(vec, b"hello world");
assert_eq!(vec.capacity(), 64);
@@ -84,8 +77,7 @@ fn collect_vec() {
let mut bs = one("hello world");
bs.size_hint.set_lower(10);
let vec: Vec<u8> = bs.collect()
.wait().unwrap();
let vec: Vec<u8> = bs.collect().wait().unwrap();
assert_eq!(vec, b"hello world");
assert_eq!(vec.capacity(), 64);
@@ -94,8 +86,7 @@ fn collect_vec() {
//
let bs = list(&["hello", " ", "world", ", one two three"]);
let vec: Vec<u8> = bs.collect()
.wait().unwrap();
let vec: Vec<u8> = bs.collect().wait().unwrap();
assert_eq!(vec, b"hello world, one two three");
}
@@ -109,42 +100,38 @@ fn limit() {
let res = one("hello world")
.limit(100)
.collect::<Vec<_>>()
.wait().unwrap();
.wait()
.unwrap();
assert_eq!(res, b"hello world");
let res = list(&["hello", " ", "world"])
.limit(100)
.collect::<Vec<_>>()
.wait().unwrap();
.wait()
.unwrap();
assert_eq!(res, b"hello world");
let res = list(&["hello", " ", "world"])
.limit(11)
.collect::<Vec<_>>()
.wait().unwrap();
.wait()
.unwrap();
assert_eq!(res, b"hello world");
// Limited
let res = one("hello world")
.limit(5)
.collect::<Vec<_>>()
.wait();
let res = one("hello world").limit(5).collect::<Vec<_>>().wait();
assert!(res.is_err());
let res = one("hello world")
.limit(10)
.collect::<Vec<_>>()
.wait();
let res = one("hello world").limit(10).collect::<Vec<_>>().wait();
assert!(res.is_err());
let mut bs = list(&["hello", " ", "world"])
.limit(9);
let mut bs = list(&["hello", " ", "world"]).limit(9);
assert_buf_eq!(bs.poll_buf(), "hello");
assert_buf_eq!(bs.poll_buf(), " ");
+5 -6
View File
@@ -1,13 +1,13 @@
#![allow(unused)]
extern crate tokio_buf;
extern crate bytes;
extern crate futures;
extern crate tokio_buf;
use tokio_buf::{BufStream, SizeHint};
use bytes::Buf;
use futures::Poll;
use futures::Async::*;
use futures::Poll;
use tokio_buf::{BufStream, SizeHint};
use std::collections::VecDeque;
use std::io::Cursor;
@@ -32,7 +32,7 @@ macro_rules! assert_none {
Ok(Ready(None)) => {}
actual => panic!("expected None; actual = {:?}", actual),
}
}
};
}
macro_rules! assert_not_ready {
@@ -41,7 +41,7 @@ macro_rules! assert_not_ready {
Ok(NotReady) => {}
actual => panic!("expected NotReady; actual = {:?}", actual),
}
}
};
}
// ===== Test utils =====
@@ -130,4 +130,3 @@ impl Buf for MockBuf {
self.data.advance(cnt)
}
}
+5 -3
View File
@@ -1,6 +1,6 @@
use bytes::{Bytes, BufMut, BytesMut};
use tokio_io::_tokio_codec::{Encoder, Decoder};
use bytes::{BufMut, Bytes, BytesMut};
use std::io;
use tokio_io::_tokio_codec::{Decoder, Encoder};
/// A simple `Codec` implementation that just ships bytes around.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
@@ -8,7 +8,9 @@ pub struct BytesCodec(());
impl BytesCodec {
/// Creates a new `BytesCodec` for shipping around raw bytes.
pub fn new() -> BytesCodec { BytesCodec(()) }
pub fn new() -> BytesCodec {
BytesCodec(())
}
}
impl Decoder for BytesCodec {
+1 -8
View File
@@ -19,14 +19,7 @@ extern crate tokio_io;
mod bytes_codec;
mod lines_codec;
pub use tokio_io::_tokio_codec::{
Decoder,
Encoder,
Framed,
FramedParts,
FramedRead,
FramedWrite,
};
pub use tokio_io::_tokio_codec::{Decoder, Encoder, Framed, FramedParts, FramedRead, FramedWrite};
pub use bytes_codec::BytesCodec;
pub use lines_codec::LinesCodec;
+4 -6
View File
@@ -1,6 +1,6 @@
use bytes::{BufMut, BytesMut};
use tokio_io::_tokio_codec::{Encoder, Decoder};
use std::{cmp, io, str, usize};
use tokio_io::_tokio_codec::{Decoder, Encoder};
/// A simple `Codec` implementation that splits up data into lines.
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
@@ -103,10 +103,8 @@ impl LinesCodec {
}
fn utf8(buf: &[u8]) -> Result<&str, io::Error> {
str::from_utf8(buf).map_err(|_|
io::Error::new(
io::ErrorKind::InvalidData,
"Unable to decode input as UTF8"))
str::from_utf8(buf)
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Unable to decode input as UTF8"))
}
fn without_carriage_return(s: &[u8]) -> &[u8] {
@@ -153,7 +151,7 @@ impl Decoder for LinesCodec {
self.is_discarding = true;
Err(io::Error::new(
io::ErrorKind::Other,
"line length limit exceeded"
"line length limit exceeded",
))
} else {
// We didn't find a line or reach the length limit, so the next
+33 -9
View File
@@ -1,8 +1,8 @@
extern crate tokio_codec;
extern crate bytes;
extern crate tokio_codec;
use bytes::{BytesMut, Bytes, BufMut};
use tokio_codec::{BytesCodec, LinesCodec, Decoder, Encoder};
use bytes::{BufMut, Bytes, BytesMut};
use tokio_codec::{BytesCodec, Decoder, Encoder, LinesCodec};
#[test]
fn bytes_decoder() {
@@ -27,13 +27,17 @@ fn bytes_encoder() {
const INLINE_CAP: usize = 4 * 4 - 1;
let mut buf = BytesMut::new();
codec.encode(Bytes::from_static(&[0; INLINE_CAP + 1]), &mut buf).unwrap();
codec
.encode(Bytes::from_static(&[0; INLINE_CAP + 1]), &mut buf)
.unwrap();
// Default capacity of Framed Read
const INITIAL_CAPACITY: usize = 8 * 1024;
let mut buf = BytesMut::with_capacity(INITIAL_CAPACITY);
codec.encode(Bytes::from_static(&[0; INITIAL_CAPACITY + 1]), &mut buf).unwrap();
codec
.encode(Bytes::from_static(&[0; INITIAL_CAPACITY + 1]), &mut buf)
.unwrap();
}
#[test]
@@ -68,17 +72,32 @@ fn lines_decoder_max_length() {
assert!(codec.decode(buf).is_err());
let line = codec.decode(buf).unwrap().unwrap();
assert!(line.len() <= MAX_LENGTH, "{:?}.len() <= {:?}", line, MAX_LENGTH);
assert!(
line.len() <= MAX_LENGTH,
"{:?}.len() <= {:?}",
line,
MAX_LENGTH
);
assert_eq!("line 2", line);
assert!(codec.decode(buf).is_err());
let line = codec.decode(buf).unwrap().unwrap();
assert!(line.len() <= MAX_LENGTH, "{:?}.len() <= {:?}", line, MAX_LENGTH);
assert!(
line.len() <= MAX_LENGTH,
"{:?}.len() <= {:?}",
line,
MAX_LENGTH
);
assert_eq!("line 4", line);
let line = codec.decode(buf).unwrap().unwrap();
assert!(line.len() <= MAX_LENGTH, "{:?}.len() <= {:?}", line, MAX_LENGTH);
assert!(
line.len() <= MAX_LENGTH,
"{:?}.len() <= {:?}",
line,
MAX_LENGTH
);
assert_eq!("", line);
assert_eq!(None, codec.decode(buf).unwrap());
@@ -87,7 +106,12 @@ fn lines_decoder_max_length() {
assert_eq!(None, codec.decode(buf).unwrap());
let line = codec.decode_eof(buf).unwrap().unwrap();
assert!(line.len() <= MAX_LENGTH, "{:?}.len() <= {:?}", line, MAX_LENGTH);
assert!(
line.len() <= MAX_LENGTH,
"{:?}.len() <= {:?}",
line,
MAX_LENGTH
);
assert_eq!("\rk", line);
assert_eq!(None, codec.decode(buf).unwrap());
+10 -10
View File
@@ -1,13 +1,13 @@
extern crate tokio_codec;
extern crate tokio_io;
extern crate bytes;
extern crate futures;
extern crate tokio_codec;
extern crate tokio_io;
use futures::{Stream, Future};
use bytes::{Buf, BufMut, BytesMut, IntoBuf};
use futures::{Future, Stream};
use std::io::{self, Read};
use tokio_codec::{Framed, FramedParts, Decoder, Encoder};
use tokio_codec::{Decoder, Encoder, Framed, FramedParts};
use tokio_io::AsyncRead;
use bytes::{BytesMut, Buf, BufMut, IntoBuf};
const INITIAL_CAPACITY: usize = 8 * 1024;
@@ -45,8 +45,10 @@ struct DontReadIntoThis;
impl Read for DontReadIntoThis {
fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
Err(io::Error::new(io::ErrorKind::Other,
"Read into something you weren't supposed to."))
Err(io::Error::new(
io::ErrorKind::Other,
"Read into something you weren't supposed to.",
))
}
}
@@ -61,9 +63,7 @@ fn can_read_from_existing_buf() {
let num = framed
.into_future()
.map(|(first_num, _)| {
first_num.unwrap()
})
.map(|(first_num, _)| first_num.unwrap())
.wait()
.map_err(|e| e.0)
.unwrap();
+7 -8
View File
@@ -1,17 +1,17 @@
extern crate tokio_codec;
extern crate tokio_io;
extern crate bytes;
extern crate futures;
extern crate tokio_codec;
extern crate tokio_io;
use tokio_codec::{Decoder, FramedRead};
use tokio_io::AsyncRead;
use tokio_codec::{FramedRead, Decoder};
use bytes::{BytesMut, Buf, IntoBuf};
use bytes::{Buf, BytesMut, IntoBuf};
use futures::Async::{NotReady, Ready};
use futures::Stream;
use futures::Async::{Ready, NotReady};
use std::io::{self, Read};
use std::collections::VecDeque;
use std::io::{self, Read};
macro_rules! mock {
($($x:expr,)*) => {{
@@ -212,5 +212,4 @@ impl Read for Mock {
}
}
impl AsyncRead for Mock {
}
impl AsyncRead for Mock {}
+6 -6
View File
@@ -1,16 +1,16 @@
extern crate tokio_codec;
extern crate tokio_io;
extern crate bytes;
extern crate futures;
extern crate tokio_codec;
extern crate tokio_io;
use tokio_io::AsyncWrite;
use tokio_codec::{Encoder, FramedWrite};
use tokio_io::AsyncWrite;
use futures::{Sink, Poll};
use bytes::{BytesMut, BufMut};
use bytes::{BufMut, BytesMut};
use futures::{Poll, Sink};
use std::io::{self, Write};
use std::collections::VecDeque;
use std::io::{self, Write};
macro_rules! mock {
($($x:expr,)*) => {{
+70 -84
View File
@@ -32,19 +32,19 @@ mod scheduler;
use self::scheduler::Scheduler;
use tokio_executor::park::{Park, ParkThread, Unpark};
use tokio_executor::{Enter, SpawnError};
use tokio_executor::park::{Park, Unpark, ParkThread};
use futures::future::{ExecuteError, ExecuteErrorKind, Executor};
use futures::{executor, Async, Future};
use futures::future::{Executor, ExecuteError, ExecuteErrorKind};
use std::fmt;
use std::cell::Cell;
use std::error::Error;
use std::fmt;
use std::rc::Rc;
use std::sync::{atomic, mpsc, Arc};
use std::time::{Duration, Instant};
use std::thread;
use std::time::{Duration, Instant};
/// Executes tasks on the current thread
pub struct CurrentThread<P: Park = ParkThread> {
@@ -86,7 +86,7 @@ pub struct TaskExecutor {
/// Returned by the `turn` function.
#[derive(Debug)]
pub struct Turn {
polled: bool
polled: bool,
}
impl Turn {
@@ -194,7 +194,7 @@ struct CurrentRunner {
id: Cell<Option<u64>>,
}
thread_local!{
thread_local! {
/// Current thread's task runner. This is set in `TaskRunner::with`
static CURRENT: CurrentRunner = CurrentRunner {
spawn: Cell::new(None),
@@ -202,7 +202,7 @@ thread_local!{
}
}
thread_local!{
thread_local! {
/// Unique ID to assign to each new executor launched on this thread.
///
/// The unique ID is used to determine if the currently running executor matches the one
@@ -226,7 +226,8 @@ thread_local!{
/// [`CurrentThread`]: struct.CurrentThread.html
/// [mod]: index.html
pub fn block_on_all<F>(future: F) -> Result<F::Item, F::Error>
where F: Future,
where
F: Future,
{
let mut current_thread = CurrentThread::new();
@@ -250,7 +251,8 @@ where F: Future,
///
/// [`tokio::spawn`]: ../fn.spawn.html
pub fn spawn<F>(future: F)
where F: Future<Item = (), Error = ()> + 'static
where
F: Future<Item = (), Error = ()> + 'static,
{
TaskExecutor::current()
.spawn_local(Box::new(future))
@@ -316,7 +318,8 @@ impl<P: Park> CurrentThread<P> {
///
/// This internally queues the future to be executed once `run` is called.
pub fn spawn<F>(&mut self, future: F) -> &mut Self
where F: Future<Item = (), Error = ()> + 'static,
where
F: Future<Item = (), Error = ()> + 'static,
{
self.borrow().spawn_local(Box::new(future), false);
self
@@ -335,41 +338,33 @@ impl<P: Park> CurrentThread<P> {
///
/// The caller is responsible for ensuring that other spawned futures
/// complete execution.
pub fn block_on<F>(&mut self, future: F)
-> Result<F::Item, BlockError<F::Error>>
where F: Future
pub fn block_on<F>(&mut self, future: F) -> Result<F::Item, BlockError<F::Error>>
where
F: Future,
{
let mut enter = tokio_executor::enter()
.expect("failed to start `current_thread::Runtime`");
let mut enter = tokio_executor::enter().expect("failed to start `current_thread::Runtime`");
self.enter(&mut enter).block_on(future)
}
/// Run the executor to completion, blocking the thread until **all**
/// spawned futures have completed.
pub fn run(&mut self) -> Result<(), RunError> {
let mut enter = tokio_executor::enter()
.expect("failed to start `current_thread::Runtime`");
let mut enter = tokio_executor::enter().expect("failed to start `current_thread::Runtime`");
self.enter(&mut enter).run()
}
/// Run the executor to completion, blocking the thread until all
/// spawned futures have completed **or** `duration` time has elapsed.
pub fn run_timeout(&mut self, duration: Duration)
-> Result<(), RunTimeoutError>
{
let mut enter = tokio_executor::enter()
.expect("failed to start `current_thread::Runtime`");
pub fn run_timeout(&mut self, duration: Duration) -> Result<(), RunTimeoutError> {
let mut enter = tokio_executor::enter().expect("failed to start `current_thread::Runtime`");
self.enter(&mut enter).run_timeout(duration)
}
/// Perform a single iteration of the event loop.
///
/// This function blocks the current thread even if the executor is idle.
pub fn turn(&mut self, duration: Option<Duration>)
-> Result<Turn, TurnError>
{
let mut enter = tokio_executor::enter()
.expect("failed to start `current_thread::Runtime`");
pub fn turn(&mut self, duration: Option<Duration>) -> Result<Turn, TurnError> {
let mut enter = tokio_executor::enter().expect("failed to start `current_thread::Runtime`");
self.enter(&mut enter).turn(duration)
}
@@ -440,7 +435,10 @@ impl<P: Park> fmt::Debug for CurrentThread<P> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("CurrentThread")
.field("scheduler", &self.scheduler)
.field("num_futures", &self.num_futures.load(atomic::Ordering::SeqCst))
.field(
"num_futures",
&self.num_futures.load(atomic::Ordering::SeqCst),
)
.finish()
}
}
@@ -452,7 +450,8 @@ impl<'a, P: Park> Entered<'a, P> {
///
/// This internally queues the future to be executed once `run` is called.
pub fn spawn<F>(&mut self, future: F) -> &mut Self
where F: Future<Item = (), Error = ()> + 'static,
where
F: Future<Item = (), Error = ()> + 'static,
{
self.executor.borrow().spawn_local(Box::new(future), false);
self
@@ -471,17 +470,18 @@ impl<'a, P: Park> Entered<'a, P> {
///
/// The caller is responsible for ensuring that other spawned futures
/// complete execution.
pub fn block_on<F>(&mut self, future: F)
-> Result<F::Item, BlockError<F::Error>>
where F: Future
pub fn block_on<F>(&mut self, future: F) -> Result<F::Item, BlockError<F::Error>>
where
F: Future,
{
let mut future = executor::spawn(future);
let notify = self.executor.scheduler.notify();
loop {
let res = self.executor.borrow().enter(self.enter, || {
future.poll_future_notify(&notify, 0)
});
let res = self
.executor
.borrow()
.enter(self.enter, || future.poll_future_notify(&notify, 0));
match res {
Ok(Async::Ready(e)) => return Ok(e),
@@ -500,24 +500,19 @@ impl<'a, P: Park> Entered<'a, P> {
/// Run the executor to completion, blocking the thread until **all**
/// spawned futures have completed.
pub fn run(&mut self) -> Result<(), RunError> {
self.run_timeout2(None)
.map_err(|_| RunError { _p: () })
self.run_timeout2(None).map_err(|_| RunError { _p: () })
}
/// Run the executor to completion, blocking the thread until all
/// spawned futures have completed **or** `duration` time has elapsed.
pub fn run_timeout(&mut self, duration: Duration)
-> Result<(), RunTimeoutError>
{
pub fn run_timeout(&mut self, duration: Duration) -> Result<(), RunTimeoutError> {
self.run_timeout2(Some(duration))
}
/// Perform a single iteration of the event loop.
///
/// This function blocks the current thread even if the executor is idle.
pub fn turn(&mut self, duration: Option<Duration>)
-> Result<Turn, TurnError>
{
pub fn turn(&mut self, duration: Option<Duration>) -> Result<Turn, TurnError> {
let res = if self.executor.scheduler.has_pending_futures() {
self.executor.park.park_timeout(Duration::from_millis(0))
} else {
@@ -546,9 +541,7 @@ impl<'a, P: Park> Entered<'a, P> {
&mut self.executor.park
}
fn run_timeout2(&mut self, dur: Option<Duration>)
-> Result<(), RunTimeoutError>
{
fn run_timeout2(&mut self, dur: Option<Duration>) -> Result<(), RunTimeoutError> {
if self.executor.is_idle() {
// Nothing to do
return Ok(());
@@ -606,10 +599,9 @@ impl<'a, P: Park> Entered<'a, P> {
}
// After any pending futures were scheduled, do the actual tick
borrow.scheduler.tick(
borrow.id,
&mut *self.enter,
borrow.num_futures)
borrow
.scheduler
.tick(borrow.id, &mut *self.enter, borrow.num_futures)
}
}
@@ -680,7 +672,8 @@ impl Handle {
return Err(SpawnError::shutdown());
}
self.sender.send(Box::new(future))
self.sender
.send(Box::new(future))
.expect("CurrentThread does not exist anymore");
// use 0 for the id, CurrentThread does not make use of it
self.notify.notify(0);
@@ -722,51 +715,44 @@ impl TaskExecutor {
/// Get the current executor's thread-local ID.
fn id(&self) -> Option<u64> {
CURRENT.with(|current| {
current.id.get()
})
CURRENT.with(|current| current.id.get())
}
/// Spawn a future onto the current `CurrentThread` instance.
pub fn spawn_local(&mut self, future: Box<Future<Item = (), Error = ()>>)
-> Result<(), SpawnError>
{
CURRENT.with(|current| {
match current.spawn.get() {
Some(spawn) => {
unsafe { (*spawn).spawn_local(future, false) };
Ok(())
}
None => {
Err(SpawnError::shutdown())
}
pub fn spawn_local(
&mut self,
future: Box<Future<Item = (), Error = ()>>,
) -> Result<(), SpawnError> {
CURRENT.with(|current| match current.spawn.get() {
Some(spawn) => {
unsafe { (*spawn).spawn_local(future, false) };
Ok(())
}
None => Err(SpawnError::shutdown()),
})
}
}
impl tokio_executor::Executor for TaskExecutor {
fn spawn(&mut self, future: Box<Future<Item = (), Error = ()> + Send>)
-> Result<(), SpawnError>
{
fn spawn(
&mut self,
future: Box<Future<Item = (), Error = ()> + Send>,
) -> Result<(), SpawnError> {
self.spawn_local(future)
}
}
impl<F> Executor<F> for TaskExecutor
where F: Future<Item = (), Error = ()> + 'static
where
F: Future<Item = (), Error = ()> + 'static,
{
fn execute(&self, future: F) -> Result<(), ExecuteError<F>> {
CURRENT.with(|current| {
match current.spawn.get() {
Some(spawn) => {
unsafe { (*spawn).spawn_local(Box::new(future), false) };
Ok(())
}
None => {
Err(ExecuteError::new(ExecuteErrorKind::Shutdown, future))
}
CURRENT.with(|current| match current.spawn.get() {
Some(spawn) => {
unsafe { (*spawn).spawn_local(Box::new(future), false) };
Ok(())
}
None => Err(ExecuteError::new(ExecuteErrorKind::Shutdown, future)),
})
}
}
@@ -775,13 +761,12 @@ where F: Future<Item = (), Error = ()> + 'static
impl<'a, U: Unpark> Borrow<'a, U> {
fn enter<F, R>(&mut self, _: &mut Enter, f: F) -> R
where F: FnOnce() -> R,
where
F: FnOnce() -> R,
{
CURRENT.with(|current| {
current.id.set(Some(self.id));
current.set_spawn(self, || {
f()
})
current.set_spawn(self, || f())
})
}
}
@@ -801,7 +786,8 @@ impl<'a, U: Unpark> SpawnLocal for Borrow<'a, U> {
impl CurrentRunner {
fn set_spawn<F, R>(&self, spawn: &mut SpawnLocal, f: F) -> R
where F: FnOnce() -> R
where
F: FnOnce() -> R,
{
struct Reset<'a>(&'a CurrentRunner);
+16 -20
View File
@@ -1,20 +1,20 @@
use super::Borrow;
use tokio_executor::Enter;
use tokio_executor::park::Unpark;
use tokio_executor::Enter;
use futures::{Future, Async};
use futures::executor::{self, Spawn, UnsafeNotify, NotifyHandle};
use futures::executor::{self, NotifyHandle, Spawn, UnsafeNotify};
use futures::{Async, Future};
use std::cell::UnsafeCell;
use std::fmt::{self, Debug};
use std::marker::PhantomData;
use std::mem;
use std::ptr;
use std::sync::atomic::Ordering::{Relaxed, SeqCst, Acquire, Release, AcqRel};
use std::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release, SeqCst};
use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize};
use std::sync::{Arc, Weak};
use std::usize;
use std::thread;
use std::marker::PhantomData;
use std::usize;
/// A generic task-aware scheduler.
///
@@ -135,7 +135,8 @@ pub struct Scheduled<'a, U: 'a> {
}
impl<U> Scheduler<U>
where U: Unpark,
where
U: Unpark,
{
/// Constructs a new, empty `Scheduler`
///
@@ -200,9 +201,7 @@ where U: Unpark,
pub fn has_pending_futures(&mut self) -> bool {
// See function definition for why the unsafe is needed and
// correctly used here
unsafe {
self.inner.has_pending_futures()
}
unsafe { self.inner.has_pending_futures() }
}
/// Advance the scheduler state, returning `true` if any futures were
@@ -210,11 +209,9 @@ where U: Unpark,
///
/// This function should be called whenever the caller is notified via a
/// wakeup.
pub fn tick(&mut self, eid: u64, enter: &mut Enter, num_futures: &AtomicUsize) -> bool
{
pub fn tick(&mut self, eid: u64, enter: &mut Enter, num_futures: &AtomicUsize) -> bool {
let mut ret = false;
let tick = self.inner.tick_num.fetch_add(1, SeqCst)
.wrapping_add(1);
let tick = self.inner.tick_num.fetch_add(1, SeqCst).wrapping_add(1);
loop {
let node = match unsafe { self.inner.dequeue(Some(tick)) } {
@@ -246,7 +243,7 @@ where U: Unpark,
let node = ptr2arc(node);
assert!((*node.next_all.get()).is_null());
assert!((*node.prev_all.get()).is_null());
continue
continue;
};
// We're going to need to be very careful if the `poll`
@@ -369,8 +366,7 @@ impl Task {
impl fmt::Debug for Task {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("Task")
.finish()
fmt.debug_struct("Task").finish()
}
}
@@ -580,7 +576,7 @@ impl<U> List<U> {
self.len += 1;
return ptr
return ptr;
}
/// Pop an element from the front of the list
@@ -632,7 +628,7 @@ impl<U> List<U> {
self.len -= 1;
return node
return node;
}
}
@@ -749,7 +745,7 @@ impl<U> Drop for Node<U> {
fn arc2ptr<T>(ptr: Arc<T>) -> *const T {
let addr = &*ptr as *const T;
mem::forget(ptr);
return addr
return addr;
}
unsafe fn ptr2arc<T>(ptr: *const T) -> Arc<T> {
+155 -120
View File
@@ -1,6 +1,6 @@
extern crate futures;
extern crate tokio_current_thread;
extern crate tokio_executor;
extern crate futures;
use tokio_current_thread::{block_on_all, CurrentThread};
@@ -10,8 +10,8 @@ use std::rc::Rc;
use std::thread;
use std::time::Duration;
use futures::task;
use futures::future::{self, lazy};
use futures::task;
// This is not actually unused --- we need this trait to be in scope for
// the tests that sue TaskExecutor::current().execute(). The compiler
// doesn't realise that.
@@ -22,7 +22,7 @@ use futures::sync::oneshot;
mod from_block_on_all {
use super::*;
fn test<F: Fn(Box<Future<Item=(), Error=()>>) + 'static>(spawn: F) {
fn test<F: Fn(Box<Future<Item = (), Error = ()>>) + 'static>(spawn: F) {
let cnt = Rc::new(Cell::new(0));
let c = cnt.clone();
@@ -36,7 +36,8 @@ mod from_block_on_all {
})));
Ok::<_, ()>("hello")
})).unwrap();
}))
.unwrap();
assert_eq!(2, cnt.get());
assert_eq!(msg, "hello");
@@ -72,7 +73,8 @@ fn block_waits() {
block_on_all(rx.then(move |_| {
cnt.set(1 + cnt.get());
Ok::<_, ()>(())
})).unwrap();
}))
.unwrap();
assert_eq!(1, cnt2.get());
}
@@ -100,11 +102,14 @@ fn spawn_many() {
mod does_not_set_global_executor_by_default {
use super::*;
fn test<F: Fn(Box<Future<Item=(), Error=()> + Send>) -> Result<(), E> + 'static, E>(spawn: F) {
fn test<F: Fn(Box<Future<Item = (), Error = ()> + Send>) -> Result<(), E> + 'static, E>(
spawn: F,
) {
block_on_all(lazy(|| {
spawn(Box::new(lazy(|| ok()))).unwrap_err();
ok()
})).unwrap()
}))
.unwrap()
}
#[test]
@@ -123,20 +128,22 @@ mod from_block_on_future {
use super::*;
fn test<F: Fn(Box<Future<Item = (), Error = ()>>)>(spawn: F) {
let cnt = Rc::new(Cell::new(0));
let cnt = Rc::new(Cell::new(0));
let mut tokio_current_thread = CurrentThread::new();
tokio_current_thread.block_on(lazy(|| {
let cnt = cnt.clone();
tokio_current_thread
.block_on(lazy(|| {
let cnt = cnt.clone();
spawn(Box::new(lazy(move || {
cnt.set(1 + cnt.get());
Ok(())
})));
spawn(Box::new(lazy(move || {
cnt.set(1 + cnt.get());
Ok(())
})));
Ok::<_, ()>(())
})).unwrap();
Ok::<_, ()>(())
}))
.unwrap();
tokio_current_thread.run().unwrap();
@@ -150,7 +157,11 @@ mod from_block_on_future {
#[test]
fn execute() {
test(|f| { tokio_current_thread::TaskExecutor::current().execute(f).unwrap(); });
test(|f| {
tokio_current_thread::TaskExecutor::current()
.execute(f)
.unwrap();
});
}
}
@@ -170,8 +181,8 @@ mod outstanding_tasks_are_dropped_when_executor_is_dropped {
fn test<F, G>(spawn: F, dotspawn: G)
where
F: Fn(Box<Future<Item=(), Error=()>>) + 'static,
G: Fn(&mut CurrentThread, Box<Future<Item=(), Error=()>>)
F: Fn(Box<Future<Item = (), Error = ()>>) + 'static,
G: Fn(&mut CurrentThread, Box<Future<Item = (), Error = ()>>),
{
let mut rc = Rc::new(());
@@ -189,10 +200,12 @@ mod outstanding_tasks_are_dropped_when_executor_is_dropped {
let mut tokio_current_thread = CurrentThread::new();
tokio_current_thread.block_on(lazy(|| {
spawn(Box::new(Never(rc.clone())));
Ok::<_, ()>(())
})).unwrap();
tokio_current_thread
.block_on(lazy(|| {
spawn(Box::new(Never(rc.clone())));
Ok::<_, ()>(())
}))
.unwrap();
drop(tokio_current_thread);
@@ -202,12 +215,15 @@ mod outstanding_tasks_are_dropped_when_executor_is_dropped {
#[test]
fn spawn() {
test(tokio_current_thread::spawn, |rt, f| { rt.spawn(f); })
test(tokio_current_thread::spawn, |rt, f| {
rt.spawn(f);
})
}
#[test]
fn execute() {
test(|f| {
test(
|f| {
tokio_current_thread::TaskExecutor::current()
.execute(f)
.unwrap();
@@ -216,7 +232,9 @@ mod outstanding_tasks_are_dropped_when_executor_is_dropped {
// `futures::Executor`, so we'll call `.spawn(...)` rather than
// `.execute(...)` for now. If `CurrentThread` is changed to
// implement Executor, change this to `.execute(...).unwrap()`.
|rt, f| { rt.spawn(f); }
|rt, f| {
rt.spawn(f);
},
);
}
}
@@ -225,12 +243,11 @@ mod outstanding_tasks_are_dropped_when_executor_is_dropped {
#[should_panic]
fn nesting_run() {
block_on_all(lazy(|| {
block_on_all(lazy(|| {
ok()
})).unwrap();
block_on_all(lazy(|| ok())).unwrap();
ok()
})).unwrap();
}))
.unwrap();
}
mod run_in_future {
@@ -241,13 +258,12 @@ mod run_in_future {
fn spawn() {
block_on_all(lazy(|| {
tokio_current_thread::spawn(lazy(|| {
block_on_all(lazy(|| {
ok()
})).unwrap();
block_on_all(lazy(|| ok())).unwrap();
ok()
}));
ok()
})).unwrap();
}))
.unwrap();
}
#[test]
@@ -256,18 +272,16 @@ mod run_in_future {
block_on_all(lazy(|| {
tokio_current_thread::TaskExecutor::current()
.execute(lazy(|| {
block_on_all(lazy(|| {
ok()
})).unwrap();
block_on_all(lazy(|| ok())).unwrap();
ok()
}))
.unwrap();
ok()
})).unwrap();
}))
.unwrap();
}
}
#[test]
fn tick_on_infini_future() {
let num = Rc::new(Cell::new(0));
@@ -288,9 +302,7 @@ fn tick_on_infini_future() {
}
CurrentThread::new()
.spawn(Infini {
num: num.clone(),
})
.spawn(Infini { num: num.clone() })
.turn(None)
.unwrap();
@@ -347,7 +359,8 @@ mod tasks_are_scheduled_fairly {
});
ok()
})).unwrap();
}))
.unwrap();
}
#[test]
@@ -359,8 +372,8 @@ mod tasks_are_scheduled_fairly {
fn execute() {
test(|f| {
tokio_current_thread::TaskExecutor::current()
.execute(f)
.unwrap();
.execute(f)
.unwrap();
})
}
}
@@ -370,8 +383,8 @@ mod and_turn {
fn test<F, G>(spawn: F, dotspawn: G)
where
F: Fn(Box<Future<Item=(), Error=()>>) + 'static,
G: Fn(&mut CurrentThread, Box<Future<Item=(), Error=()>>)
F: Fn(Box<Future<Item = (), Error = ()>>) + 'static,
G: Fn(&mut CurrentThread, Box<Future<Item = (), Error = ()>>),
{
let cnt = Rc::new(Cell::new(0));
let c = cnt.clone();
@@ -379,24 +392,25 @@ mod and_turn {
let mut tokio_current_thread = CurrentThread::new();
// Spawn a basic task to get the executor to turn
dotspawn(&mut tokio_current_thread, Box::new(lazy(move || {
Ok(())
})));
dotspawn(&mut tokio_current_thread, Box::new(lazy(move || Ok(()))));
// Turn once...
tokio_current_thread.turn(None).unwrap();
dotspawn(&mut tokio_current_thread, Box::new(lazy(move || {
c.set(1 + c.get());
// Spawn!
spawn(Box::new(lazy(move || {
dotspawn(
&mut tokio_current_thread,
Box::new(lazy(move || {
c.set(1 + c.get());
Ok::<(), ()>(())
})));
Ok(())
})));
// Spawn!
spawn(Box::new(lazy(move || {
c.set(1 + c.get());
Ok::<(), ()>(())
})));
Ok(())
})),
);
// This does not run the newly spawned thread
tokio_current_thread.turn(None).unwrap();
@@ -409,12 +423,15 @@ mod and_turn {
#[test]
fn spawn() {
test(tokio_current_thread::spawn, |rt, f| { rt.spawn(f); })
test(tokio_current_thread::spawn, |rt, f| {
rt.spawn(f);
})
}
#[test]
fn execute() {
test(|f| {
test(
|f| {
tokio_current_thread::TaskExecutor::current()
.execute(f)
.unwrap();
@@ -423,11 +440,12 @@ mod and_turn {
// `futures::Executor`, so we'll call `.spawn(...)` rather than
// `.execute(...)` for now. If `CurrentThread` is changed to
// implement Executor, change this to `.execute(...).unwrap()`.
|rt, f| { rt.spawn(f); }
|rt, f| {
rt.spawn(f);
},
);
}
}
mod in_drop {
@@ -455,23 +473,24 @@ mod in_drop {
fn test<F, G>(spawn: F, dotspawn: G)
where
F: Fn(Box<Future<Item=(), Error=()>>) + 'static,
G: Fn(&mut CurrentThread, Box<Future<Item=(), Error=()>>)
F: Fn(Box<Future<Item = (), Error = ()>>) + 'static,
G: Fn(&mut CurrentThread, Box<Future<Item = (), Error = ()>>),
{
let mut tokio_current_thread = CurrentThread::new();
let mut tokio_current_thread = CurrentThread::new();
let (tx, rx) = oneshot::channel();
dotspawn(&mut tokio_current_thread, Box::new(
MyFuture {
dotspawn(
&mut tokio_current_thread,
Box::new(MyFuture {
_data: Box::new(OnDrop(Some(move || {
spawn(Box::new(lazy(move || {
tx.send(()).unwrap();
Ok(())
})));
}))),
}
));
}),
);
tokio_current_thread.block_on(rx).unwrap();
tokio_current_thread.run().unwrap();
@@ -479,12 +498,15 @@ mod in_drop {
#[test]
fn spawn() {
test(tokio_current_thread::spawn, |rt, f| { rt.spawn(f); })
test(tokio_current_thread::spawn, |rt, f| {
rt.spawn(f);
})
}
#[test]
fn execute() {
test(|f| {
test(
|f| {
tokio_current_thread::TaskExecutor::current()
.execute(f)
.unwrap();
@@ -493,7 +515,9 @@ mod in_drop {
// `futures::Executor`, so we'll call `.spawn(...)` rather than
// `.execute(...)` for now. If `CurrentThread` is changed to
// implement Executor, change this to `.execute(...).unwrap()`.
|rt, f| { rt.spawn(f); }
|rt, f| {
rt.spawn(f);
},
);
}
@@ -562,13 +586,17 @@ fn turn_has_polled() {
tokio_current_thread.spawn(receiver.then(|_| Ok(())));
// Turn once...
let res = tokio_current_thread.turn(Some(Duration::from_millis(0))).unwrap();
let res = tokio_current_thread
.turn(Some(Duration::from_millis(0)))
.unwrap();
// Should've polled the receiver once, but considered it not ready
assert!(res.has_polled());
// Turn another time
let res = tokio_current_thread.turn(Some(Duration::from_millis(0))).unwrap();
let res = tokio_current_thread
.turn(Some(Duration::from_millis(0)))
.unwrap();
// Should've polled nothing, the receiver is not ready yet
assert!(!res.has_polled());
@@ -577,14 +605,18 @@ fn turn_has_polled() {
sender.send(()).unwrap();
// Turn another time
let res = tokio_current_thread.turn(Some(Duration::from_millis(0))).unwrap();
let res = tokio_current_thread
.turn(Some(Duration::from_millis(0)))
.unwrap();
// Should've polled the receiver, it's ready now
assert!(res.has_polled());
// Now the executor should be empty
assert!(tokio_current_thread.is_idle());
let res = tokio_current_thread.turn(Some(Duration::from_millis(0))).unwrap();
let res = tokio_current_thread
.turn(Some(Duration::from_millis(0)))
.unwrap();
// So should've polled nothing
assert!(!res.has_polled());
@@ -646,46 +678,41 @@ fn turn_fair() {
// Once an item is received on the oneshot channel, it will immediately
// immediately make the second oneshot channel ready
tokio_current_thread.spawn(receiver
.map_err(|_| unreachable!())
.and_then(move |_| {
sender_2.send(()).unwrap();
receiver_1_done_clone.set(true);
tokio_current_thread.spawn(receiver.map_err(|_| unreachable!()).and_then(move |_| {
sender_2.send(()).unwrap();
receiver_1_done_clone.set(true);
Ok(())
})
);
Ok(())
}));
let receiver_2_done = Rc::new(Cell::new(false));
let receiver_2_done_clone = receiver_2_done.clone();
tokio_current_thread.spawn(receiver_2
.map_err(|_| unreachable!())
.and_then(move |_| {
receiver_2_done_clone.set(true);
Ok(())
})
);
tokio_current_thread.spawn(receiver_2.map_err(|_| unreachable!()).and_then(move |_| {
receiver_2_done_clone.set(true);
Ok(())
}));
// The third receiver is only woken up from our Park implementation, it simulates
// e.g. a socket that first has to be polled to know if it is ready now
let receiver_3_done = Rc::new(Cell::new(false));
let receiver_3_done_clone = receiver_3_done.clone();
tokio_current_thread.spawn(receiver_3
.map_err(|_| unreachable!())
.and_then(move |_| {
receiver_3_done_clone.set(true);
Ok(())
})
);
tokio_current_thread.spawn(receiver_3.map_err(|_| unreachable!()).and_then(move |_| {
receiver_3_done_clone.set(true);
Ok(())
}));
// First turn should've polled both and considered them not ready
let res = tokio_current_thread.turn(Some(Duration::from_millis(0))).unwrap();
let res = tokio_current_thread
.turn(Some(Duration::from_millis(0)))
.unwrap();
assert!(res.has_polled());
// Next turn should've polled nothing
let res = tokio_current_thread.turn(Some(Duration::from_millis(0))).unwrap();
let res = tokio_current_thread
.turn(Some(Duration::from_millis(0)))
.unwrap();
assert!(!res.has_polled());
assert!(!receiver_1_done.get());
@@ -736,10 +763,12 @@ fn spawn_from_other_thread() {
let (sender, receiver) = oneshot::channel::<()>();
thread::spawn(move || {
handle.spawn(lazy(move || {
sender.send(()).unwrap();
Ok(())
})).unwrap();
handle
.spawn(lazy(move || {
sender.send(()).unwrap();
Ok(())
}))
.unwrap();
});
let _ = current_thread.block_on(receiver).unwrap();
@@ -758,10 +787,12 @@ fn spawn_from_other_thread_unpark() {
thread::spawn(move || {
let _ = receiver_2.recv().unwrap();
handle.spawn(lazy(move || {
sender_1.send(()).unwrap();
Ok(())
})).unwrap();
handle
.spawn(lazy(move || {
sender_1.send(()).unwrap();
Ok(())
}))
.unwrap();
});
// Ensure that unparking the executor works correctly. It will first
@@ -769,13 +800,15 @@ fn spawn_from_other_thread_unpark() {
// lazy future below which will cause the future to be spawned from
// the other thread. Then the executor will park but should be woken
// up because *now* we have a new future to schedule
let _ = current_thread.block_on(
lazy(move || {
sender_2.send(()).unwrap();
Ok(())
})
.and_then(|_| receiver_1)
).unwrap();
let _ = current_thread
.block_on(
lazy(move || {
sender_2.send(()).unwrap();
Ok(())
})
.and_then(|_| receiver_1),
)
.unwrap();
}
#[test]
@@ -785,10 +818,12 @@ fn spawn_from_executor_with_handle() {
let (tx, rx) = oneshot::channel();
current_thread.spawn(lazy(move || {
handle.spawn(lazy(move || {
tx.send(()).unwrap();
Ok(())
})).unwrap();
handle
.spawn(lazy(move || {
tx.send(()).unwrap();
Ok(())
}))
.unwrap();
Ok::<_, ()>(())
}));
+6 -4
View File
@@ -1,7 +1,7 @@
use std::prelude::v1::*;
use std::cell::Cell;
use std::error::Error;
use std::fmt;
use std::prelude::v1::*;
use futures::{self, Future};
@@ -70,7 +70,10 @@ pub fn enter() -> Result<Enter, EnterError> {
impl Enter {
/// Register a callback to be invoked if and when the thread
/// ceased to act as an executor.
pub fn on_exit<F>(&mut self, f: F) where F: FnOnce() + 'static {
pub fn on_exit<F>(&mut self, f: F)
where
F: FnOnce() + 'static,
{
self.on_exit.push(Box::new(f));
}
@@ -88,7 +91,6 @@ impl Enter {
pub fn block_on<F: Future>(&mut self, f: F) -> Result<F::Item, F::Error> {
futures::executor::spawn(f).wait_future()
}
}
impl fmt::Debug for Enter {
@@ -103,7 +105,7 @@ impl Drop for Enter {
assert!(c.get());
if self.permanent {
return
return;
}
for callback in self.on_exit.drain(..) {
+25 -23
View File
@@ -1,4 +1,4 @@
use super::{Executor, Enter, SpawnError};
use super::{Enter, Executor, SpawnError};
use futures::{future, Future};
@@ -33,24 +33,22 @@ impl DefaultExecutor {
/// `DefaultExecutor::current()` on thread A and then sending the result to
/// thread B will _not_ reference the default executor that was set on thread A.
pub fn current() -> DefaultExecutor {
DefaultExecutor {
_dummy: (),
}
DefaultExecutor { _dummy: () }
}
#[inline]
fn with_current<F: FnOnce(&mut Executor) -> R, R>(f: F) -> Option<R> {
EXECUTOR.with(|current_executor| {
match current_executor.replace(State::Active) {
EXECUTOR.with(
|current_executor| match current_executor.replace(State::Active) {
State::Ready(executor_ptr) => {
let executor = unsafe { &mut *executor_ptr };
let result = f(executor);
current_executor.set(State::Ready(executor_ptr));
Some(result)
},
}
State::Empty | State::Active => None,
}
})
},
)
}
}
@@ -61,10 +59,10 @@ enum State {
// default executor is defined and ready to be used
Ready(*mut Executor),
// default executor is currently active (used to detect recursive calls)
Active
Active,
}
thread_local!{
thread_local! {
/// Thread-local tracking the current executor
static EXECUTOR: Cell<State> = Cell::new(State::Empty)
}
@@ -72,9 +70,10 @@ thread_local!{
// ===== impl DefaultExecutor =====
impl super::Executor for DefaultExecutor {
fn spawn(&mut self, future: Box<Future<Item = (), Error = ()> + Send>)
-> Result<(), SpawnError>
{
fn spawn(
&mut self,
future: Box<Future<Item = (), Error = ()> + Send>,
) -> Result<(), SpawnError> {
DefaultExecutor::with_current(|executor| executor.spawn(future))
.unwrap_or_else(|| Err(SpawnError::shutdown()))
}
@@ -86,7 +85,8 @@ impl super::Executor for DefaultExecutor {
}
impl<T> future::Executor<T> for DefaultExecutor
where T: Future<Item = (), Error = ()> + Send + 'static,
where
T: Future<Item = (), Error = ()> + Send + 'static,
{
fn execute(&self, future: T) -> Result<(), future::ExecuteError<T>> {
if let Err(e) = super::Executor::status(self) {
@@ -146,10 +146,10 @@ where T: Future<Item = (), Error = ()> + Send + 'static,
/// # pub fn main() {}
/// ```
pub fn spawn<T>(future: T)
where T: Future<Item = (), Error = ()> + Send + 'static,
where
T: Future<Item = (), Error = ()> + Send + 'static,
{
DefaultExecutor::current().spawn(Box::new(future))
.unwrap()
DefaultExecutor::current().spawn(Box::new(future)).unwrap()
}
/// Set the default executor for the duration of the closure
@@ -158,13 +158,15 @@ pub fn spawn<T>(future: T)
///
/// This function panics if there already is a default executor set.
pub fn with_default<T, F, R>(executor: &mut T, enter: &mut Enter, f: F) -> R
where T: Executor,
F: FnOnce(&mut Enter) -> R
where
T: Executor,
F: FnOnce(&mut Enter) -> R,
{
EXECUTOR.with(|cell| {
match cell.get() {
State::Ready(_) | State::Active =>
panic!("default executor already set for execution context"),
State::Ready(_) | State::Active => {
panic!("default executor already set for execution context")
}
_ => {}
}
@@ -202,7 +204,7 @@ unsafe fn hide_lt<'a>(p: *mut (Executor + 'a)) -> *mut (Executor + 'static) {
#[cfg(test)]
mod tests {
use super::{Executor, DefaultExecutor, with_default};
use super::{with_default, DefaultExecutor, Executor};
#[test]
fn default_executor_is_send_and_sync() {
+8 -5
View File
@@ -134,8 +134,10 @@ pub trait Executor {
/// # }
/// # fn main() {}
/// ```
fn spawn(&mut self, future: Box<Future<Item = (), Error = ()> + Send>)
-> Result<(), SpawnError>;
fn spawn(
&mut self,
future: Box<Future<Item = (), Error = ()> + Send>,
) -> Result<(), SpawnError>;
/// Provides a best effort **hint** to whether or not `spawn` will succeed.
///
@@ -178,9 +180,10 @@ pub trait Executor {
}
impl<E: Executor + ?Sized> Executor for Box<E> {
fn spawn(&mut self, future: Box<Future<Item = (), Error = ()> + Send>)
-> Result<(), SpawnError>
{
fn spawn(
&mut self,
future: Box<Future<Item = (), Error = ()> + Send>,
) -> Result<(), SpawnError> {
(**self).spawn(future)
}
+2 -1
View File
@@ -190,7 +190,8 @@ impl ParkThread {
/// Get a reference to the `ParkThread` handle for this thread.
fn with_current<F, R>(&self, f: F) -> R
where F: FnOnce(&Parker) -> R,
where
F: FnOnce(&Parker) -> R,
{
CURRENT_PARKER.with(|inner| f(inner))
}
+3 -3
View File
@@ -1,15 +1,15 @@
extern crate tokio_executor;
extern crate futures;
extern crate tokio_executor;
use futures::{future::lazy, Future};
use tokio_executor::*;
use futures::{Future, future::lazy};
mod out_of_executor_context {
use super::*;
fn test<F, E>(spawn: F)
where
F: Fn(Box<Future<Item=(), Error=()> + Send>) -> Result<(), E>,
F: Fn(Box<Future<Item = (), Error = ()> + Send>) -> Result<(), E>,
{
let res = spawn(Box::new(lazy(|| Ok(()))));
assert!(res.is_err());
+17 -19
View File
@@ -2,39 +2,35 @@
#![deny(deprecated, warnings)]
extern crate futures;
extern crate tokio_fs;
extern crate tokio_codec;
extern crate tokio_fs;
extern crate tokio_threadpool;
use tokio_fs::{stdin, stdout, stderr};
use tokio_codec::{FramedRead, FramedWrite, LinesCodec};
use tokio_fs::{stderr, stdin, stdout};
use tokio_threadpool::Builder;
use futures::{Future, Stream, Sink};
use futures::{Future, Sink, Stream};
use std::io;
pub fn main() -> Result<(), Box<std::error::Error>> {
let pool = Builder::new()
.pool_size(1)
.build();
let pool = Builder::new().pool_size(1).build();
pool.spawn({
let input = FramedRead::new(stdin(), LinesCodec::new());
let output = FramedWrite::new(stdout(), LinesCodec::new())
.with(|line: String| {
let mut out = "OUT: ".to_string();
out.push_str(&line);
Ok::<_, io::Error>(out)
});
let output = FramedWrite::new(stdout(), LinesCodec::new()).with(|line: String| {
let mut out = "OUT: ".to_string();
out.push_str(&line);
Ok::<_, io::Error>(out)
});
let error = FramedWrite::new(stderr(), LinesCodec::new())
.with(|line: String| {
let mut out = "ERR: ".to_string();
out.push_str(&line);
Ok::<_, io::Error>(out)
});
let error = FramedWrite::new(stderr(), LinesCodec::new()).with(|line: String| {
let mut out = "ERR: ".to_string();
out.push_str(&line);
Ok::<_, io::Error>(out)
});
let dst = output.fanout(error);
@@ -44,6 +40,8 @@ pub fn main() -> Result<(), Box<std::error::Error>> {
.map_err(|e| panic!("io error = {:?}", e))
});
pool.shutdown_on_idle().wait().map_err(|_| "failed to shutdown the thread pool")?;
pool.shutdown_on_idle()
.wait()
.map_err(|_| "failed to shutdown the thread pool")?;
Ok(())
}
+5 -7
View File
@@ -17,30 +17,28 @@ pub fn create_dir<P: AsRef<Path>>(path: P) -> CreateDirFuture<P> {
#[derive(Debug)]
pub struct CreateDirFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
path: P,
}
impl<P> CreateDirFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
fn new(path: P) -> CreateDirFuture<P> {
CreateDirFuture {
path: path,
}
CreateDirFuture { path: path }
}
}
impl<P> Future for CreateDirFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
type Item = ();
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::create_dir(&self.path) )
::blocking_io(|| fs::create_dir(&self.path))
}
}
+5 -7
View File
@@ -18,30 +18,28 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) -> CreateDirAllFuture<P> {
#[derive(Debug)]
pub struct CreateDirAllFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
path: P,
}
impl<P> CreateDirAllFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
fn new(path: P) -> CreateDirAllFuture<P> {
CreateDirAllFuture {
path: path,
}
CreateDirAllFuture { path: path }
}
}
impl<P> Future for CreateDirAllFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
type Item = ();
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::create_dir_all(&self.path) )
::blocking_io(|| fs::create_dir_all(&self.path))
}
}
+5 -5
View File
@@ -13,7 +13,8 @@ pub struct CreateFuture<P> {
}
impl<P> CreateFuture<P>
where P: AsRef<Path> + Send + 'static,
where
P: AsRef<Path> + Send + 'static,
{
pub(crate) fn new(path: P) -> Self {
CreateFuture { path }
@@ -21,15 +22,14 @@ where P: AsRef<Path> + Send + 'static,
}
impl<P> Future for CreateFuture<P>
where P: AsRef<Path> + Send + 'static,
where
P: AsRef<Path> + Send + 'static,
{
type Item = File;
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let std = try_ready!(::blocking_io(|| {
StdFile::create(&self.path)
}));
let std = try_ready!(::blocking_io(|| StdFile::create(&self.path)));
let file = File::from_std(std);
Ok(file.into())
+1 -3
View File
@@ -29,9 +29,7 @@ impl Future for MetadataFuture {
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let metadata = try_ready!(::blocking_io(|| {
StdFile::metadata(self.std())
}));
let metadata = try_ready!(::blocking_io(|| StdFile::metadata(self.std())));
let file = self.file.take().expect(POLL_AFTER_RESOLVE);
Ok((file, metadata).into())
+31 -29
View File
@@ -21,7 +21,7 @@ use tokio_io::{AsyncRead, AsyncWrite};
use futures::Poll;
use std::fs::{File as StdFile, Metadata, Permissions};
use std::io::{self, Read, Write, Seek};
use std::io::{self, Read, Seek, Write};
use std::path::Path;
/// A reference to an open file on the filesystem.
@@ -43,16 +43,16 @@ use std::path::Path;
///
/// ```no_run
/// extern crate tokio;
///
///
/// use tokio::prelude::{AsyncWrite, Future};
///
///
/// fn main() {
/// let task = tokio::fs::File::create("foo.txt")
/// .and_then(|mut file| file.poll_write(b"hello, world!"))
/// .map(|res| {
/// println!("{:?}", res);
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
///
///
/// tokio::run(task);
/// }
/// ```
@@ -61,9 +61,9 @@ use std::path::Path;
///
/// ```no_run
/// extern crate tokio;
///
///
/// use tokio::prelude::{AsyncRead, Future};
///
///
/// fn main() {
/// let task = tokio::fs::File::open("foo.txt")
/// .and_then(|mut file| {
@@ -112,7 +112,8 @@ impl File {
/// }
/// ```
pub fn open<P>(path: P) -> OpenFuture<P>
where P: AsRef<Path> + Send + 'static,
where
P: AsRef<Path> + Send + 'static,
{
OpenOptions::new().read(true).open(path)
}
@@ -151,7 +152,8 @@ impl File {
/// }
/// ```
pub fn create<P>(path: P) -> CreateFuture<P>
where P: AsRef<Path> + Send + 'static,
where
P: AsRef<Path> + Send + 'static,
{
CreateFuture::new(path)
}
@@ -165,7 +167,7 @@ impl File {
/// ```no_run
/// # extern crate tokio;
/// use std::fs::File;
///
///
/// fn main() {
/// let std_file = File::open("foo.txt").unwrap();
/// let file = tokio::fs::File::from_std(std_file);
@@ -194,7 +196,7 @@ impl File {
/// # extern crate tokio;
/// use tokio::prelude::Future;
/// use std::io::SeekFrom;
///
///
/// fn main() {
/// let task = tokio::fs::File::open("foo.txt")
/// // move cursor 6 bytes from the start of the file
@@ -202,7 +204,7 @@ impl File {
/// .map(|res| {
/// println!("{:?}", res);
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
///
///
/// tokio::run(task);
/// }
/// ```
@@ -223,7 +225,7 @@ impl File {
/// # extern crate tokio;
/// use tokio::prelude::Future;
/// use std::io::SeekFrom;
///
///
/// fn main() {
/// let task = tokio::fs::File::create("foo.txt")
/// .and_then(|file| file.seek(SeekFrom::Start(6)))
@@ -231,7 +233,7 @@ impl File {
/// // handle returned file ..
/// # println!("{:?}", file);
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
///
///
/// tokio::run(task);
/// }
/// ```
@@ -249,7 +251,7 @@ impl File {
/// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::{AsyncWrite, Future};
///
///
/// fn main() {
/// let task = tokio::fs::File::create("foo.txt")
/// .and_then(|mut file| {
@@ -260,7 +262,7 @@ impl File {
/// // handle returned result ..
/// # println!("{:?}", res);
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
///
///
/// tokio::run(task);
/// }
/// ```
@@ -282,7 +284,7 @@ impl File {
/// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::{AsyncWrite, Future};
///
///
/// fn main() {
/// let task = tokio::fs::File::create("foo.txt")
/// .and_then(|mut file| {
@@ -293,7 +295,7 @@ impl File {
/// // handle returned result ..
/// # println!("{:?}", res);
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
///
///
/// tokio::run(task);
/// }
/// ```
@@ -318,7 +320,7 @@ impl File {
/// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future;
///
///
/// fn main() {
/// let task = tokio::fs::File::create("foo.txt")
/// .and_then(|mut file| {
@@ -328,7 +330,7 @@ impl File {
/// // handle returned result ..
/// # println!("{:?}", res);
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
///
///
/// tokio::run(task);
/// }
/// ```
@@ -343,14 +345,14 @@ impl File {
/// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future;
///
///
/// fn main() {
/// let task = tokio::fs::File::create("foo.txt")
/// .and_then(|file| file.metadata())
/// .map(|metadata| {
/// println!("{:?}", metadata);
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
///
///
/// tokio::run(task);
/// }
/// ```
@@ -365,7 +367,7 @@ impl File {
/// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future;
///
///
/// fn main() {
/// let task = tokio::fs::File::create("foo.txt")
/// .and_then(|mut file| file.poll_metadata())
@@ -373,7 +375,7 @@ impl File {
/// // metadata is of type Async::Ready<Metadata>
/// println!("{:?}", metadata);
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
///
///
/// tokio::run(task);
/// }
/// ```
@@ -390,7 +392,7 @@ impl File {
/// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future;
///
///
/// fn main() {
/// let task = tokio::fs::File::create("foo.txt")
/// .and_then(|mut file| file.poll_try_clone())
@@ -398,7 +400,7 @@ impl File {
/// // do something with the clone
/// # println!("{:?}", clone);
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
///
///
/// tokio::run(task);
/// }
/// ```
@@ -462,7 +464,7 @@ impl File {
/// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future;
///
///
/// fn main() {
/// let task = tokio::fs::File::create("foo.txt")
/// .and_then(|file| file.metadata())
@@ -474,7 +476,7 @@ impl File {
/// _ => println!("permissions set!"),
/// }
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
///
///
/// tokio::run(task);
/// }
/// ```
@@ -495,7 +497,7 @@ impl File {
/// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future;
///
///
/// fn main() {
/// let task = tokio::fs::File::create("foo.txt")
/// .map(|file| {
@@ -503,7 +505,7 @@ impl File {
/// // do something with the std::fs::File
/// # println!("{:?}", std_file);
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
///
///
/// tokio::run(task);
/// }
/// ```
+5 -5
View File
@@ -14,7 +14,8 @@ pub struct OpenFuture<P> {
}
impl<P> OpenFuture<P>
where P: AsRef<Path> + Send + 'static,
where
P: AsRef<Path> + Send + 'static,
{
pub(crate) fn new(options: StdOpenOptions, path: P) -> Self {
OpenFuture { options, path }
@@ -22,15 +23,14 @@ where P: AsRef<Path> + Send + 'static,
}
impl<P> Future for OpenFuture<P>
where P: AsRef<Path> + Send + 'static,
where
P: AsRef<Path> + Send + 'static,
{
type Item = File;
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let std = try_ready!(::blocking_io(|| {
self.options.open(&self.path)
}));
let std = try_ready!(::blocking_io(|| self.options.open(&self.path)));
let file = File::from_std(std);
Ok(file.into())
+2 -1
View File
@@ -90,7 +90,8 @@ impl OpenOptions {
///
/// [`open`]: https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.open
pub fn open<P>(&self, path: P) -> OpenFuture<P>
where P: AsRef<Path> + Send + 'static
where
P: AsRef<Path> + Send + 'static,
{
OpenFuture::new(self.0.clone(), path)
}
+5 -6
View File
@@ -25,12 +25,11 @@ impl Future for SeekFuture {
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let pos = try_ready!(
self.inner
.as_mut()
.expect("Cannot poll `SeekFuture` after it resolves")
.poll_seek(self.pos)
);
let pos = try_ready!(self
.inner
.as_mut()
.expect("Cannot poll `SeekFuture` after it resolves")
.poll_seek(self.pos));
let inner = self.inner.take().unwrap();
Ok((inner, pos).into())
}
+5 -8
View File
@@ -21,7 +21,7 @@ pub fn hard_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> HardLinkFutu
pub struct HardLinkFuture<P, Q>
where
P: AsRef<Path>,
Q: AsRef<Path>
Q: AsRef<Path>,
{
src: P,
dst: Q,
@@ -30,25 +30,22 @@ where
impl<P, Q> HardLinkFuture<P, Q>
where
P: AsRef<Path>,
Q: AsRef<Path>
Q: AsRef<Path>,
{
fn new(src: P, dst: Q) -> HardLinkFuture<P, Q> {
HardLinkFuture {
src: src,
dst: dst,
}
HardLinkFuture { src: src, dst: dst }
}
}
impl<P, Q> Future for HardLinkFuture<P, Q>
where
P: AsRef<Path>,
Q: AsRef<Path>
Q: AsRef<Path>,
{
type Item = ();
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::hard_link(&self.src, &self.dst) )
::blocking_io(|| fs::hard_link(&self.src, &self.dst))
}
}
+15 -10
View File
@@ -39,16 +39,16 @@ pub mod file;
mod hard_link;
mod metadata;
pub mod os;
mod read;
mod read_dir;
mod read_link;
mod read;
mod remove_dir;
mod remove_file;
mod rename;
mod set_permissions;
mod stderr;
mod stdin;
mod stdout;
mod stderr;
mod symlink_metadata;
mod write;
@@ -58,27 +58,28 @@ pub use file::File;
pub use file::OpenOptions;
pub use hard_link::{hard_link, HardLinkFuture};
pub use metadata::{metadata, MetadataFuture};
pub use read_dir::{read_dir, ReadDirFuture, ReadDir, DirEntry};
pub use read_link::{read_link, ReadLinkFuture};
pub use read::{read, ReadFile};
pub use read_dir::{read_dir, DirEntry, ReadDir, ReadDirFuture};
pub use read_link::{read_link, ReadLinkFuture};
pub use remove_dir::{remove_dir, RemoveDirFuture};
pub use remove_file::{remove_file, RemoveFileFuture};
pub use rename::{rename, RenameFuture};
pub use set_permissions::{set_permissions, SetPermissionsFuture};
pub use stderr::{stderr, Stderr};
pub use stdin::{stdin, Stdin};
pub use stdout::{stdout, Stdout};
pub use stderr::{stderr, Stderr};
pub use symlink_metadata::{symlink_metadata, SymlinkMetadataFuture};
pub use write::{write, WriteFile};
use futures::Poll;
use futures::Async::*;
use futures::Poll;
use std::io;
use std::io::ErrorKind::{Other, WouldBlock};
fn blocking_io<F, T>(f: F) -> Poll<T, io::Error>
where F: FnOnce() -> io::Result<T>,
where
F: FnOnce() -> io::Result<T>,
{
match tokio_threadpool::blocking(f) {
Ok(Ready(Ok(v))) => Ok(v.into()),
@@ -89,7 +90,8 @@ where F: FnOnce() -> io::Result<T>,
}
fn would_block<F, T>(f: F) -> io::Result<T>
where F: FnOnce() -> io::Result<T>,
where
F: FnOnce() -> io::Result<T>,
{
match tokio_threadpool::blocking(f) {
Ok(Ready(Ok(v))) => Ok(v),
@@ -103,6 +105,9 @@ where F: FnOnce() -> io::Result<T>,
}
fn blocking_err() -> io::Error {
io::Error::new(Other, "`blocking` annotated I/O must be called \
from the context of the Tokio runtime.")
io::Error::new(
Other,
"`blocking` annotated I/O must be called \
from the context of the Tokio runtime.",
)
}
+6 -9
View File
@@ -1,8 +1,8 @@
//! Unix-specific extensions to primitives in the `tokio_fs` module.
use std::io;
use std::path::Path;
use std::os::unix::fs;
use std::path::Path;
use futures::{Future, Poll};
@@ -22,7 +22,7 @@ pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> SymlinkFuture<
pub struct SymlinkFuture<P, Q>
where
P: AsRef<Path>,
Q: AsRef<Path>
Q: AsRef<Path>,
{
src: P,
dst: Q,
@@ -31,25 +31,22 @@ where
impl<P, Q> SymlinkFuture<P, Q>
where
P: AsRef<Path>,
Q: AsRef<Path>
Q: AsRef<Path>,
{
fn new(src: P, dst: Q) -> SymlinkFuture<P, Q> {
SymlinkFuture {
src: src,
dst: dst,
}
SymlinkFuture { src: src, dst: dst }
}
}
impl<P, Q> Future for SymlinkFuture<P, Q>
where
P: AsRef<Path>,
Q: AsRef<Path>
Q: AsRef<Path>,
{
type Item = ();
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::symlink(&self.src, &self.dst) )
::blocking_io(|| fs::symlink(&self.src, &self.dst))
}
}
+6 -9
View File
@@ -1,6 +1,6 @@
use std::io;
use std::path::Path;
use std::os::windows::fs;
use std::path::Path;
use futures::{Future, Poll};
@@ -21,7 +21,7 @@ pub fn symlink_dir<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> SymlinkDir
pub struct SymlinkDirFuture<P, Q>
where
P: AsRef<Path>,
Q: AsRef<Path>
Q: AsRef<Path>,
{
src: P,
dst: Q,
@@ -30,25 +30,22 @@ where
impl<P, Q> SymlinkDirFuture<P, Q>
where
P: AsRef<Path>,
Q: AsRef<Path>
Q: AsRef<Path>,
{
fn new(src: P, dst: Q) -> SymlinkDirFuture<P, Q> {
SymlinkDirFuture {
src: src,
dst: dst,
}
SymlinkDirFuture { src: src, dst: dst }
}
}
impl<P, Q> Future for SymlinkDirFuture<P, Q>
where
P: AsRef<Path>,
Q: AsRef<Path>
Q: AsRef<Path>,
{
type Item = ();
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::symlink_dir(&self.src, &self.dst) )
::blocking_io(|| fs::symlink_dir(&self.src, &self.dst))
}
}
+6 -9
View File
@@ -1,6 +1,6 @@
use std::io;
use std::path::Path;
use std::os::windows::fs;
use std::path::Path;
use futures::{Future, Poll};
@@ -21,7 +21,7 @@ pub fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> SymlinkFi
pub struct SymlinkFileFuture<P, Q>
where
P: AsRef<Path>,
Q: AsRef<Path>
Q: AsRef<Path>,
{
src: P,
dst: Q,
@@ -30,25 +30,22 @@ where
impl<P, Q> SymlinkFileFuture<P, Q>
where
P: AsRef<Path>,
Q: AsRef<Path>
Q: AsRef<Path>,
{
fn new(src: P, dst: Q) -> SymlinkFileFuture<P, Q> {
SymlinkFileFuture {
src: src,
dst: dst,
}
SymlinkFileFuture { src: src, dst: dst }
}
}
impl<P, Q> Future for SymlinkFileFuture<P, Q>
where
P: AsRef<Path>,
Q: AsRef<Path>
Q: AsRef<Path>,
{
type Item = ();
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::symlink_file(&self.src, &self.dst) )
::blocking_io(|| fs::symlink_file(&self.src, &self.dst))
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
use {file, File};
use futures::{Async, Future, Poll};
use std::{io, mem, path::Path};
use tokio_io;
use {file, File};
/// Creates a future which will open a file for reading and read the entire
/// contents into a buffer and return said buffer.
+7 -11
View File
@@ -1,5 +1,5 @@
use std::ffi::OsString;
use std::fs::{self, DirEntry as StdDirEntry, ReadDir as StdReadDir, FileType, Metadata};
use std::fs::{self, DirEntry as StdDirEntry, FileType, Metadata, ReadDir as StdReadDir};
use std::io;
#[cfg(unix)]
use std::os::unix::fs::DirEntryExt;
@@ -30,12 +30,10 @@ where
impl<P> ReadDirFuture<P>
where
P: AsRef<Path> + Send + 'static
P: AsRef<Path> + Send + 'static,
{
fn new(path: P) -> ReadDirFuture<P> {
ReadDirFuture {
path: path,
}
ReadDirFuture { path: path }
}
}
@@ -75,12 +73,10 @@ impl Stream for ReadDir {
type Error = io::Error;
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
::blocking_io(|| {
match self.0.next() {
Some(Err(err)) => Err(err),
Some(Ok(item)) => Ok(Some(DirEntry(item))),
None => Ok(None)
}
::blocking_io(|| match self.0.next() {
Some(Err(err)) => Err(err),
Some(Ok(item)) => Ok(Some(DirEntry(item))),
None => Ok(None),
})
}
}
+5 -7
View File
@@ -17,30 +17,28 @@ pub fn read_link<P: AsRef<Path>>(path: P) -> ReadLinkFuture<P> {
#[derive(Debug)]
pub struct ReadLinkFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
path: P,
}
impl<P> ReadLinkFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
fn new(path: P) -> ReadLinkFuture<P> {
ReadLinkFuture {
path: path,
}
ReadLinkFuture { path: path }
}
}
impl<P> Future for ReadLinkFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
type Item = PathBuf;
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::read_link(&self.path) )
::blocking_io(|| fs::read_link(&self.path))
}
}
+5 -7
View File
@@ -17,30 +17,28 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> RemoveDirFuture<P> {
#[derive(Debug)]
pub struct RemoveDirFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
path: P,
}
impl<P> RemoveDirFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
fn new(path: P) -> RemoveDirFuture<P> {
RemoveDirFuture {
path: path,
}
RemoveDirFuture { path: path }
}
}
impl<P> Future for RemoveDirFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
type Item = ();
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::remove_dir(&self.path) )
::blocking_io(|| fs::remove_dir(&self.path))
}
}
+5 -7
View File
@@ -21,30 +21,28 @@ pub fn remove_file<P: AsRef<Path>>(path: P) -> RemoveFileFuture<P> {
#[derive(Debug)]
pub struct RemoveFileFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
path: P,
}
impl<P> RemoveFileFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
fn new(path: P) -> RemoveFileFuture<P> {
RemoveFileFuture {
path: path,
}
RemoveFileFuture { path: path }
}
}
impl<P> Future for RemoveFileFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
type Item = ();
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::remove_file(&self.path) )
::blocking_io(|| fs::remove_file(&self.path))
}
}
+5 -8
View File
@@ -21,7 +21,7 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> RenameFuture<P,
pub struct RenameFuture<P, Q>
where
P: AsRef<Path>,
Q: AsRef<Path>
Q: AsRef<Path>,
{
from: P,
to: Q,
@@ -30,25 +30,22 @@ where
impl<P, Q> RenameFuture<P, Q>
where
P: AsRef<Path>,
Q: AsRef<Path>
Q: AsRef<Path>,
{
fn new(from: P, to: Q) -> RenameFuture<P, Q> {
RenameFuture {
from: from,
to: to,
}
RenameFuture { from: from, to: to }
}
}
impl<P, Q> Future for RenameFuture<P, Q>
where
P: AsRef<Path>,
Q: AsRef<Path>
Q: AsRef<Path>,
{
type Item = ();
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::rename(&self.from, &self.to) )
::blocking_io(|| fs::rename(&self.from, &self.to))
}
}
+4 -4
View File
@@ -17,7 +17,7 @@ pub fn set_permissions<P: AsRef<Path>>(path: P, perm: fs::Permissions) -> SetPer
#[derive(Debug)]
pub struct SetPermissionsFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
path: P,
perm: fs::Permissions,
@@ -25,7 +25,7 @@ where
impl<P> SetPermissionsFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
fn new(path: P, perm: fs::Permissions) -> SetPermissionsFuture<P> {
SetPermissionsFuture {
@@ -37,12 +37,12 @@ where
impl<P> Future for SetPermissionsFuture<P>
where
P: AsRef<Path>
P: AsRef<Path>,
{
type Item = ();
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::set_permissions(&self.path, self.perm.clone()) )
::blocking_io(|| fs::set_permissions(&self.path, self.perm.clone()))
}
}
+2 -3
View File
@@ -1,8 +1,8 @@
use tokio_io::{AsyncWrite};
use tokio_io::AsyncWrite;
use futures::Poll;
use std::io::{self, Write, Stderr as StdStderr};
use std::io::{self, Stderr as StdStderr, Write};
/// A handle to the standard error stream of a process.
///
@@ -42,4 +42,3 @@ impl AsyncWrite for Stderr {
Ok(().into())
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
use tokio_io::{AsyncRead};
use tokio_io::AsyncRead;
use std::io::{self, Read, Stdin as StdStdin};

Some files were not shown because too many files have changed in this diff Show More