sync/
condvar.rs

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
5use std::fmt;
6use std::fmt::Debug;
7use std::sync::Condvar as StdCondvar;
8use std::sync::MutexGuard;
9use std::sync::WaitTimeoutResult;
10use std::time::Duration;
11
12static CONDVAR_POISONED: &str = "condvar is poisoned";
13
14/// A Condition Variable.
15#[derive(Default)]
16pub struct Condvar {
17    std: StdCondvar,
18}
19
20impl Condvar {
21    /// Creates a new condvar that is ready to be waited on.
22    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.
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.
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.
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.
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.
70    pub fn notify_one(&self) {
71        self.std.notify_one();
72    }
73
74    /// Notifies all threads blocked by this condvar.
75    pub fn notify_all(&self) {
76        self.std.notify_all();
77    }
78}
79
80impl Debug for Condvar {
81    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
82        Debug::fmt(&self.std, formatter)
83    }
84}