From 0a3dc0bb75203107ab44991b8548094cca70ec31 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 4 Nov 2016 09:12:00 -0700 Subject: [PATCH] Add a method to manually deregister an I/O object Typically this happens automatically as the `E` in `PollEvented` is an owned reference (e.g. a `TcpStream`) where dropping that will close the resource, automatically unregistering it from the event loop. In some situations, however, this isn't always the case, so the deregistering needs to happen manually. --- src/reactor/mod.rs | 4 ++++ src/reactor/poll_evented.rs | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/reactor/mod.rs b/src/reactor/mod.rs index eab8cfe2f..6add6141b 100644 --- a/src/reactor/mod.rs +++ b/src/reactor/mod.rs @@ -435,6 +435,10 @@ impl Inner { Ok((sched.readiness.clone(), entry.insert(sched).index())) } + fn deregister_source(&mut self, source: &mio::Evented) -> io::Result<()> { + self.io.deregister(source) + } + fn drop_source(&mut self, token: usize) { debug!("dropping I/O source: {}", token); self.io_dispatch.remove(token).unwrap(); diff --git a/src/reactor/poll_evented.rs b/src/reactor/poll_evented.rs index 5dd897136..e3d6ee149 100644 --- a/src/reactor/poll_evented.rs +++ b/src/reactor/poll_evented.rs @@ -53,6 +53,27 @@ impl PollEvented { io: io, }) } + + /// Deregisters this source of events from the reactor core specified. + /// + /// This method can optionally be called to unregister the underlying I/O + /// object with the event loop that the `handle` provided points to. + /// Typically this method is not required as this automatically happens when + /// `E` is dropped, but for some use cases the `E` object doesn't represent + /// an owned reference, so dropping it won't automatically unreigster with + /// the event loop. + /// + /// This consumes `self` as it will no longer provide events after the + /// 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.inner.upgrade() { + Some(inner) => inner, + None => return Ok(()), + }; + let ret = inner.borrow_mut().deregister_source(&self.io); + return ret + } } impl PollEvented {