Skip to main content

fuchsia_sync/
lib.rs

1// Copyright 2023 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
5//! Fuchsia-native synchronization primitives.
6
7#[cfg(target_os = "fuchsia")]
8mod completion;
9#[cfg(target_os = "fuchsia")]
10pub use completion::*;
11mod condvar;
12pub use condvar::*;
13
14#[cfg(target_os = "fuchsia")]
15mod mutex;
16#[cfg(target_os = "fuchsia")]
17mod rwlock;
18
19#[cfg(target_os = "fuchsia")]
20pub use mutex::RawSyncMutex as RawMutex;
21#[cfg(not(target_os = "fuchsia"))]
22pub use parking_lot::RawMutex;
23
24#[cfg(not(target_os = "fuchsia"))]
25pub use parking_lot::RawRwLock;
26#[cfg(target_os = "fuchsia")]
27pub use rwlock::RawSyncRwLock as RawRwLock;
28
29#[cfg(not(detect_lock_cycles))]
30type RawMutexImpl = RawMutex;
31#[cfg(detect_lock_cycles)]
32type RawMutexImpl = tracing_mutex::lockapi::TracingWrapper<RawMutex>;
33
34#[cfg(not(detect_lock_cycles))]
35type RawRwLockImpl = RawRwLock;
36#[cfg(detect_lock_cycles)]
37type RawRwLockImpl = tracing_mutex::lockapi::TracingWrapper<RawRwLock>;
38
39pub type Mutex<T> = lock_api::Mutex<RawMutexImpl, T>;
40pub type MutexGuard<'a, T> = lock_api::MutexGuard<'a, RawMutexImpl, T>;
41pub type MappedMutexGuard<'a, T> = lock_api::MappedMutexGuard<'a, RawMutexImpl, T>;
42
43pub type RwLock<T> = lock_api::RwLock<RawRwLockImpl, T>;
44pub type RwLockReadGuard<'a, T> = lock_api::RwLockReadGuard<'a, RawRwLockImpl, T>;
45pub type RwLockWriteGuard<'a, T> = lock_api::RwLockWriteGuard<'a, RawRwLockImpl, T>;
46pub type MappedRwLockReadGuard<'a, T> = lock_api::MappedRwLockReadGuard<'a, RawRwLockImpl, T>;
47pub type MappedRwLockWriteGuard<'a, T> = lock_api::MappedRwLockWriteGuard<'a, RawRwLockImpl, T>;
48
49/// Prevent potential deadlocks from panicking when lock cycle detection is enabled. This will
50/// cause them to print instead of exiting the process.
51pub fn suppress_lock_cycle_panics() {
52    #[cfg(detect_lock_cycles)]
53    tracing_mutex::suppress_panics();
54}
55
56/// A trait for locks whose dynamic dependency tracking graph can be reset.
57///
58/// This should only be called when we need to change a previous lock ordering.
59pub trait ResetDependencies {
60    /// Resets the lock dependency graph for this lock.
61    ///
62    /// # Safety
63    ///
64    /// It is the responsibility of the caller to ensure changing this lock ordering is safe.
65    unsafe fn reset_dependencies(&self);
66}
67
68impl<T> ResetDependencies for RwLock<T> {
69    #[inline(always)]
70    unsafe fn reset_dependencies(&self) {
71        #[cfg(detect_lock_cycles)]
72        // SAFETY: The caller guarantees they are enforcing a sound locking order
73        // and that resetting the graph will not mask a real deadlock.
74        unsafe {
75            tracing_mutex::util::reset_dependencies(lock_api::RwLock::raw(self));
76        }
77    }
78}
79
80impl<T> ResetDependencies for Mutex<T> {
81    #[inline(always)]
82    unsafe fn reset_dependencies(&self) {
83        #[cfg(detect_lock_cycles)]
84        // SAFETY: The caller guarantees they are enforcing a sound locking order
85        // and that resetting the graph will not mask a real deadlock.
86        unsafe {
87            tracing_mutex::util::reset_dependencies(lock_api::Mutex::raw(self));
88        }
89    }
90}