arc.rs (c5fb51b71788926feef0d07f30c8af1d5e4af1a6) arc.rs (47cb6bf7860ce33bdd000198f8b65cf9fb3324b4)
1// SPDX-License-Identifier: GPL-2.0
2
3//! A reference-counted pointer.
4//!
5//! This module implements a way for users to create reference-counted objects and pointers to
6//! them. Such a pointer automatically increments and decrements the count, and drops the
7//! underlying object when it reaches zero. It is also safe to use concurrently from multiple
8//! threads.

--- 12 unchanged lines hidden (view full) ---

21 bindings,
22 init::{self, InPlaceInit, Init, PinInit},
23 try_init,
24 types::{ForeignOwnable, Opaque},
25};
26use core::{
27 alloc::Layout,
28 fmt,
1// SPDX-License-Identifier: GPL-2.0
2
3//! A reference-counted pointer.
4//!
5//! This module implements a way for users to create reference-counted objects and pointers to
6//! them. Such a pointer automatically increments and decrements the count, and drops the
7//! underlying object when it reaches zero. It is also safe to use concurrently from multiple
8//! threads.

--- 12 unchanged lines hidden (view full) ---

21 bindings,
22 init::{self, InPlaceInit, Init, PinInit},
23 try_init,
24 types::{ForeignOwnable, Opaque},
25};
26use core::{
27 alloc::Layout,
28 fmt,
29 marker::{PhantomData, Unsize},
29 marker::PhantomData,
30 mem::{ManuallyDrop, MaybeUninit},
31 ops::{Deref, DerefMut},
32 pin::Pin,
33 ptr::NonNull,
34};
35use macros::pin_data;
36
37mod std_vendor;

--- 82 unchanged lines hidden (view full) ---

120///
121/// // `obj` has type `Arc<Example>`.
122/// let obj: Arc<Example> = Arc::new(Example, GFP_KERNEL)?;
123///
124/// // `coerced` has type `Arc<dyn MyTrait>`.
125/// let coerced: Arc<dyn MyTrait> = obj;
126/// # Ok::<(), Error>(())
127/// ```
30 mem::{ManuallyDrop, MaybeUninit},
31 ops::{Deref, DerefMut},
32 pin::Pin,
33 ptr::NonNull,
34};
35use macros::pin_data;
36
37mod std_vendor;

--- 82 unchanged lines hidden (view full) ---

120///
121/// // `obj` has type `Arc<Example>`.
122/// let obj: Arc<Example> = Arc::new(Example, GFP_KERNEL)?;
123///
124/// // `coerced` has type `Arc<dyn MyTrait>`.
125/// let coerced: Arc<dyn MyTrait> = obj;
126/// # Ok::<(), Error>(())
127/// ```
128#[repr(transparent)]
129#[cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, derive(core::marker::CoercePointee))]
128pub struct Arc<T: ?Sized> {
129 ptr: NonNull<ArcInner<T>>,
130pub struct Arc<T: ?Sized> {
131 ptr: NonNull<ArcInner<T>>,
132 // NB: this informs dropck that objects of type `ArcInner<T>` may be used in `<Arc<T> as
133 // Drop>::drop`. Note that dropck already assumes that objects of type `T` may be used in
134 // `<Arc<T> as Drop>::drop` and the distinction between `T` and `ArcInner<T>` is not presently
135 // meaningful with respect to dropck - but this may change in the future so this is left here
136 // out of an abundance of caution.
137 //
138 // See https://doc.rust-lang.org/nomicon/phantom-data.html#generic-parameters-and-drop-checking
139 // for more detail on the semantics of dropck in the presence of `PhantomData`.
130 _p: PhantomData<ArcInner<T>>,
131}
132
133#[pin_data]
134#[repr(C)]
135struct ArcInner<T: ?Sized> {
136 refcount: Opaque<bindings::refcount_t>,
137 data: T,

--- 29 unchanged lines hidden (view full) ---

167 // SAFETY: The pointer can't be null since you can't have an `ArcInner<T>` value at the null
168 // address.
169 unsafe { NonNull::new_unchecked(ptr.cast_mut()) }
170 }
171}
172
173// This is to allow coercion from `Arc<T>` to `Arc<U>` if `T` can be converted to the
174// dynamically-sized type (DST) `U`.
140 _p: PhantomData<ArcInner<T>>,
141}
142
143#[pin_data]
144#[repr(C)]
145struct ArcInner<T: ?Sized> {
146 refcount: Opaque<bindings::refcount_t>,
147 data: T,

--- 29 unchanged lines hidden (view full) ---

177 // SAFETY: The pointer can't be null since you can't have an `ArcInner<T>` value at the null
178 // address.
179 unsafe { NonNull::new_unchecked(ptr.cast_mut()) }
180 }
181}
182
183// This is to allow coercion from `Arc<T>` to `Arc<U>` if `T` can be converted to the
184// dynamically-sized type (DST) `U`.
175impl<T: ?Sized + Unsize<U>, U: ?Sized> core::ops::CoerceUnsized<Arc<U>> for Arc<T> {}
185#[cfg(not(CONFIG_RUSTC_HAS_COERCE_POINTEE))]
186impl<T: ?Sized + core::marker::Unsize<U>, U: ?Sized> core::ops::CoerceUnsized<Arc<U>> for Arc<T> {}
176
177// This is to allow `Arc<U>` to be dispatched on when `Arc<T>` can be coerced into `Arc<U>`.
187
188// This is to allow `Arc<U>` to be dispatched on when `Arc<T>` can be coerced into `Arc<U>`.
178impl<T: ?Sized + Unsize<U>, U: ?Sized> core::ops::DispatchFromDyn<Arc<U>> for Arc<T> {}
189#[cfg(not(CONFIG_RUSTC_HAS_COERCE_POINTEE))]
190impl<T: ?Sized + core::marker::Unsize<U>, U: ?Sized> core::ops::DispatchFromDyn<Arc<U>> for Arc<T> {}
179
180// SAFETY: It is safe to send `Arc<T>` to another thread when the underlying `T` is `Sync` because
181// it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs
182// `T` to be `Send` because any thread that has an `Arc<T>` may ultimately access `T` using a
183// mutable reference when the reference count reaches zero and `T` is dropped.
184unsafe impl<T: ?Sized + Sync + Send> Send for Arc<T> {}
185
186// SAFETY: It is safe to send `&Arc<T>` to another thread when the underlying `T` is `Sync`

--- 279 unchanged lines hidden (view full) ---

466/// // ...
467/// }
468/// }
469///
470/// let obj = Arc::new(Example { a: 10, b: 20 }, GFP_KERNEL)?;
471/// obj.as_arc_borrow().use_reference();
472/// # Ok::<(), Error>(())
473/// ```
191
192// SAFETY: It is safe to send `Arc<T>` to another thread when the underlying `T` is `Sync` because
193// it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs
194// `T` to be `Send` because any thread that has an `Arc<T>` may ultimately access `T` using a
195// mutable reference when the reference count reaches zero and `T` is dropped.
196unsafe impl<T: ?Sized + Sync + Send> Send for Arc<T> {}
197
198// SAFETY: It is safe to send `&Arc<T>` to another thread when the underlying `T` is `Sync`

--- 279 unchanged lines hidden (view full) ---

478/// // ...
479/// }
480/// }
481///
482/// let obj = Arc::new(Example { a: 10, b: 20 }, GFP_KERNEL)?;
483/// obj.as_arc_borrow().use_reference();
484/// # Ok::<(), Error>(())
485/// ```
486#[repr(transparent)]
487#[cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, derive(core::marker::CoercePointee))]
474pub struct ArcBorrow<'a, T: ?Sized + 'a> {
475 inner: NonNull<ArcInner<T>>,
476 _p: PhantomData<&'a ()>,
477}
478
479// This is to allow `ArcBorrow<U>` to be dispatched on when `ArcBorrow<T>` can be coerced into
480// `ArcBorrow<U>`.
488pub struct ArcBorrow<'a, T: ?Sized + 'a> {
489 inner: NonNull<ArcInner<T>>,
490 _p: PhantomData<&'a ()>,
491}
492
493// This is to allow `ArcBorrow<U>` to be dispatched on when `ArcBorrow<T>` can be coerced into
494// `ArcBorrow<U>`.
481impl<T: ?Sized + Unsize<U>, U: ?Sized> core::ops::DispatchFromDyn<ArcBorrow<'_, U>>
495#[cfg(not(CONFIG_RUSTC_HAS_COERCE_POINTEE))]
496impl<T: ?Sized + core::marker::Unsize<U>, U: ?Sized> core::ops::DispatchFromDyn<ArcBorrow<'_, U>>
482 for ArcBorrow<'_, T>
483{
484}
485
486impl<T: ?Sized> Clone for ArcBorrow<'_, T> {
487 fn clone(&self) -> Self {
488 *self
489 }

--- 265 unchanged lines hidden ---
497 for ArcBorrow<'_, T>
498{
499}
500
501impl<T: ?Sized> Clone for ArcBorrow<'_, T> {
502 fn clone(&self) -> Self {
503 *self
504 }

--- 265 unchanged lines hidden ---