@@ -69,20 +69,20 @@ pub struct Condvar { inner: Box<StaticCondvar> }
6969/// # Examples
7070///
7171/// ```
72- /// # #![feature(std_misc )]
72+ /// # #![feature(static_condvar )]
7373/// use std::sync::{StaticCondvar, CONDVAR_INIT};
7474///
7575/// static CVAR: StaticCondvar = CONDVAR_INIT;
7676/// ```
77- #[ unstable( feature = "std_misc " ,
77+ #[ unstable( feature = "static_condvar " ,
7878 reason = "may be merged with Condvar in the future" ) ]
7979pub struct StaticCondvar {
8080 inner : sys:: Condvar ,
8181 mutex : AtomicUsize ,
8282}
8383
8484/// Constant initializer for a statically allocated condition variable.
85- #[ unstable( feature = "std_misc " ,
85+ #[ unstable( feature = "static_condvar " ,
8686 reason = "may be merged with Condvar in the future" ) ]
8787pub const CONDVAR_INIT : StaticCondvar = StaticCondvar {
8888 inner : sys:: CONDVAR_INIT ,
@@ -161,6 +161,30 @@ impl Condvar {
161161 }
162162 }
163163
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+
164188 /// Waits on this condition variable for a notification, timing out after a
165189 /// specified duration.
166190 ///
@@ -214,7 +238,7 @@ impl StaticCondvar {
214238 /// notification.
215239 ///
216240 /// See `Condvar::wait`.
217- #[ unstable( feature = "std_misc " ,
241+ #[ unstable( feature = "static_condvar " ,
218242 reason = "may be merged with Condvar in the future" ) ]
219243 pub fn wait < ' a , T > ( & ' static self , guard : MutexGuard < ' a , T > )
220244 -> LockResult < MutexGuard < ' a , T > > {
@@ -235,14 +259,27 @@ impl StaticCondvar {
235259 /// specified duration.
236260 ///
237261 /// See `Condvar::wait_timeout`.
238- #[ unstable( feature = "std_misc " ,
262+ #[ unstable( feature = "static_condvar " ,
239263 reason = "may be merged with Condvar in the future" ) ]
240264 pub fn wait_timeout_ms < ' a , T > ( & ' static self , guard : MutexGuard < ' a , T > , ms : u32 )
241265 -> 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 ) > {
242279 let ( poisoned, success) = unsafe {
243280 let lock = mutex:: guard_lock ( & guard) ;
244281 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 ) ;
246283 ( mutex:: guard_poison ( & guard) . get ( ) , success)
247284 } ;
248285 if poisoned {
@@ -259,15 +296,16 @@ impl StaticCondvar {
259296 /// passed and the function returns `false`.
260297 ///
261298 /// See `Condvar::wait_timeout_with`.
262- #[ unstable( feature = "std_misc " ,
299+ #[ unstable( feature = "static_condvar " ,
263300 reason = "may be merged with Condvar in the future" ) ]
264301 pub fn wait_timeout_with < ' a , T , F > ( & ' static self ,
265302 guard : MutexGuard < ' a , T > ,
266303 dur : Duration ,
267304 mut f : F )
268305 -> LockResult < ( MutexGuard < ' a , T > , bool ) >
269306 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
271309 let start = SteadyTime :: now ( ) ;
272310 let mut guard_result: LockResult < MutexGuard < ' a , T > > = Ok ( guard) ;
273311 while !f ( guard_result
@@ -277,12 +315,15 @@ impl StaticCondvar {
277315 let now = SteadyTime :: now ( ) ;
278316 let consumed = & now - & start;
279317 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 ) ;
281- let ( new_guard_result, no_timeout) = match res {
282- Ok ( ( new_guard, no_timeout) ) => ( Ok ( new_guard) , no_timeout) ,
283- Err ( err) => {
284- let ( new_guard, no_timeout) = err. into_inner ( ) ;
285- ( Err ( PoisonError :: new ( new_guard) ) , no_timeout)
318+ let ( new_guard_result, no_timeout) = if consumed > dur {
319+ ( Ok ( guard) , false )
320+ } else {
321+ match self . wait_timeout ( guard, dur - consumed) {
322+ Ok ( ( new_guard, no_timeout) ) => ( Ok ( new_guard) , no_timeout) ,
323+ Err ( err) => {
324+ let ( new_guard, no_timeout) = err. into_inner ( ) ;
325+ ( Err ( PoisonError :: new ( new_guard) ) , no_timeout)
326+ }
286327 }
287328 } ;
288329 guard_result = new_guard_result;
@@ -301,14 +342,14 @@ impl StaticCondvar {
301342 /// Wakes up one blocked thread on this condvar.
302343 ///
303344 /// See `Condvar::notify_one`.
304- #[ unstable( feature = "std_misc " ,
345+ #[ unstable( feature = "static_condvar " ,
305346 reason = "may be merged with Condvar in the future" ) ]
306347 pub fn notify_one ( & ' static self ) { unsafe { self . inner . notify_one ( ) } }
307348
308349 /// Wakes up all blocked threads on this condvar.
309350 ///
310351 /// See `Condvar::notify_all`.
311- #[ unstable( feature = "std_misc " ,
352+ #[ unstable( feature = "static_condvar " ,
312353 reason = "may be merged with Condvar in the future" ) ]
313354 pub fn notify_all ( & ' static self ) { unsafe { self . inner . notify_all ( ) } }
314355
@@ -318,7 +359,7 @@ impl StaticCondvar {
318359 /// active users of the condvar, and this also doesn't prevent any future
319360 /// users of the condvar. This method is required to be called to not leak
320361 /// memory on all platforms.
321- #[ unstable( feature = "std_misc " ,
362+ #[ unstable( feature = "static_condvar " ,
322363 reason = "may be merged with Condvar in the future" ) ]
323364 pub unsafe fn destroy ( & ' static self ) {
324365 self . inner . destroy ( )
@@ -447,7 +488,9 @@ mod tests {
447488 static S : AtomicUsize = ATOMIC_USIZE_INIT ;
448489
449490 let g = M . lock ( ) . unwrap ( ) ;
450- let ( g, success) = C . wait_timeout_with ( g, Duration :: nanoseconds ( 1000 ) , |_| false ) . unwrap ( ) ;
491+ let ( g, success) = C . wait_timeout_with ( g, Duration :: new ( 0 , 1000 ) , |_| {
492+ false
493+ } ) . unwrap ( ) ;
451494 assert ! ( !success) ;
452495
453496 let ( tx, rx) = channel ( ) ;
@@ -471,7 +514,8 @@ mod tests {
471514 } ) ;
472515
473516 let mut state = 0 ;
474- let ( _g, success) = C . wait_timeout_with ( g, Duration :: days ( 1 ) , |_| {
517+ let day = 24 * 60 * 60 ;
518+ let ( _g, success) = C . wait_timeout_with ( g, Duration :: new ( day, 0 ) , |_| {
475519 assert_eq ! ( state, S . load( Ordering :: SeqCst ) ) ;
476520 tx. send ( ( ) ) . unwrap ( ) ;
477521 state += 1 ;
0 commit comments