diff options
author | Alice Ryhl <aliceryhl@google.com> | 2023-05-31 14:59:38 +0000 |
---|---|---|
committer | Miguel Ojeda <ojeda@kernel.org> | 2023-05-31 18:53:10 +0200 |
commit | be7724cdbbca22e0cbde1edf30941a7aa4378ded (patch) | |
tree | 588498f46c522aff57e6c60a636fea4cc6a249e4 /rust | |
parent | d701e061cb14f589f8c4f48fd7fbe81c0e34b7e7 (diff) | |
download | lwn-be7724cdbbca22e0cbde1edf30941a7aa4378ded.tar.gz lwn-be7724cdbbca22e0cbde1edf30941a7aa4378ded.zip |
rust: specify when `ARef` is thread safe
An `ARef` behaves just like the `Arc` when it comes to thread safety, so
we can reuse the thread safety comments from `Arc` here.
This is necessary because without this change, the Rust compiler will
assume that things are not thread safe even though they are.
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Andreas Hindborg <a.hindborg@samsung.com>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/r/20230531145939.3714886-4-aliceryhl@google.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'rust')
-rw-r--r-- | rust/kernel/types.rs | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index 29db59d6119a..1e5380b16ed5 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -321,6 +321,19 @@ pub struct ARef<T: AlwaysRefCounted> { _p: PhantomData<T>, } +// SAFETY: It is safe to send `ARef<T>` to another thread when the underlying `T` is `Sync` because +// it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs +// `T` to be `Send` because any thread that has an `ARef<T>` may ultimately access `T` using a +// mutable reference, for example, when the reference count reaches zero and `T` is dropped. +unsafe impl<T: AlwaysRefCounted + Sync + Send> Send for ARef<T> {} + +// SAFETY: It is safe to send `&ARef<T>` to another thread when the underlying `T` is `Sync` +// because it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, +// it needs `T` to be `Send` because any thread that has a `&ARef<T>` may clone it and get an +// `ARef<T>` on that thread, so the thread may ultimately access `T` using a mutable reference, for +// example, when the reference count reaches zero and `T` is dropped. +unsafe impl<T: AlwaysRefCounted + Sync + Send> Sync for ARef<T> {} + impl<T: AlwaysRefCounted> ARef<T> { /// Creates a new instance of [`ARef`]. /// |