From 7c768fc046188fd6bb640fd1b3679a06d1404b4b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 5 Dec 2017 08:15:26 -0800 Subject: [PATCH] Remove the `Remote` type The `Handle` type is now `Send` and `Sync` so the `Remote` type no longer needs to exist. --- src/net/tcp.rs | 23 ++-------- src/reactor/io_token.rs | 12 ++--- src/reactor/mod.rs | 90 +++---------------------------------- src/reactor/poll_evented.rs | 8 ++-- 4 files changed, 20 insertions(+), 113 deletions(-) diff --git a/src/net/tcp.rs b/src/net/tcp.rs index 4d932a3af..d68cef398 100644 --- a/src/net/tcp.rs +++ b/src/net/tcp.rs @@ -82,26 +82,9 @@ impl TcpListener { return Err(e) }, Ok((sock, addr)) => { - // Fast path if we haven't left the event loop - if let Some(handle) = self.io.remote().handle() { - let io = try!(PollEvented::new(sock, &handle)); - return Ok((TcpStream { io: io }, addr)) - } - - // If we're off the event loop then send the socket back - // over there to get registered and then we'll get it back - // eventually. - let (tx, rx) = oneshot::channel(); - let remote = self.io.remote().clone(); - remote.run(move |handle| { - let res = PollEvented::new(sock, handle) - .map(move |io| { - (TcpStream { io: io }, addr) - }); - drop(tx.send(res)); - }); - self.pending_accept = Some(rx); - // continue to polling the `rx` at the beginning of the loop + let handle = self.io.handle(); + let io = try!(PollEvented::new(sock, &handle)); + return Ok((TcpStream { io: io }, addr)) } } } diff --git a/src/reactor/io_token.rs b/src/reactor/io_token.rs index c62ce0d83..6174228e3 100644 --- a/src/reactor/io_token.rs +++ b/src/reactor/io_token.rs @@ -3,12 +3,12 @@ use std::io; use mio::event::Evented; -use reactor::{Remote, Handle, Direction}; +use reactor::{Handle, Direction}; /// A token that identifies an active I/O resource. pub struct IoToken { token: usize, - handle: Remote, + handle: Handle, } impl IoToken { @@ -29,10 +29,10 @@ impl IoToken { /// associated with has gone away, or if there is an error communicating /// with the event loop. pub fn new(source: &Evented, handle: &Handle) -> io::Result { - match handle.remote.inner.upgrade() { + match handle.inner.upgrade() { Some(inner) => { let token = try!(inner.add_source(source)); - let handle = handle.remote().clone(); + let handle = handle.clone(); Ok(IoToken { token, handle }) } @@ -40,8 +40,8 @@ impl IoToken { } } - /// Returns a reference to the remote handle. - pub fn remote(&self) -> &Remote { + /// Returns a reference to this I/O token's event loop's handle. + pub fn handle(&self) -> &Handle { &self.handle } diff --git a/src/reactor/mod.rs b/src/reactor/mod.rs index 12df7c128..61d861436 100644 --- a/src/reactor/mod.rs +++ b/src/reactor/mod.rs @@ -72,30 +72,15 @@ struct Inner { io_dispatch: RwLock>, } -/// A remote handle to an event loop, for more information see [`Handle`]. +/// A handle to an event loop. /// -/// This handle can be cloned, and when cloned they will still refer to the -/// same underlying event loop. -/// -/// [`Handle`]: struct.Handle.html -#[derive(Clone)] -pub struct Remote { - id: usize, - inner: Weak, -} - -/// A handle to an event loop, used to construct I/O objects, send messages, and -/// otherwise interact indirectly with the event loop itself. -/// -/// Handles can be cloned, and when cloned they will still refer to the -/// same underlying event loop. -/// -/// Handles are non-sendable, see [`Remote`] for a sendable reference. -/// -/// [`Remote`]: struct.Remote.html +/// A `Handle` is used for associating I/O objects with an event loop +/// explicitly. Typically though you won't end up using a `Handle` that often +/// and will instead use and implicitly configured handle for your thread. #[derive(Clone)] pub struct Handle { - remote: Remote, + id: usize, + inner: Weak, } struct ScheduledIo { @@ -116,7 +101,6 @@ fn _assert_kinds() { fn _assert() {} _assert::(); - _assert::(); } impl Core { @@ -153,14 +137,7 @@ impl Core { /// This handle is typically passed into functions that create I/O objects /// to bind them to this event loop. pub fn handle(&self) -> Handle { - let remote = self.remote(); - Handle { remote } - } - - /// Generates a remote handle to this event loop which can be used to spawn - /// tasks from other threads into this event loop. - pub fn remote(&self) -> Remote { - Remote { + Handle { id: self.inner.id, inner: Arc::downgrade(&self.inner), } @@ -316,59 +293,6 @@ impl Inner { } } -impl Remote { - /// Attempts to "promote" this remote to a handle, if possible. - /// - /// This function is intended for structures which typically work through a - /// `Remote` but want to optimize runtime when the remote doesn't actually - /// leave the thread of the original reactor. This will attempt to return a - /// handle if the `Remote` is on the same thread as the event loop and the - /// event loop is running. - /// - /// If this `Remote` has moved to a different thread or if the event loop is - /// running, then `None` may be returned. If you need to guarantee access to - /// a `Handle`, then you can call this function and fall back to using - /// `spawn` above if it returns `None`. - pub fn handle(&self) -> Option { - let remote = self.clone(); - Some(Handle { remote } ) - } - - /// Spawns a new future into the event loop this remote is associated with. - /// - /// This function takes a closure which is executed within the context of - /// the I/O loop itself. The future returned by the closure will be - /// scheduled on the event loop and run to completion. - /// - /// Note that the closure, `F`, requires the `Send` bound as it might cross - /// threads. - /// - /// # Panics - /// - /// This method will **not** catch panics from polling the future `f`. If - /// the future panics then it's the responsibility of the caller to catch - /// that panic and handle it as appropriate. - pub(crate) fn run(&self, f: F) - where F: FnOnce(&Handle) + Send + 'static, - { - let handle = self.handle().unwrap(); - f(&handle); - } -} - -impl fmt::Debug for Remote { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f,"Remote") - } -} - -impl Handle { - /// Returns a reference to the underlying remote handle to the event loop. - pub fn remote(&self) -> &Remote { - &self.remote - } -} - impl fmt::Debug for Handle { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Handle") diff --git a/src/reactor/poll_evented.rs b/src/reactor/poll_evented.rs index 19f6081b0..52ba7e87c 100644 --- a/src/reactor/poll_evented.rs +++ b/src/reactor/poll_evented.rs @@ -15,7 +15,7 @@ use mio::event::Evented; use mio::Ready; use tokio_io::{AsyncRead, AsyncWrite}; -use reactor::{Handle, Remote}; +use reactor::Handle; use reactor::io_token::IoToken; /// A concrete implementation of a stream of readiness notifications for I/O @@ -103,7 +103,7 @@ impl PollEvented { /// 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, handle: &Handle) -> io::Result<()> { - let inner = match handle.remote.inner.upgrade() { + let inner = match handle.inner.upgrade() { Some(inner) => inner, None => return Ok(()), }; @@ -251,8 +251,8 @@ impl PollEvented { /// Returns a reference to the event loop handle that this readiness stream /// is associated with. - pub fn remote(&self) -> &Remote { - self.token.remote() + pub fn handle(&self) -> &Handle { + self.token.handle() } /// Returns a shared reference to the underlying I/O object this readiness