@@ -17,6 +17,8 @@ and create receivers which will receive notifications after a period of time.
17
17
18
18
*/
19
19
20
+ // FIXME: These functions take Durations but only pass ms to the backend impls.
21
+
20
22
use comm:: { Receiver , Sender , channel} ;
21
23
use time:: Duration ;
22
24
use io:: { IoResult , IoError } ;
@@ -71,13 +73,15 @@ pub struct Timer {
71
73
struct TimerCallback { tx : Sender < ( ) > }
72
74
73
75
fn in_ms ( d : Duration ) -> u64 {
74
- // FIXME: Do we really want to fail on negative duration?
75
76
let ms = d. num_milliseconds ( ) ;
76
- if ms < 0 { fail ! ( "negative duration" ) }
77
+ if ms < 0 { return 0 } ;
77
78
return ms as u64 ;
78
79
}
79
80
80
81
/// Sleep the current task for the specified duration.
82
+ ///
83
+ /// When provided a zero or negative `duration`, the function will
84
+ /// return immediately.
81
85
pub fn sleep ( duration : Duration ) {
82
86
let timer = Timer :: new ( ) ;
83
87
let mut timer = timer. ok ( ) . expect ( "timer::sleep: could not create a Timer" ) ;
@@ -99,8 +103,14 @@ impl Timer {
99
103
///
100
104
/// Note that this function will cause any other receivers for this timer to
101
105
/// be invalidated (the other end will be closed).
106
+ ///
107
+ /// When provided a zero or negative `duration`, the function will
108
+ /// return immediately.
102
109
pub fn sleep ( & mut self , duration : Duration ) {
103
- self . obj . sleep ( in_ms ( duration) ) ;
110
+ // Short-circuit the timer backend for 0 duration
111
+ let ms = in_ms ( duration) ;
112
+ if ms == 0 { return }
113
+ self . obj . sleep ( ms) ;
104
114
}
105
115
106
116
/// Creates a oneshot receiver which will have a notification sent when
@@ -137,9 +147,17 @@ impl Timer {
137
147
/// // The timer object was destroyed, so this will always fail:
138
148
/// // five_ms.recv()
139
149
/// ```
150
+ ///
151
+ /// When provided a zero or negative `duration`, the message will
152
+ /// be sent immediately.
140
153
pub fn oneshot ( & mut self , duration : Duration ) -> Receiver < ( ) > {
141
154
let ( tx, rx) = channel ( ) ;
142
- self . obj . oneshot ( in_ms ( duration) , box TimerCallback { tx : tx } ) ;
155
+ // Short-circuit the timer backend for 0 duration
156
+ if in_ms ( duration) != 0 {
157
+ self . obj . oneshot ( in_ms ( duration) , box TimerCallback { tx : tx } ) ;
158
+ } else {
159
+ tx. send ( ( ) ) ;
160
+ }
143
161
return rx
144
162
}
145
163
@@ -185,9 +203,17 @@ impl Timer {
185
203
/// // The timer object was destroyed, so this will always fail:
186
204
/// // five_ms.recv()
187
205
/// ```
206
+ ///
207
+ /// When provided a zero or negative `duration`, the messages will
208
+ /// be sent without delay.
188
209
pub fn periodic ( & mut self , duration : Duration ) -> Receiver < ( ) > {
210
+ let ms = in_ms ( duration) ;
211
+ // FIXME: The backend implementations don't ever send a message
212
+ // if given a 0 ms duration. Temporarily using 1ms. It's
213
+ // not clear what use a 0ms period is anyway...
214
+ let ms = if ms == 0 { 1 } else { ms } ;
189
215
let ( tx, rx) = channel ( ) ;
190
- self . obj . period ( in_ms ( duration ) , box TimerCallback { tx : tx } ) ;
216
+ self . obj . period ( ms , box TimerCallback { tx : tx } ) ;
191
217
return rx
192
218
}
193
219
}
@@ -200,8 +226,6 @@ impl Callback for TimerCallback {
200
226
201
227
#[ cfg( test) ]
202
228
mod test {
203
- use time:: Duration ;
204
-
205
229
iotest ! ( fn test_io_timer_sleep_simple( ) {
206
230
let mut timer = Timer :: new( ) . unwrap( ) ;
207
231
timer. sleep( Duration :: milliseconds( 1 ) ) ;
@@ -214,20 +238,20 @@ mod test {
214
238
215
239
iotest ! ( fn test_io_timer_sleep_oneshot_forget( ) {
216
240
let mut timer = Timer :: new( ) . unwrap( ) ;
217
- timer. oneshot( Duration :: milliseconds( 100000000000 ) ) ;
241
+ timer. oneshot( Duration :: milliseconds( 100000000 ) ) ;
218
242
} )
219
243
220
244
iotest ! ( fn oneshot_twice( ) {
221
245
let mut timer = Timer :: new( ) . unwrap( ) ;
222
246
let rx1 = timer. oneshot( Duration :: milliseconds( 10000 ) ) ;
223
- let rx = timer. oneshot( 1 ) ;
247
+ let rx = timer. oneshot( Duration :: milliseconds ( 1 ) ) ;
224
248
rx. recv( ) ;
225
249
assert_eq!( rx1. recv_opt( ) , Err ( ( ) ) ) ;
226
250
} )
227
251
228
252
iotest ! ( fn test_io_timer_oneshot_then_sleep( ) {
229
253
let mut timer = Timer :: new( ) . unwrap( ) ;
230
- let rx = timer. oneshot( Duration :: milliseconds( 100000000000 ) ) ;
254
+ let rx = timer. oneshot( Duration :: milliseconds( 100000000 ) ) ;
231
255
timer. sleep( Duration :: milliseconds( 1 ) ) ; // this should invalidate rx
232
256
233
257
assert_eq!( rx. recv_opt( ) , Err ( ( ) ) ) ;
@@ -243,7 +267,7 @@ mod test {
243
267
244
268
iotest ! ( fn test_io_timer_sleep_periodic_forget( ) {
245
269
let mut timer = Timer :: new( ) . unwrap( ) ;
246
- timer. periodic( Duration :: milliseconds( 100000000000 ) ) ;
270
+ timer. periodic( Duration :: milliseconds( 100000000 ) ) ;
247
271
} )
248
272
249
273
iotest ! ( fn test_io_timer_sleep_standalone( ) {
@@ -277,7 +301,7 @@ mod test {
277
301
let rx = timer. periodic( Duration :: milliseconds( 1 ) ) ;
278
302
rx. recv( ) ;
279
303
rx. recv( ) ;
280
- let rx2 = timer. periodic( Durtion :: milliseconds( 1 ) ) ;
304
+ let rx2 = timer. periodic( Duration :: milliseconds( 1 ) ) ;
281
305
rx2. recv( ) ;
282
306
rx2. recv( ) ;
283
307
} )
@@ -375,4 +399,45 @@ mod test {
375
399
// callback do something terrible.
376
400
timer2. sleep( Duration :: milliseconds( 2 ) ) ;
377
401
} )
402
+
403
+ iotest ! ( fn sleep_zero( ) {
404
+ let mut timer = Timer :: new( ) . unwrap( ) ;
405
+ timer. sleep( Duration :: milliseconds( 0 ) ) ;
406
+ } )
407
+
408
+ iotest ! ( fn sleep_negative( ) {
409
+ let mut timer = Timer :: new( ) . unwrap( ) ;
410
+ timer. sleep( Duration :: milliseconds( -1000000 ) ) ;
411
+ } )
412
+
413
+ iotest ! ( fn oneshot_zero( ) {
414
+ let mut timer = Timer :: new( ) . unwrap( ) ;
415
+ let rx = timer. oneshot( Duration :: milliseconds( 0 ) ) ;
416
+ rx. recv( ) ;
417
+ } )
418
+
419
+ iotest ! ( fn oneshot_negative( ) {
420
+ let mut timer = Timer :: new( ) . unwrap( ) ;
421
+ let rx = timer. oneshot( Duration :: milliseconds( -1000000 ) ) ;
422
+ rx. recv( ) ;
423
+ } )
424
+
425
+ iotest ! ( fn periodic_zero( ) {
426
+ let mut timer = Timer :: new( ) . unwrap( ) ;
427
+ let rx = timer. periodic( Duration :: milliseconds( 0 ) ) ;
428
+ rx. recv( ) ;
429
+ rx. recv( ) ;
430
+ rx. recv( ) ;
431
+ rx. recv( ) ;
432
+ } )
433
+
434
+ iotest ! ( fn periodic_negative( ) {
435
+ let mut timer = Timer :: new( ) . unwrap( ) ;
436
+ let rx = timer. periodic( Duration :: milliseconds( -1000000 ) ) ;
437
+ rx. recv( ) ;
438
+ rx. recv( ) ;
439
+ rx. recv( ) ;
440
+ rx. recv( ) ;
441
+ } )
442
+
378
443
}
0 commit comments