Skip to main content

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 pin_init::pin_data;
6
7/// A zero-sized raw mutex marker that does not perform physical locking.
8///
9/// `PhantomMutex` can be used as the raw lock type in a `KMutex<Class, PhantomMutex>` field
10/// to serve as a zero-sized "phantom" lock in structs where physical synchronization is managed
11/// by an external shared lock (such as a ref-counted `PeerHolder` for peered dispatchers).
12///
13/// Using `KMutex<Class, PhantomMutex>` allows structs to integrate with `#[guarded]` and
14/// `#[guarded_by(...)]` without allocating memory for a physical mutex in every instance.
15/// Because `PhantomMutex` has no physical state of its own, associating a `PhantomMutex`-guarded
16/// struct with a physical mutex (`lock_<mu>`) or lock token (`guard_<mu>` / `guard_<mu>_mut`) is
17/// `unsafe` and requires the caller to uphold that the provided mutex or token is the specific
18/// lock instance protecting that struct.
19///
20/// # Example
21///
22/// ```
23/// use ksync::{KCell, KMutex, PhantomMutex, guarded};
24///
25/// #[guarded]
26/// struct RealObject {
27///     #[mutex]
28///     mu: KMutex,
29/// }
30///
31/// #[guarded]
32/// struct PeeredObject {
33///     #[mutex(RealObjectMuClass)]
34///     mu: KMutex<PhantomMutex>,
35///     #[guarded_by(mu)]
36///     value: KCell<i32>,
37/// }
38///
39/// // When locking the shared physical mutex (`real_obj.mu`), call `lock_mu` in an `unsafe`
40/// // block (asserting that `real_obj.mu` is the lock protecting `phantom_obj`):
41///
42///     ksync::lock!(let guard = unsafe { phantom_obj.lock_mu(&real_obj.mu) });
43///     let value = guard.value();
44///
45/// // If already holding a lock token from another guard of the same class, call `guard_mu`
46/// // in an `unsafe` block to obtain an accessor object without re-locking:
47///
48///     let other_value = unsafe { other_phantom_obj.guard_mu(guard.token()) }.value();
49/// ```
50#[pin_data]
51#[derive(Default, Debug, Clone, Copy)]
52pub struct PhantomMutex;