Allow registration with empty interest (#640)

In order to temporarily disable event listening for a specific handle,
it may be convenient to reregister it with an empty interest.

This avoids to temporarily deregister the handle before registering it
again (which, by the way, is not supported on Windows[1]).

Therefore, remove the check that prohibited registration with empty
interest.

Note that ERROR and HUP may still be triggered in that case.

[1]: https://github.com/carllerche/mio/issues/633
diff --git a/src/poll.rs b/src/poll.rs
index d14d96d..8078629 100644
--- a/src/poll.rs
+++ b/src/poll.rs
@@ -11,8 +11,6 @@
 use std::sync::atomic::{AtomicUsize, AtomicPtr, AtomicBool};
 use std::sync::atomic::Ordering::{self, Acquire, Release, AcqRel, Relaxed, SeqCst};
 use std::time::{Duration, Instant};
-#[cfg(all(unix, not(target_os = "fuchsia")))]
-use sys::unix::UnixReady;
 
 // Poll is backed by two readiness queues. The first is a system readiness queue
 // represented by `sys::Selector`. The system readiness queue handles events
@@ -776,7 +774,7 @@
     pub fn register<E: ?Sized>(&self, handle: &E, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()>
         where E: Evented
     {
-        validate_args(token, interest)?;
+        validate_args(token)?;
 
         /*
          * Undefined behavior:
@@ -847,7 +845,7 @@
     pub fn reregister<E: ?Sized>(&self, handle: &E, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()>
         where E: Evented
     {
-        validate_args(token, interest)?;
+        validate_args(token)?;
 
         trace!("registering with poller");
 
@@ -1170,31 +1168,11 @@
     }
 }
 
-#[cfg(all(unix, not(target_os = "fuchsia")))]
-fn registerable(interest: Ready) -> bool {
-    let unixinterest = UnixReady::from(interest);
-    unixinterest.is_readable() || unixinterest.is_writable() || unixinterest.is_aio()
-}
-
-#[cfg(target_os = "fuchsia")]
-fn registerable(interest: Ready) -> bool {
-    event::ready_as_usize(interest) != 0
-}
-
-#[cfg(not(unix))]
-fn registerable(interest: Ready) -> bool {
-    interest.is_readable() || interest.is_writable()
-}
-
-fn validate_args(token: Token, interest: Ready) -> io::Result<()> {
+fn validate_args(token: Token) -> io::Result<()> {
     if token == AWAKEN {
         return Err(io::Error::new(io::ErrorKind::Other, "invalid token"));
     }
 
-    if !registerable(interest) {
-        return Err(io::Error::new(io::ErrorKind::Other, "interest must include readable or writable or aio"));
-    }
-
     Ok(())
 }
 
diff --git a/test/test_register_deregister.rs b/test/test_register_deregister.rs
index a6f50e3..a82698f 100644
--- a/test/test_register_deregister.rs
+++ b/test/test_register_deregister.rs
@@ -1,5 +1,6 @@
-use {localhost, TryWrite};
-use mio::*;
+use {expect_events, localhost, TryWrite};
+use mio::{Events, Poll, PollOpt, Ready, Token};
+use mio::event::Event;
 use mio::net::{TcpListener, TcpStream};
 use bytes::SliceBuf;
 use std::time::Duration;
@@ -93,15 +94,30 @@
 }
 
 #[test]
-pub fn test_register_with_no_readable_writable_is_error() {
+pub fn test_register_empty_interest() {
     let poll = Poll::new().unwrap();
+    let mut events = Events::with_capacity(1024);
     let addr = localhost();
 
     let sock = TcpListener::bind(&addr).unwrap();
 
-    assert!(poll.register(&sock, Token(0), Ready::empty(), PollOpt::edge()).is_err());
+    poll.register(&sock, Token(0), Ready::empty(), PollOpt::edge()).unwrap();
 
-    poll.register(&sock, Token(0), Ready::readable(), PollOpt::edge()).unwrap();
+    let client = TcpStream::connect(&addr).unwrap();
 
-    assert!(poll.reregister(&sock, Token(0), Ready::empty(), PollOpt::edge()).is_err());
+    // The connect is not guaranteed to have started until it is registered
+    // https://docs.rs/mio/0.6.10/mio/struct.Poll.html#registering-handles
+    poll.register(&client, Token(1), Ready::empty(), PollOpt::edge()).unwrap();
+
+    // sock is registered with empty interest, we should not receive any event
+    poll.poll(&mut events, Some(Duration::from_millis(100))).unwrap();
+    assert_eq!(events.len(), 0, "Received unexpected event: {:?}", events.get(0).unwrap());
+
+    // now sock is reregistered with readable, we should receive the pending event
+    poll.reregister(&sock, Token(0), Ready::readable(), PollOpt::edge()).unwrap();
+    expect_events(&poll, &mut events, 2, vec![
+        Event::new(Ready::readable(), Token(0))
+    ]);
+
+    poll.reregister(&sock, Token(0), Ready::empty(), PollOpt::edge()).unwrap();
 }