1 // Copyright 2018 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 use std::fmt; 6 use std::fmt::Debug; 7 use std::sync::Condvar as StdCondvar; 8 use std::sync::MutexGuard; 9 use std::sync::WaitTimeoutResult; 10 use std::time::Duration; 11 12 static CONDVAR_POISONED: &str = "condvar is poisoned"; 13 14 /// A Condition Variable. 15 #[derive(Default)] 16 pub struct Condvar { 17 std: StdCondvar, 18 } 19 20 impl Condvar { 21 /// Creates a new condvar that is ready to be waited on. new() -> Condvar22 pub const fn new() -> Condvar { 23 Condvar { 24 std: StdCondvar::new(), 25 } 26 } 27 28 /// Waits on a condvar, blocking the current thread until it is notified. wait<'a, T>(&self, guard: MutexGuard<'a, T>) -> MutexGuard<'a, T>29 pub fn wait<'a, T>(&self, guard: MutexGuard<'a, T>) -> MutexGuard<'a, T> { 30 self.std.wait(guard).expect(CONDVAR_POISONED) 31 } 32 33 /// Blocks the current thread until this condition variable receives a notification and the 34 /// provided condition is false. wait_while<'a, T, F>(&self, guard: MutexGuard<'a, T>, condition: F) -> MutexGuard<'a, T> where F: FnMut(&mut T) -> bool,35 pub fn wait_while<'a, T, F>(&self, guard: MutexGuard<'a, T>, condition: F) -> MutexGuard<'a, T> 36 where 37 F: FnMut(&mut T) -> bool, 38 { 39 self.std 40 .wait_while(guard, condition) 41 .expect(CONDVAR_POISONED) 42 } 43 44 /// Waits on a condvar, blocking the current thread until it is notified 45 /// or the specified duration has elapsed. wait_timeout<'a, T>( &self, guard: MutexGuard<'a, T>, dur: Duration, ) -> (MutexGuard<'a, T>, WaitTimeoutResult)46 pub fn wait_timeout<'a, T>( 47 &self, 48 guard: MutexGuard<'a, T>, 49 dur: Duration, 50 ) -> (MutexGuard<'a, T>, WaitTimeoutResult) { 51 self.std.wait_timeout(guard, dur).expect(CONDVAR_POISONED) 52 } 53 54 /// Waits on this condition variable for a notification, timing out after a specified duration. wait_timeout_while<'a, T, F>( &self, guard: MutexGuard<'a, T>, dur: Duration, condition: F, ) -> (MutexGuard<'a, T>, WaitTimeoutResult) where F: FnMut(&mut T) -> bool,55 pub fn wait_timeout_while<'a, T, F>( 56 &self, 57 guard: MutexGuard<'a, T>, 58 dur: Duration, 59 condition: F, 60 ) -> (MutexGuard<'a, T>, WaitTimeoutResult) 61 where 62 F: FnMut(&mut T) -> bool, 63 { 64 self.std 65 .wait_timeout_while(guard, dur, condition) 66 .expect(CONDVAR_POISONED) 67 } 68 69 /// Notifies one thread blocked by this condvar. notify_one(&self)70 pub fn notify_one(&self) { 71 self.std.notify_one(); 72 } 73 74 /// Notifies all threads blocked by this condvar. notify_all(&self)75 pub fn notify_all(&self) { 76 self.std.notify_all(); 77 } 78 } 79 80 impl Debug for Condvar { fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result81 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 82 Debug::fmt(&self.std, formatter) 83 } 84 } 85