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