@@ -69,20 +69,20 @@ pub struct Condvar { inner: Box<StaticCondvar> }
69
69
/// # Examples
70
70
///
71
71
/// ```
72
- /// # #![feature(std_misc )]
72
+ /// # #![feature(static_condvar )]
73
73
/// use std::sync::{StaticCondvar, CONDVAR_INIT};
74
74
///
75
75
/// static CVAR: StaticCondvar = CONDVAR_INIT;
76
76
/// ```
77
- #[ unstable( feature = "std_misc " ,
77
+ #[ unstable( feature = "static_condvar " ,
78
78
reason = "may be merged with Condvar in the future" ) ]
79
79
pub struct StaticCondvar {
80
80
inner : sys:: Condvar ,
81
81
mutex : AtomicUsize ,
82
82
}
83
83
84
84
/// Constant initializer for a statically allocated condition variable.
85
- #[ unstable( feature = "std_misc " ,
85
+ #[ unstable( feature = "static_condvar " ,
86
86
reason = "may be merged with Condvar in the future" ) ]
87
87
pub const CONDVAR_INIT : StaticCondvar = StaticCondvar {
88
88
inner : sys:: CONDVAR_INIT ,
@@ -161,6 +161,30 @@ impl Condvar {
161
161
}
162
162
}
163
163
164
+ /// Waits on this condition variable for a notification, timing out after a
165
+ /// specified duration.
166
+ ///
167
+ /// The semantics of this function are equivalent to `wait()` except that
168
+ /// the thread will be blocked for roughly no longer than `dur`. This
169
+ /// method should not be used for precise timing due to anomalies such as
170
+ /// preemption or platform differences that may not cause the maximum
171
+ /// amount of time waited to be precisely `dur`.
172
+ ///
173
+ /// The returned boolean is `false` only if the timeout is known
174
+ /// to have elapsed.
175
+ ///
176
+ /// Like `wait`, the lock specified will be re-acquired when this function
177
+ /// returns, regardless of whether the timeout elapsed or not.
178
+ #[ unstable( feature = "wait_timeout" , reason = "waiting for Duration" ) ]
179
+ pub fn wait_timeout < ' a , T > ( & self , guard : MutexGuard < ' a , T > ,
180
+ dur : Duration )
181
+ -> LockResult < ( MutexGuard < ' a , T > , bool ) > {
182
+ unsafe {
183
+ let me: & ' static Condvar = & * ( self as * const _ ) ;
184
+ me. inner . wait_timeout ( guard, dur)
185
+ }
186
+ }
187
+
164
188
/// Waits on this condition variable for a notification, timing out after a
165
189
/// specified duration.
166
190
///
@@ -214,7 +238,7 @@ impl StaticCondvar {
214
238
/// notification.
215
239
///
216
240
/// See `Condvar::wait`.
217
- #[ unstable( feature = "std_misc " ,
241
+ #[ unstable( feature = "static_condvar " ,
218
242
reason = "may be merged with Condvar in the future" ) ]
219
243
pub fn wait < ' a , T > ( & ' static self , guard : MutexGuard < ' a , T > )
220
244
-> LockResult < MutexGuard < ' a , T > > {
@@ -235,14 +259,27 @@ impl StaticCondvar {
235
259
/// specified duration.
236
260
///
237
261
/// See `Condvar::wait_timeout`.
238
- #[ unstable( feature = "std_misc " ,
262
+ #[ unstable( feature = "static_condvar " ,
239
263
reason = "may be merged with Condvar in the future" ) ]
240
264
pub fn wait_timeout_ms < ' a , T > ( & ' static self , guard : MutexGuard < ' a , T > , ms : u32 )
241
265
-> LockResult < ( MutexGuard < ' a , T > , bool ) > {
266
+ self . wait_timeout ( guard, Duration :: from_millis ( ms as u64 ) )
267
+ }
268
+
269
+ /// Waits on this condition variable for a notification, timing out after a
270
+ /// specified duration.
271
+ ///
272
+ /// See `Condvar::wait_timeout`.
273
+ #[ unstable( feature = "static_condvar" ,
274
+ reason = "may be merged with Condvar in the future" ) ]
275
+ pub fn wait_timeout < ' a , T > ( & ' static self ,
276
+ guard : MutexGuard < ' a , T > ,
277
+ timeout : Duration )
278
+ -> LockResult < ( MutexGuard < ' a , T > , bool ) > {
242
279
let ( poisoned, success) = unsafe {
243
280
let lock = mutex:: guard_lock ( & guard) ;
244
281
self . verify ( lock) ;
245
- let success = self . inner . wait_timeout ( lock, Duration :: milliseconds ( ms as i64 ) ) ;
282
+ let success = self . inner . wait_timeout ( lock, timeout ) ;
246
283
( mutex:: guard_poison ( & guard) . get ( ) , success)
247
284
} ;
248
285
if poisoned {
@@ -259,15 +296,16 @@ impl StaticCondvar {
259
296
/// passed and the function returns `false`.
260
297
///
261
298
/// See `Condvar::wait_timeout_with`.
262
- #[ unstable( feature = "std_misc " ,
299
+ #[ unstable( feature = "static_condvar " ,
263
300
reason = "may be merged with Condvar in the future" ) ]
264
301
pub fn wait_timeout_with < ' a , T , F > ( & ' static self ,
265
302
guard : MutexGuard < ' a , T > ,
266
303
dur : Duration ,
267
304
mut f : F )
268
305
-> LockResult < ( MutexGuard < ' a , T > , bool ) >
269
306
where F : FnMut ( LockResult < & mut T > ) -> bool {
270
- // This could be made more efficient by pushing the implementation into sys::condvar
307
+ // This could be made more efficient by pushing the implementation into
308
+ // sys::condvar
271
309
let start = SteadyTime :: now ( ) ;
272
310
let mut guard_result: LockResult < MutexGuard < ' a , T > > = Ok ( guard) ;
273
311
while !f ( guard_result
@@ -277,7 +315,7 @@ impl StaticCondvar {
277
315
let now = SteadyTime :: now ( ) ;
278
316
let consumed = & now - & start;
279
317
let guard = guard_result. unwrap_or_else ( |e| e. into_inner ( ) ) ;
280
- let res = self . wait_timeout_ms ( guard, ( dur - consumed) . num_milliseconds ( ) as u32 ) ;
318
+ let res = self . wait_timeout ( guard, dur - consumed) ;
281
319
let ( new_guard_result, no_timeout) = match res {
282
320
Ok ( ( new_guard, no_timeout) ) => ( Ok ( new_guard) , no_timeout) ,
283
321
Err ( err) => {
@@ -301,14 +339,14 @@ impl StaticCondvar {
301
339
/// Wakes up one blocked thread on this condvar.
302
340
///
303
341
/// See `Condvar::notify_one`.
304
- #[ unstable( feature = "std_misc " ,
342
+ #[ unstable( feature = "static_condvar " ,
305
343
reason = "may be merged with Condvar in the future" ) ]
306
344
pub fn notify_one ( & ' static self ) { unsafe { self . inner . notify_one ( ) } }
307
345
308
346
/// Wakes up all blocked threads on this condvar.
309
347
///
310
348
/// See `Condvar::notify_all`.
311
- #[ unstable( feature = "std_misc " ,
349
+ #[ unstable( feature = "static_condvar " ,
312
350
reason = "may be merged with Condvar in the future" ) ]
313
351
pub fn notify_all ( & ' static self ) { unsafe { self . inner . notify_all ( ) } }
314
352
@@ -318,7 +356,7 @@ impl StaticCondvar {
318
356
/// active users of the condvar, and this also doesn't prevent any future
319
357
/// users of the condvar. This method is required to be called to not leak
320
358
/// memory on all platforms.
321
- #[ unstable( feature = "std_misc " ,
359
+ #[ unstable( feature = "static_condvar " ,
322
360
reason = "may be merged with Condvar in the future" ) ]
323
361
pub unsafe fn destroy ( & ' static self ) {
324
362
self . inner . destroy ( )
@@ -447,7 +485,9 @@ mod tests {
447
485
static S : AtomicUsize = ATOMIC_USIZE_INIT ;
448
486
449
487
let g = M . lock ( ) . unwrap ( ) ;
450
- let ( g, success) = C . wait_timeout_with ( g, Duration :: nanoseconds ( 1000 ) , |_| false ) . unwrap ( ) ;
488
+ let ( g, success) = C . wait_timeout_with ( g, Duration :: new ( 0 , 1000 ) , |_| {
489
+ false
490
+ } ) . unwrap ( ) ;
451
491
assert ! ( !success) ;
452
492
453
493
let ( tx, rx) = channel ( ) ;
@@ -471,7 +511,8 @@ mod tests {
471
511
} ) ;
472
512
473
513
let mut state = 0 ;
474
- let ( _g, success) = C . wait_timeout_with ( g, Duration :: days ( 1 ) , |_| {
514
+ let day = 24 * 60 * 60 ;
515
+ let ( _g, success) = C . wait_timeout_with ( g, Duration :: new ( day, 0 ) , |_| {
475
516
assert_eq ! ( state, S . load( Ordering :: SeqCst ) ) ;
476
517
tx. send ( ( ) ) . unwrap ( ) ;
477
518
state += 1 ;
0 commit comments