Skip to content

Commit 13b0cef

Browse files
committed
---
yaml --- r: 127866 b: refs/heads/auto c: dc8b23b h: refs/heads/master v: v3
1 parent 676fdbd commit 13b0cef

File tree

2 files changed

+98
-1
lines changed

2 files changed

+98
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0
1313
refs/tags/release-0.3.1: 495bae036dfe5ec6ceafd3312b4dca48741e845b
1414
refs/tags/release-0.4: e828ea2080499553b97dfe33b3f4d472b4562ad7
1515
refs/tags/release-0.5: 7e3bcfbf21278251ee936ad53e92e9b719702d73
16-
refs/heads/auto: 657b679b158894556628f096a28aab364b605446
16+
refs/heads/auto: dc8b23bc1ffa227bdc7b95206c7b2dabe32818ac
1717
refs/heads/servo: af82457af293e2a842ba6b7759b70288da276167
1818
refs/tags/release-0.6: b4ebcfa1812664df5e142f0134a5faea3918544c
1919
refs/tags/0.1: b19db808c2793fe2976759b85a355c3ad8c8b336

branches/auto/src/libstd/io/timer.rs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ and create receivers which will receive notifications after a period of time.
1818
*/
1919

2020
use comm::{Receiver, Sender, channel};
21+
use time::Duration;
2122
use io::{IoResult, IoError};
2223
use kinds::Send;
2324
use boxed::Box;
25+
use num::{CheckedMul, CheckedAdd};
2426
use rt::rtio::{IoFactory, LocalIo, RtioTimer, Callback};
2527

2628
/// A synchronous timer object
@@ -69,6 +71,33 @@ pub struct Timer {
6971

7072
struct TimerCallback { tx: Sender<()> }
7173

74+
#[allow(missing_doc)]
75+
trait DurationExtension {
76+
fn in_ms(&self) -> u64;
77+
}
78+
79+
impl DurationExtension for Duration {
80+
fn in_ms(&self) -> u64 {
81+
if self.ndays() < 0 { fail!("negative duration") }
82+
let nanos = self.nnanoseconds() as u64;
83+
let secs = self.nseconds() as u64;
84+
let days = self.ndays() as u64;
85+
let nanos_in_ms = nanos / 1000;
86+
let secs_in_ms = secs.checked_mul(&1000).expect("overflow");
87+
let ms_per_day = 24 * 60 * 60 * 1000; // hours/day * min/hour * sec/min * ms/sec
88+
let days_in_ms = days.checked_mul(&ms_per_day).expect("overflow");
89+
let result = nanos_in_ms;
90+
let result = result.checked_add(&secs_in_ms).expect("overflow");
91+
let result = result.checked_add(&(days_in_ms as u64)).expect("overflow");
92+
return result;
93+
}
94+
}
95+
96+
/// Sleep the current task for the specified duration.
97+
pub fn sleep(duration: Duration) {
98+
sleep_ms(duration.in_ms())
99+
}
100+
72101
/// Sleep the current task for `msecs` milliseconds.
73102
pub fn sleep_ms(msecs: u64) {
74103
let timer = Timer::new();
@@ -87,6 +116,14 @@ impl Timer {
87116
}).map_err(IoError::from_rtio_error)
88117
}
89118

119+
/// Blocks the current task for the specified duration.
120+
///
121+
/// Note that this function will cause any other receivers for this timer to
122+
/// be invalidated (the other end will be closed).
123+
pub fn sleep(&mut self, duration: Duration) {
124+
self.obj.sleep(duration.in_ms());
125+
}
126+
90127
/// Blocks the current task for `msecs` milliseconds.
91128
///
92129
/// Note that this function will cause any other receivers for this timer to
@@ -95,6 +132,23 @@ impl Timer {
95132
self.obj.sleep(msecs);
96133
}
97134

135+
/// Creates a oneshot receiver which will have a notification sent when
136+
/// the specified duration has elapsed.
137+
///
138+
/// This does *not* block the current task, but instead returns immediately.
139+
///
140+
/// Note that this invalidates any previous receiver which has been created
141+
/// by this timer, and that the returned receiver will be invalidated once
142+
/// the timer is destroyed (when it falls out of scope). In particular, if
143+
/// this is called in method-chaining style, the receiver will be
144+
/// invalidated at the end of that statement, and all `recv` calls will
145+
/// fail.
146+
pub fn oneshot(&mut self, duration: Duration) -> Receiver<()> {
147+
let (tx, rx) = channel();
148+
self.obj.oneshot(duration.in_ms(), box TimerCallback { tx: tx });
149+
return rx
150+
}
151+
98152
/// Creates a oneshot receiver which will have a notification sent when
99153
/// `msecs` milliseconds has elapsed.
100154
///
@@ -135,6 +189,25 @@ impl Timer {
135189
return rx
136190
}
137191

192+
/// Creates a receiver which will have a continuous stream of notifications
193+
/// being sent each time the specified duration has elapsed.
194+
///
195+
/// This does *not* block the current task, but instead returns
196+
/// immediately. The first notification will not be received immediately,
197+
/// but rather after the first duration.
198+
///
199+
/// Note that this invalidates any previous receiver which has been created
200+
/// by this timer, and that the returned receiver will be invalidated once
201+
/// the timer is destroyed (when it falls out of scope). In particular, if
202+
/// this is called in method-chaining style, the receiver will be
203+
/// invalidated at the end of that statement, and all `recv` calls will
204+
/// fail.
205+
pub fn periodic(&mut self, duration: Duration) -> Receiver<()> {
206+
let (tx, rx) = channel();
207+
self.obj.period(duration.in_ms(), box TimerCallback { tx: tx });
208+
return rx
209+
}
210+
138211
/// Creates a receiver which will have a continuous stream of notifications
139212
/// being sent every `msecs` milliseconds.
140213
///
@@ -365,4 +438,28 @@ mod test {
365438
// callback do something terrible.
366439
timer2.sleep_ms(2);
367440
})
441+
442+
443+
iotest!(fn test_io_timer_sleep_duration_simple() {
444+
use time::Duration;
445+
let mut timer = Timer::new().unwrap();
446+
timer.sleep(Duration::seconds(1));
447+
})
448+
449+
iotest!(fn test_io_timer_sleep_oneshot_duration() {
450+
use time::Duration;
451+
let mut timer = Timer::new().unwrap();
452+
timer.oneshot(Duration::seconds(1)).recv();
453+
})
454+
455+
iotest!(fn test_io_timer_sleep_periodic_duration() {
456+
use time::Duration;
457+
let mut timer = Timer::new().unwrap();
458+
let rx = timer.periodic(Duration::seconds(1));
459+
rx.recv();
460+
rx.recv();
461+
rx.recv();
462+
})
463+
464+
368465
}

0 commit comments

Comments
 (0)