diff --git a/src/reactor/mod.rs b/src/reactor/mod.rs index 23d93bc45..c2d80de7a 100644 --- a/src/reactor/mod.rs +++ b/src/reactor/mod.rs @@ -137,6 +137,13 @@ enum Message { Run(Box), } +#[repr(usize)] +#[derive(Clone, Copy, Debug, PartialEq)] +enum Readiness { + Readable = 1, + Writable = 2, +} + const TOKEN_MESSAGES: mio::Token = mio::Token(0); const TOKEN_FUTURE: mio::Token = mio::Token(1); const TOKEN_START: usize = 2; @@ -321,11 +328,13 @@ impl Core { if let Some(io) = inner.io_dispatch.get_mut(token) { if ready.is_readable() || ready.is_hup() { reader = io.reader.take(); - io.readiness.fetch_or(1, Ordering::Relaxed); + io.readiness.fetch_or(Readiness::Readable as usize, + Ordering::Relaxed); } if ready.is_writable() { writer = io.writer.take(); - io.readiness.fetch_or(2, Ordering::Relaxed); + io.readiness.fetch_or(Readiness::Writable as usize, + Ordering::Relaxed); } } drop(inner); @@ -480,8 +489,8 @@ impl Inner { debug!("scheduling direction for: {}", token); let sched = self.io_dispatch.get_mut(token).unwrap(); let (slot, bit) = match dir { - Direction::Read => (&mut sched.reader, 1), - Direction::Write => (&mut sched.writer, 2), + Direction::Read => (&mut sched.reader, Readiness::Readable as usize), + Direction::Write => (&mut sched.writer, Readiness::Writable as usize), }; if sched.readiness.load(Ordering::SeqCst) & bit != 0 { *slot = None; diff --git a/src/reactor/poll_evented.rs b/src/reactor/poll_evented.rs index c92ce5812..a957d824a 100644 --- a/src/reactor/poll_evented.rs +++ b/src/reactor/poll_evented.rs @@ -15,6 +15,7 @@ use mio; use io::Io; use reactor::{Handle, Remote}; +use reactor::Readiness::*; use reactor::io_token::IoToken; /// A concrete implementation of a stream of readiness notifications for I/O @@ -98,11 +99,11 @@ impl PollEvented { /// to call from within the context of a future's task, typically done in a /// `Future::poll` method. pub fn poll_read(&self) -> Async<()> { - if self.readiness.load(Ordering::SeqCst) & 1 != 0 { + if self.readiness.load(Ordering::SeqCst) & Readable as usize != 0 { return Async::Ready(()) } self.readiness.fetch_or(self.token.take_readiness(), Ordering::SeqCst); - if self.readiness.load(Ordering::SeqCst) & 1 != 0 { + if self.readiness.load(Ordering::SeqCst) & Readable as usize != 0 { Async::Ready(()) } else { self.token.schedule_read(&self.handle); @@ -118,11 +119,11 @@ impl PollEvented { /// to call from within the context of a future's task, typically done in a /// `Future::poll` method. pub fn poll_write(&self) -> Async<()> { - if self.readiness.load(Ordering::SeqCst) & 2 != 0 { + if self.readiness.load(Ordering::SeqCst) & Writable as usize != 0 { return Async::Ready(()) } self.readiness.fetch_or(self.token.take_readiness(), Ordering::SeqCst); - if self.readiness.load(Ordering::SeqCst) & 2 != 0 { + if self.readiness.load(Ordering::SeqCst) & Writable as usize != 0 { Async::Ready(()) } else { self.token.schedule_write(&self.handle); @@ -146,7 +147,7 @@ impl PollEvented { /// previously indicated that the object is readable. That is, this function /// must always be paired with calls to `poll_read` previously. pub fn need_read(&self) { - self.readiness.fetch_and(!1, Ordering::SeqCst); + self.readiness.fetch_and(!(Readable as usize), Ordering::SeqCst); self.token.schedule_read(&self.handle) } @@ -166,7 +167,7 @@ impl PollEvented { /// previously indicated that the object is writable. That is, this function /// must always be paired with calls to `poll_write` previously. pub fn need_write(&self) { - self.readiness.fetch_and(!2, Ordering::SeqCst); + self.readiness.fetch_and(!(Writable as usize), Ordering::SeqCst); self.token.schedule_write(&self.handle) }