1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
15 This module exposes the functionality to create timers, block the current task,
16 and create receivers which will receive notifications after a period of time.
24 use rt::rtio::{IoFactory, LocalIo, RtioTimer};
26 /// A synchronous timer object
28 /// Values of this type can be used to put the current task to sleep for a
29 /// period of time. Handles to this timer can also be created in the form of
30 /// receivers which will receive notifications over time.
37 /// use std::io::Timer;
39 /// let mut timer = Timer::new().unwrap();
40 /// timer.sleep(10); // block the task for awhile
42 /// let timeout = timer.oneshot(10);
44 /// timeout.recv(); // wait for the timeout to expire
46 /// let periodic = timer.periodic(10);
49 /// // this loop is only executed once every 10ms
54 /// If only sleeping is necessary, then a convenience api is provided through
55 /// the `io::timer` module.
60 /// use std::io::timer;
62 /// // Put this task to sleep for 5 seconds
63 /// timer::sleep(5000);
67 obj: Box<RtioTimer:Send>,
70 /// Sleep the current task for `msecs` milliseconds.
71 pub fn sleep(msecs: u64) {
72 let timer = Timer::new();
73 let mut timer = timer.ok().expect("timer::sleep: could not create a Timer");
79 /// Creates a new timer which can be used to put the current task to sleep
80 /// for a number of milliseconds, or to possibly create channels which will
81 /// get notified after an amount of time has passed.
82 pub fn new() -> IoResult<Timer> {
83 LocalIo::maybe_raise(|io| io.timer_init().map(|t| Timer { obj: t }))
86 /// Blocks the current task for `msecs` milliseconds.
88 /// Note that this function will cause any other receivers for this timer to
89 /// be invalidated (the other end will be closed).
90 pub fn sleep(&mut self, msecs: u64) {
91 self.obj.sleep(msecs);
94 /// Creates a oneshot receiver which will have a notification sent when
95 /// `msecs` milliseconds has elapsed. This does *not* block the current
96 /// task, but instead returns immediately.
98 /// Note that this invalidates any previous receiver which has been created
99 /// by this timer, and that the returned receiver will be invalidated once
100 /// the timer is destroyed (when it falls out of scope).
101 pub fn oneshot(&mut self, msecs: u64) -> Receiver<()> {
102 self.obj.oneshot(msecs)
105 /// Creates a receiver which will have a continuous stream of notifications
106 /// being sent every `msecs` milliseconds. This does *not* block the
107 /// current task, but instead returns immediately. The first notification
108 /// will not be received immediately, but rather after `msec` milliseconds
111 /// Note that this invalidates any previous receiver which has been created
112 /// by this timer, and that the returned receiver will be invalidated once
113 /// the timer is destroyed (when it falls out of scope).
114 pub fn periodic(&mut self, msecs: u64) -> Receiver<()> {
115 self.obj.period(msecs)
121 iotest!(fn test_io_timer_sleep_simple() {
122 let mut timer = Timer::new().unwrap();
126 iotest!(fn test_io_timer_sleep_oneshot() {
127 let mut timer = Timer::new().unwrap();
128 timer.oneshot(1).recv();
131 iotest!(fn test_io_timer_sleep_oneshot_forget() {
132 let mut timer = Timer::new().unwrap();
133 timer.oneshot(100000000000);
136 iotest!(fn oneshot_twice() {
137 let mut timer = Timer::new().unwrap();
138 let rx1 = timer.oneshot(10000);
139 let rx = timer.oneshot(1);
141 assert_eq!(rx1.recv_opt(), Err(()));
144 iotest!(fn test_io_timer_oneshot_then_sleep() {
145 let mut timer = Timer::new().unwrap();
146 let rx = timer.oneshot(100000000000);
147 timer.sleep(1); // this should inalidate rx
149 assert_eq!(rx.recv_opt(), Err(()));
152 iotest!(fn test_io_timer_sleep_periodic() {
153 let mut timer = Timer::new().unwrap();
154 let rx = timer.periodic(1);
160 iotest!(fn test_io_timer_sleep_periodic_forget() {
161 let mut timer = Timer::new().unwrap();
162 timer.periodic(100000000000);
165 iotest!(fn test_io_timer_sleep_standalone() {
169 iotest!(fn oneshot() {
170 let mut timer = Timer::new().unwrap();
172 let rx = timer.oneshot(1);
174 assert!(rx.recv_opt().is_err());
176 let rx = timer.oneshot(1);
178 assert!(rx.recv_opt().is_err());
181 iotest!(fn override() {
182 let mut timer = Timer::new().unwrap();
183 let orx = timer.oneshot(100);
184 let prx = timer.periodic(100);
186 assert_eq!(orx.recv_opt(), Err(()));
187 assert_eq!(prx.recv_opt(), Err(()));
188 timer.oneshot(1).recv();
191 iotest!(fn period() {
192 let mut timer = Timer::new().unwrap();
193 let rx = timer.periodic(1);
196 let rx2 = timer.periodic(1);
202 let mut timer = Timer::new().unwrap();
207 iotest!(fn oneshot_fail() {
208 let mut timer = Timer::new().unwrap();
209 let _rx = timer.oneshot(1);
213 iotest!(fn period_fail() {
214 let mut timer = Timer::new().unwrap();
215 let _rx = timer.periodic(1);
219 iotest!(fn normal_fail() {
220 let _timer = Timer::new().unwrap();
224 iotest!(fn closing_channel_during_drop_doesnt_kill_everything() {
226 let mut timer = Timer::new().unwrap();
227 let timer_rx = timer.periodic(1000);
230 let _ = timer_rx.recv_opt();
233 // when we drop the TimerWatcher we're going to destroy the channel,
234 // which must wake up the task on the other end
237 iotest!(fn reset_doesnt_switch_tasks() {
238 // similar test to the one above.
239 let mut timer = Timer::new().unwrap();
240 let timer_rx = timer.periodic(1000);
243 let _ = timer_rx.recv_opt();
249 iotest!(fn reset_doesnt_switch_tasks2() {
250 // similar test to the one above.
251 let mut timer = Timer::new().unwrap();
252 let timer_rx = timer.periodic(1000);
255 let _ = timer_rx.recv_opt();
261 iotest!(fn sender_goes_away_oneshot() {
263 let mut timer = Timer::new().unwrap();
266 assert_eq!(rx.recv_opt(), Err(()));
269 iotest!(fn sender_goes_away_period() {
271 let mut timer = Timer::new().unwrap();
274 assert_eq!(rx.recv_opt(), Err(()));
277 iotest!(fn receiver_goes_away_oneshot() {
278 let mut timer1 = Timer::new().unwrap();
280 let mut timer2 = Timer::new().unwrap();
281 // while sleeping, the prevous timer should fire and not have its
282 // callback do something terrible.
286 iotest!(fn receiver_goes_away_period() {
287 let mut timer1 = Timer::new().unwrap();
289 let mut timer2 = Timer::new().unwrap();
290 // while sleeping, the prevous timer should fire and not have its
291 // callback do something terrible.