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