Skip to content

Commit

Permalink
Rename to tokio-core, add in futures-io
Browse files Browse the repository at this point in the history
Renames the futures-mio crate to tokio-core, pulls in the futures-io crate under
an `io` module, and gets everything compiling.
  • Loading branch information
alexcrichton committed Aug 26, 2016
1 parent e71d509 commit f107c8d
Show file tree
Hide file tree
Showing 29 changed files with 1,495 additions and 77 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target
Cargo.lock
24 changes: 24 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
language: rust

rust:
- stable
- beta
- nightly
sudo: false
before_script:
- pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
script:
- cargo build
- cargo test
- cargo doc --no-deps
after_success:
- travis-cargo --only nightly doc-upload
env:
global:
- secure: LVrtwDI0IJradnHRk53dGWtTS+limhkuHym17wuto/Zaz6IJB9aq7G5wSYuZU3qabcxah7pigjXPFgzYwFD6mNHW1DAuAko1qOi4AL0rvg+rA7Fa5E9NEIxoqzCf+wBtqCvomBe/akOs7UtHdjE3CZpIEPwSHVf3jf61suB0mPVUW0AFTHvYTvHT4lyHjlruY+Ifi350yb4t0Oy9rU1bHNtX0q1T0mKuTnKkmpCT2Kj+2L7afgsAR3UgBjL3Py89LXmnF5VxSMGJWa6HL3xgEi3CXxBRQFdr+vipIDejWtjY+7DzvSRHid1rVfwCLdLfTwvA3Pf3b0I5DSJnjzRgKkfiH2j7JNFtCvLz+mM5C/4QJzAgNmdyNuDv0qOy07OABtYs/LE60f6ZZ5YMZAloMtA/9qQjJx+c2jO2nTZkx6vNJ5C421yzm2klQSL0d8pFaDmojqC5pT85MYhf3mESqSw1UjwFPa0xFtysT52oJBcyvwI/wBYbK40sArjSDZaU2Jncw9ptDWML/xUM+sWHF7ZW/mI1V15lqaCBX91xlbppfWDMgNF2c60vC90t0entbGpYLvHjQMdW6iucbsLLN5KAPzYPuufX2vJa8V1gxMxZ7CLcVLx9lmm3uEdrOZLEg4Fg7H7Xqc2JRygbNrTtOeBw1/o73znnnjEv8Vl3xqg=
notifications:
email:
on_success: never
os:
- linux
- osx
15 changes: 7 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
[package]
name = "futures-mio"
name = "tokio-core"
version = "0.1.0"
authors = ["Alex Crichton <[email protected]>"]
license = "MIT/Apache-2.0"
repository = "https://github.com/alexcrichton/futures-rs"
homepage = "https://github.com/alexcrichton/futures-rs"
documentation = "http://alexcrichton.com/futures-rs/futures_mio/"
repository = "https://github.com/tokio-rs/tokio-core"
homepage = "https://github.com/tokio-rs/tokio-core"
documentation = "https://tokio-rs.github.io/tokio-core"
description = """
Bindings from the `futures` crate to the `mio` crate to get I/O in the form of
futures and streams.
Core I/O and event loop primitives for asynchronous I/O in Rust. Foundation for
the rest of the tokio crates.
"""

[dependencies]
futures = { path = "..", version = "0.1.0" }
futures-io = { path = "../futures-io", version = "0.1.0" }
futures = { git = "https://github.com/alexcrichton/futures-rs" }
log = "0.3"
mio = { git = "https://github.com/carllerche/mio" }
scoped-tls = "0.1.0"
Expand Down
45 changes: 22 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
# futures-mio
# tokio-core

Bindings to the `mio` crate implementing the `futures-io` and `futures`
abstractions.
Core I/O and event loop abstraction for asynchronous I/O in Rust built on
`futures` and `mio`.

[![Build Status](https://travis-ci.org/alexcrichton/futures-rs.svg?branch=master)](https://travis-ci.org/alexcrichton/futures-rs)
[![Build Status](https://travis-ci.org/tokio-rs/tokio-core.svg?branch=master)](https://travis-ci.org/tokio-rs/tokio-core)
[![Build status](https://ci.appveyor.com/api/projects/status/yl5w3ittk4kggfsh?svg=true)](https://ci.appveyor.com/project/alexcrichton/futures-rs)

[Documentation](http://alexcrichton.com/futures-rs/futures_mio)
[Documentation](https://tokio-rs.github.io/tokio-core)

## Usage

First, add this to your `Cargo.toml`:

```toml
[dependencies]
futures-mio = { git = "https://github.com/alexcrichton/futures-rs" }
tokio-core = { git = "https://github.com/tokio-rs/tokio-core" }
```

Next, add this to your crate:

```rust
extern crate futures_mio;
extern crate tokio_core;
```

## Examples
Expand All @@ -30,18 +30,17 @@ There are a few small examples showing off how to use this library:
* [echo.rs] - a simple TCP echo server
* [socks5.rs] - an implementation of a SOCKSv5 proxy server

[echo.rs]: https://github.com/alexcrichton/futures-rs/blob/master/futures-mio/src/bin/echo.rs
[socks5.rs]: https://github.com/alexcrichton/futures-rs/blob/master/futures-socks5/src/main.rs
[echo.rs]: https://github.com/tokio-rs/tokio-core/blob/master/src/bin/echo.rs
[socks5.rs]: https://github.com/tokio-rs/tokio-socks5/blob/master/src/main.rs

## What is futures-mio?
## What is tokio-core?

This crate is a connection `futures`, a zero-cost implementation of futures in
Rust, and `mio`, a crate for zero-cost asynchronous I/O, and `futures-io`,
abstractions for I/O on top of the `futures` crate. The types and structures
implemented in `futures-mio` implement `Future` and `Stream` traits as
appropriate. For example connecting a TCP stream returns a `Future` resolving
to a TCP stream, and a TCP listener implements a stream of TCP streams
(accepted connections).
Rust, and `mio` and a crate for zero-cost asynchronous I/O. The types and
structures implemented in `tokio-core` implement `Future` and `Stream` traits
as appropriate. For example connecting a TCP stream returns a `Future`
resolving to a TCP stream, and a TCP listener implements a stream of TCP
streams (accepted connections).

This crate also provides facilities such as:

Expand All @@ -52,20 +51,20 @@ This crate also provides facilities such as:
* Data owned and local to the event loop
* An `Executor` implementation for a futures' `Task`

The intention of `futures-mio` is to provide a concrete implementation for
crates built on top of `futures-io`. For example you can easily turn a TCP
stream into a TLS/SSL stream with the [`futures-tls`] crate or use the
combinators to compose working with data on sockets.
The intention of `tokio-core` is to provide a concrete implementation for crates
built on top of asynchronous I/O. For example you can easily turn a TCP stream
into a TLS/SSL stream with the [`tokio-tls`] crate or use the combinators to
compose working with data on sockets.

[`futures-tls`]: http://alexcrichton.com/futures-rs/futures_tls
[`tokio-tls`]: https://tokio-rs.github.io/tokio-tls

Check out the [documentation] for more information, and more coming here soon!

[documentation]: http://alexcrichton.com/futures-rs/futures_mio
[documentation]: https://tokio-rs.github.io/tokio-core

# License

`futures-mio` is primarily distributed under the terms of both the MIT license
`tokio-core` is primarily distributed under the terms of both the MIT license
and the Apache License (Version 2.0), with portions covered by various BSD-like
licenses.

Expand Down
7 changes: 3 additions & 4 deletions src/bin/echo.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
//! An echo server that just writes back everything that's written to it.
extern crate futures;
extern crate futures_io;
extern crate futures_mio;
extern crate tokio_core;

use std::env;
use std::net::SocketAddr;

use futures::Future;
use futures::stream::Stream;
use futures_io::{copy, TaskIo};
use tokio_core::io::{copy, TaskIo};

fn main() {
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
let addr = addr.parse::<SocketAddr>().unwrap();

// Create the event loop that will drive this server
let mut l = futures_mio::Loop::new().unwrap();
let mut l = tokio_core::Loop::new().unwrap();

// Create a TCP listener which will listen for incoming connections
let server = l.handle().tcp_listen(&addr);
Expand Down
11 changes: 5 additions & 6 deletions src/bin/sink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,21 @@
#[macro_use]
extern crate futures;
extern crate futures_io;
extern crate futures_mio;
extern crate tokio_core;

use std::env;
use std::iter;
use std::net::SocketAddr;

use futures::Future;
use futures::stream::{self, Stream};
use futures_io::IoFuture;
use tokio_core::io::IoFuture;

fn main() {
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
let addr = addr.parse::<SocketAddr>().unwrap();

let mut l = futures_mio::Loop::new().unwrap();
let mut l = tokio_core::Loop::new().unwrap();
let server = l.handle().tcp_listen(&addr).and_then(|socket| {
socket.incoming().and_then(|(socket, addr)| {
println!("got a socket: {}", addr);
Expand All @@ -34,10 +33,10 @@ fn main() {
l.run(server).unwrap();
}

fn write(socket: futures_mio::TcpStream) -> IoFuture<()> {
fn write(socket: tokio_core::TcpStream) -> IoFuture<()> {
static BUF: &'static [u8] = &[0; 64 * 1024];
let iter = iter::repeat(()).map(|()| Ok(()));
stream::iter(iter).fold(socket, |socket, ()| {
futures_io::write_all(socket, BUF).map(|(socket, _)| socket)
tokio_core::io::write_all(socket, BUF).map(|(socket, _)| socket)
}).map(|_| ()).boxed()
}
2 changes: 1 addition & 1 deletion src/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ use std::sync::mpsc::TryRecvError;

use futures::{Future, Poll};
use futures::stream::Stream;
use futures_io::IoFuture;
use mio::channel;

use {ReadinessStream, LoopHandle};
use io::IoFuture;

/// The transmission half of a channel used for sending messages to a receiver.
///
Expand Down
82 changes: 82 additions & 0 deletions src/io/copy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use std::io::{self, Read, Write};

use futures::{Future, Poll};

/// A future which will copy all data from a reader into a writer.
///
/// Created by the `copy` function, this future will resolve to the number of
/// bytes copied or an error if one happens.
pub struct Copy<R, W> {
reader: R,
read_done: bool,
writer: W,
pos: usize,
cap: usize,
amt: u64,
buf: Box<[u8]>,
}

/// Creates a future which represents copying all the bytes from one object to
/// another.
///
/// The returned future will copy all the bytes read from `reader` into the
/// `writer` specified. This future will only complete once the `reader` has hit
/// EOF and all bytes have been written to and flushed from the `writer`
/// provided.
///
/// On success the number of bytes is returned and the `reader` and `writer` are
/// consumed. On error the error is returned and the I/O objects are consumed as
/// well.
pub fn copy<R, W>(reader: R, writer: W) -> Copy<R, W>
where R: Read,
W: Write,
{
Copy {
reader: reader,
read_done: false,
writer: writer,
amt: 0,
pos: 0,
cap: 0,
buf: Box::new([0; 2048]),
}
}

impl<R, W> Future for Copy<R, W>
where R: Read,
W: Write,
{
type Item = u64;
type Error = io::Error;

fn poll(&mut self) -> Poll<u64, io::Error> {
loop {
// If our buffer is empty, then we need to read some data to
// continue.
if self.pos == self.cap && !self.read_done {
let n = try_nb!(self.reader.read(&mut self.buf));
if n == 0 {
self.read_done = true;
} else {
self.pos = 0;
self.cap = n;
}
}

// If our buffer has some data, let's write it out!
while self.pos < self.cap {
let i = try_nb!(self.writer.write(&self.buf[self.pos..self.cap]));
self.pos += i;
self.amt += i as u64;
}

// If we've written al the data and we've seen EOF, flush out the
// data and finish the transfer.
// done with the entire transfer.
if self.pos == self.cap && self.read_done {
try_nb!(self.writer.flush());
return Poll::Ok(self.amt)
}
}
}
}
39 changes: 39 additions & 0 deletions src/io/flush.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use std::io::{self, Write};

use futures::{Poll, Future};

/// A future used to fully flush an I/O object.
///
/// Resolves to the underlying I/O object once the flush operation is complete.
///
/// Created by the `flush` function.
pub struct Flush<A> {
a: Option<A>,
}

/// Creates a future which will entirely flush an I/O object and then yield the
/// object itself.
///
/// This function will consume the object provided if an error happens, and
/// otherwise it will repeatedly call `flush` until it sees `Ok(())`, scheduling
/// a retry if `WouldBlock` is seen along the way.
pub fn flush<A>(a: A) -> Flush<A>
where A: Write,
{
Flush {
a: Some(a),
}
}

impl<A> Future for Flush<A>
where A: Write,
{
type Item = A;
type Error = io::Error;

fn poll(&mut self) -> Poll<A, io::Error> {
try_nb!(self.a.as_mut().unwrap().flush());
Poll::Ok(self.a.take().unwrap())
}
}

47 changes: 47 additions & 0 deletions src/io/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//! I/O conveniences when working with primitives in `tokio-core`
//!
//! Contains various combinators to work with I/O objects and type definitions
//! as well.
use std::io;

use futures::BoxFuture;
use futures::stream::BoxStream;

/// A convenience typedef around a `Future` whose error component is `io::Error`
pub type IoFuture<T> = BoxFuture<T, io::Error>;

/// A convenience typedef around a `Stream` whose error component is `io::Error`
pub type IoStream<T> = BoxStream<T, io::Error>;

/// A convenience macro for working with `io::Result<T>` from the `Read` and
/// `Write` traits.
///
/// This macro takes `io::Result<T>` as input, and returns `T` as the output. If
/// the input type is of the `Err` variant, then `Poll::NotReady` is returned if
/// it indicates `WouldBlock` or otherwise `Err` is returned.
#[macro_export]
macro_rules! try_nb {
($e:expr) => (match $e {
Ok(t) => t,
Err(ref e) if e.kind() == ::std::io::ErrorKind::WouldBlock => {
return ::futures::Poll::NotReady
}
Err(e) => return ::futures::Poll::Err(e.into()),
})
}

mod copy;
mod flush;
mod read_exact;
mod read_to_end;
mod task;
mod window;
mod write_all;
pub use self::copy::{copy, Copy};
pub use self::flush::{flush, Flush};
pub use self::read_exact::{read_exact, ReadExact};
pub use self::read_to_end::{read_to_end, ReadToEnd};
pub use self::task::{TaskIo, TaskIoRead, TaskIoWrite};
pub use self::window::Window;
pub use self::write_all::{write_all, WriteAll};
Loading

0 comments on commit f107c8d

Please sign in to comment.