Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions src/reactor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,85 @@ impl Remote {
}
}

/// Retrieves a `Handle` for the currently running reactor
///
/// Having to pass `Handle`s around can be frustrating. This function will retrieve
/// a handle from the current reactor when running on the same thread. This way, you
/// won't have to pass handles around if using the `Tokio` event loop to drive your
/// futures. As such, this function should be called from inside a reactor, otherwise
/// it will return an error. This means that:-
///
/// 1. you should call it from inside a futures combinator or `async` macros (this
/// includes `async_block`)
/// 2. you should run any future that calls this method using `Core::run()`.
///
/// # Examples
///
/// A simple TCP echo server:
///
/// ```no_run
/// extern crate futures;
/// extern crate tokio_io;
/// extern crate tokio_core;
///
/// use futures::{Future, Stream, lazy};
/// use tokio_io::io::copy;
/// use tokio_io::AsyncRead;
/// use tokio_core::net::TcpListener;
/// use tokio_core::reactor::{self, Core};
///
/// fn server() -> Box<Future<Item=(), Error=std::io::Error>> {
/// let server = lazy(|| {
/// // Get a handle to the current reactor
/// let handle = reactor::current().unwrap();
///
/// // Bind the server's socket
/// let addr = "127.0.0.1:12345".parse().unwrap();
/// let listener = TcpListener::bind(&addr, &handle).unwrap();
///
/// // Pull out a stream of sockets for incoming connections
/// listener.incoming().for_each(move |(sock, _)| {
/// // Split up the reading and writing parts of the
/// // socket
/// let (reader, writer) = sock.split();
///
/// // A future that echos the data and returns how
/// // many bytes were copied...
/// let bytes_copied = copy(reader, writer);
///
/// // ... after which we'll print what happened
/// let handle_conn = bytes_copied.map(|amt| {
/// println!("wrote {} bytes", amt.0)
/// }).map_err(|err| {
/// println!("IO error {:?}", err)
/// });
///
/// // Spawn the future as a concurrent task
/// handle.spawn(handle_conn);
///
/// Ok(())
/// })
/// });
///
/// Box::new(server)
/// }
///
/// fn main() {
/// // Create the event loop that will drive this server
/// let mut core = Core::new().unwrap();
/// // Spin up the server on the event loop
/// core.run(server()).unwrap();
/// }
/// ```
pub fn current() -> io::Result<Handle> {
if CURRENT_LOOP.is_set() {
CURRENT_LOOP.with(|lp| Ok(lp.handle()))
} else {
let msg = "tokio_core::reactor::current() called outside of a reactor";
Err(io::Error::new(io::ErrorKind::Other, msg))
}
}

impl<F> Executor<F> for Remote
where F: Future<Item = (), Error = ()> + Send + 'static,
{
Expand Down