Skip to main content

starnix_sync/
condvar.rs

1// Copyright 2026 The Fuchsia 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
5use fuchsia_sync::MutexGuard;
6
7/// A Condition Variable that is compatible with both standard Mutex and LockDepMutex
8/// in Starnix.
9pub struct CondVar {
10    inner: fuchsia_sync::Condvar,
11}
12
13/// A token that proves the caller is allowed to access the inner guard.
14/// Its field is private, so it can only be constructed within this crate.
15pub struct WaitToken(());
16
17pub trait WaitableMutexGuard<'a, T> {
18    fn inner_guard(&mut self, token: WaitToken) -> &mut MutexGuard<'a, T>;
19}
20
21impl<'a, T> WaitableMutexGuard<'a, T> for MutexGuard<'a, T> {
22    fn inner_guard(&mut self, _token: WaitToken) -> &mut MutexGuard<'a, T> {
23        self
24    }
25}
26
27impl CondVar {
28    #[inline]
29    pub const fn new() -> Self {
30        Self { inner: fuchsia_sync::Condvar::new() }
31    }
32
33    /// Blocks the current thread until this condition variable receives a notification.
34    pub fn wait<'a, T: 'a, G: WaitableMutexGuard<'a, T>>(&self, guard: &mut G) {
35        self.inner.wait(guard.inner_guard(WaitToken(())));
36    }
37
38    /// Wakes up one blocked thread on this condvar.
39    pub fn notify_one(&self) {
40        self.inner.notify_one();
41    }
42
43    /// Wakes up all blocked threads on this condvar.
44    pub fn notify_all(&self) {
45        self.inner.notify_all();
46    }
47}
48
49impl Default for CondVar {
50    fn default() -> Self {
51        Self::new()
52    }
53}
54
55impl std::fmt::Debug for CondVar {
56    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57        f.debug_struct("CondVar").finish()
58    }
59}