From add747486db4f344a25dc23bb75ce75fd23054de Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Sat, 14 Sep 2013 19:24:32 +0200 Subject: [PATCH 1/2] Implement recv_timeout for std::comm *Port implementations --- src/libstd/rt/io/timer.rs | 70 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/src/libstd/rt/io/timer.rs b/src/libstd/rt/io/timer.rs index 53e4c4051e1c3..0711ec32ffb65 100644 --- a/src/libstd/rt/io/timer.rs +++ b/src/libstd/rt/io/timer.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use comm; +use kinds::Send; use option::{Option, Some, None}; use result::{Ok, Err}; use rt::io::{io_error}; @@ -48,10 +50,50 @@ impl Timer { } } +trait TimedPort { + fn recv_timeout(self, msecs: u64) -> Option; +} + +impl TimedPort for comm::PortOne { + + fn recv_timeout(self, msecs: u64) -> Option { + let mut tout = msecs; + let mut timer = Timer::new().unwrap(); + + while tout > 0 { + if self.peek() { return Some(self.recv()); } + timer.sleep(1000); + tout -= 1000; + } + + None + } +} + + +impl TimedPort for comm::Port { + + fn recv_timeout(self, msecs: u64) -> Option { + let mut tout = msecs; + let mut timer = Timer::new().unwrap(); + + while tout > 0 { + if self.peek() { return Some(self.recv()); } + timer.sleep(1000); + tout -= 1000; + } + + None + } +} + #[cfg(test)] mod test { use super::*; use rt::test::*; + use task; + use comm; + #[test] fn test_io_timer_sleep_simple() { do run_in_mt_newsched_task { @@ -66,4 +108,32 @@ mod test { sleep(1) } } + + #[test] + fn test_recv_timeout() { + do run_in_newsched_task { + let (p, c) = comm::stream::(); + do task::spawn { + let mut t = Timer::new().unwrap(); + t.sleep(1000); + c.send(1); + } + + assert!(p.recv_timeout(2000).unwrap() == 1); + } + } + + #[test] + fn test_recv_timeout_expire() { + do run_in_newsched_task { + let (p, c) = comm::stream::(); + do task::spawn { + let mut t = Timer::new().unwrap(); + t.sleep(3000); + c.send(1); + } + + assert!(p.recv_timeout(1000).is_none()); + } + } } From a161f1618b538440d0ac4487f8ebecd55415abe9 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Sun, 15 Sep 2013 22:05:06 +0200 Subject: [PATCH 2/2] Added a docstring + FIXME until the new implementation is done --- src/libstd/rt/io/timer.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/libstd/rt/io/timer.rs b/src/libstd/rt/io/timer.rs index 0711ec32ffb65..b0400a72f8310 100644 --- a/src/libstd/rt/io/timer.rs +++ b/src/libstd/rt/io/timer.rs @@ -51,6 +51,21 @@ impl Timer { } trait TimedPort { + + /** + * This implementation adds the required + * API for recv_timeout with an approximate + * but not safe behavior. + * + * Current implementations of this Trait for + * both PortOne and Port poll on the port every + * second to check for new messages. A correct + * implementation for recv_timeout should implement + * `SelectInner` and Select for UvTimer and re-write + * the sleep method around that. + * + * FIXME: (flaper87) #9195 + */ fn recv_timeout(self, msecs: u64) -> Option; }