ksync/phantom_mutex.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 crate::{LockPolicy, RawLock};
6use pin_init::{PinInit, pin_data, pin_init};
7
8/// A zero-sized raw mutex implementation that does not perform physical locking.
9///
10/// `PhantomMutex` can be used as the raw lock type in a `KMutex<Class, PhantomMutex>` field
11/// to serve as a zero-sized "phantom" lock in structs where physical synchronization is managed
12/// by an external shared lock (such as a ref-counted `PeerHolder` for peered dispatchers).
13///
14/// Using `KMutex<Class, PhantomMutex>` allows structs to integrate with `#[guarded]` and
15/// `#[guarded_by(...)]` without allocating memory for a physical mutex in every instance.
16///
17/// # Example
18///
19/// ```
20/// use ksync::{KCell, KMutex, PhantomMutex, guarded};
21///
22/// #[guarded]
23/// struct RealObject {
24/// #[mutex]
25/// mu: KMutex,
26/// }
27///
28/// #[guarded]
29/// struct PeeredObject {
30/// #[mutex(RealObjectMuClass)]
31/// mu: KMutex<PhantomMutex>,
32/// #[guarded_by(mu)]
33/// value: KCell<i32>,
34/// }
35///
36/// // When holding the shared physical mutex (`real_obj.mu`), call `lock_mu` to access fields
37/// // protected by the zero-sized `PhantomMutex`:
38///
39/// ksync::lock!(let guard = phantom_obj.lock_mu(&real_obj.mu));
40/// let value = guard.value();
41///
42/// // If already holding a lock token from another guard of the same class, call `guard_mu`
43/// // to obtain an accessor object without re-locking:
44///
45/// let other_value = other_phantom_obj.guard_mu(guard.token()).value();
46/// ```
47#[pin_data]
48#[derive(Default, Debug, Clone, Copy)]
49pub struct PhantomMutex;
50
51pub struct PhantomMutexPolicy;
52
53impl LockPolicy<PhantomMutex> for PhantomMutexPolicy {
54 type AcquireArgs = ();
55 type GuardState = ();
56
57 #[inline]
58 unsafe fn acquire(_lock: &PhantomMutex, _entry: *mut (), _args: ()) -> Self::GuardState {}
59
60 #[inline]
61 unsafe fn reacquire(_lock: &PhantomMutex, _entry: *mut (), _state: &mut Self::GuardState) {}
62
63 #[inline]
64 unsafe fn release(_lock: &PhantomMutex, _entry: *mut (), _state: Self::GuardState) {}
65}
66
67impl RawLock for PhantomMutex {
68 type LockEntry = ();
69 type DefaultPolicy = PhantomMutexPolicy;
70
71 #[inline]
72 unsafe fn init(
73 _class_id: *const core::ffi::c_void,
74 ) -> impl PinInit<Self, core::convert::Infallible>
75 where
76 Self: Sized,
77 {
78 pin_init!(Self {})
79 }
80
81 #[inline]
82 fn as_mut_ptr(&self) -> *mut core::ffi::c_void {
83 core::ptr::NonNull::<Self>::dangling().as_ptr() as *mut _
84 }
85}