Commit | Line | Data |
---|---|---|
9dc04365 WAF |
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. | |
9 | //! | |
10 | //! It is different from the standard library's [`Arc`] in a few ways: | |
11 | //! 1. It is backed by the kernel's `refcount_t` type. | |
12 | //! 2. It does not support weak references, which allows it to be half the size. | |
13 | //! 3. It saturates the reference count instead of aborting when it goes over a threshold. | |
14 | //! 4. It does not provide a `get_mut` method, so the ref counted object is pinned. | |
15 | //! | |
16 | //! [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html | |
17 | ||
0c7ae432 WAF |
18 | use crate::{ |
19 | bindings, | |
92c4a1e7 | 20 | error::{self, Error}, |
701608bd BL |
21 | init::{self, InPlaceInit, Init, PinInit}, |
22 | try_init, | |
0c7ae432 WAF |
23 | types::{ForeignOwnable, Opaque}, |
24 | }; | |
9dc04365 | 25 | use alloc::boxed::Box; |
f75cb6fc | 26 | use core::{ |
d6dbca35 | 27 | alloc::AllocError, |
00140a83 | 28 | fmt, |
f75cb6fc | 29 | marker::{PhantomData, Unsize}, |
70e42ebb WAF |
30 | mem::{ManuallyDrop, MaybeUninit}, |
31 | ops::{Deref, DerefMut}, | |
32 | pin::Pin, | |
f75cb6fc WAF |
33 | ptr::NonNull, |
34 | }; | |
701608bd | 35 | use macros::pin_data; |
9dc04365 | 36 | |
1edd0337 AL |
37 | mod std_vendor; |
38 | ||
9dc04365 WAF |
39 | /// A reference-counted pointer to an instance of `T`. |
40 | /// | |
41 | /// The reference count is incremented when new instances of [`Arc`] are created, and decremented | |
42 | /// when they are dropped. When the count reaches zero, the underlying `T` is also dropped. | |
43 | /// | |
44 | /// # Invariants | |
45 | /// | |
46 | /// The reference count on an instance of [`Arc`] is always non-zero. | |
47 | /// The object pointed to by [`Arc`] is always pinned. | |
48 | /// | |
49 | /// # Examples | |
50 | /// | |
51 | /// ``` | |
52 | /// use kernel::sync::Arc; | |
53 | /// | |
54 | /// struct Example { | |
55 | /// a: u32, | |
56 | /// b: u32, | |
57 | /// } | |
58 | /// | |
59 | /// // Create a ref-counted instance of `Example`. | |
60 | /// let obj = Arc::try_new(Example { a: 10, b: 20 })?; | |
61 | /// | |
62 | /// // Get a new pointer to `obj` and increment the refcount. | |
63 | /// let cloned = obj.clone(); | |
64 | /// | |
65 | /// // Assert that both `obj` and `cloned` point to the same underlying object. | |
66 | /// assert!(core::ptr::eq(&*obj, &*cloned)); | |
67 | /// | |
68 | /// // Destroy `obj` and decrement its refcount. | |
69 | /// drop(obj); | |
70 | /// | |
71 | /// // Check that the values are still accessible through `cloned`. | |
72 | /// assert_eq!(cloned.a, 10); | |
73 | /// assert_eq!(cloned.b, 20); | |
74 | /// | |
75 | /// // The refcount drops to zero when `cloned` goes out of scope, and the memory is freed. | |
76 | /// ``` | |
53528772 WAF |
77 | /// |
78 | /// Using `Arc<T>` as the type of `self`: | |
79 | /// | |
80 | /// ``` | |
81 | /// use kernel::sync::Arc; | |
82 | /// | |
83 | /// struct Example { | |
84 | /// a: u32, | |
85 | /// b: u32, | |
86 | /// } | |
87 | /// | |
88 | /// impl Example { | |
89 | /// fn take_over(self: Arc<Self>) { | |
90 | /// // ... | |
91 | /// } | |
92 | /// | |
93 | /// fn use_reference(self: &Arc<Self>) { | |
94 | /// // ... | |
95 | /// } | |
96 | /// } | |
97 | /// | |
98 | /// let obj = Arc::try_new(Example { a: 10, b: 20 })?; | |
99 | /// obj.use_reference(); | |
100 | /// obj.take_over(); | |
101 | /// ``` | |
f75cb6fc WAF |
102 | /// |
103 | /// Coercion from `Arc<Example>` to `Arc<dyn MyTrait>`: | |
104 | /// | |
105 | /// ``` | |
0748424a WAF |
106 | /// use kernel::sync::{Arc, ArcBorrow}; |
107 | /// | |
108 | /// trait MyTrait { | |
109 | /// // Trait has a function whose `self` type is `Arc<Self>`. | |
110 | /// fn example1(self: Arc<Self>) {} | |
f75cb6fc | 111 | /// |
0748424a WAF |
112 | /// // Trait has a function whose `self` type is `ArcBorrow<'_, Self>`. |
113 | /// fn example2(self: ArcBorrow<'_, Self>) {} | |
114 | /// } | |
f75cb6fc WAF |
115 | /// |
116 | /// struct Example; | |
117 | /// impl MyTrait for Example {} | |
118 | /// | |
119 | /// // `obj` has type `Arc<Example>`. | |
120 | /// let obj: Arc<Example> = Arc::try_new(Example)?; | |
121 | /// | |
122 | /// // `coerced` has type `Arc<dyn MyTrait>`. | |
123 | /// let coerced: Arc<dyn MyTrait> = obj; | |
124 | /// ``` | |
9dc04365 WAF |
125 | pub struct Arc<T: ?Sized> { |
126 | ptr: NonNull<ArcInner<T>>, | |
127 | _p: PhantomData<ArcInner<T>>, | |
128 | } | |
129 | ||
701608bd | 130 | #[pin_data] |
9dc04365 WAF |
131 | #[repr(C)] |
132 | struct ArcInner<T: ?Sized> { | |
133 | refcount: Opaque<bindings::refcount_t>, | |
134 | data: T, | |
135 | } | |
136 | ||
53528772 WAF |
137 | // This is to allow [`Arc`] (and variants) to be used as the type of `self`. |
138 | impl<T: ?Sized> core::ops::Receiver for Arc<T> {} | |
139 | ||
f75cb6fc WAF |
140 | // This is to allow coercion from `Arc<T>` to `Arc<U>` if `T` can be converted to the |
141 | // dynamically-sized type (DST) `U`. | |
142 | impl<T: ?Sized + Unsize<U>, U: ?Sized> core::ops::CoerceUnsized<Arc<U>> for Arc<T> {} | |
143 | ||
0748424a WAF |
144 | // This is to allow `Arc<U>` to be dispatched on when `Arc<T>` can be coerced into `Arc<U>`. |
145 | impl<T: ?Sized + Unsize<U>, U: ?Sized> core::ops::DispatchFromDyn<Arc<U>> for Arc<T> {} | |
146 | ||
9dc04365 WAF |
147 | // SAFETY: It is safe to send `Arc<T>` to another thread when the underlying `T` is `Sync` because |
148 | // it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs | |
149 | // `T` to be `Send` because any thread that has an `Arc<T>` may ultimately access `T` directly, for | |
150 | // example, when the reference count reaches zero and `T` is dropped. | |
151 | unsafe impl<T: ?Sized + Sync + Send> Send for Arc<T> {} | |
152 | ||
153 | // SAFETY: It is safe to send `&Arc<T>` to another thread when the underlying `T` is `Sync` for the | |
154 | // same reason as above. `T` needs to be `Send` as well because a thread can clone an `&Arc<T>` | |
155 | // into an `Arc<T>`, which may lead to `T` being accessed by the same reasoning as above. | |
156 | unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {} | |
157 | ||
158 | impl<T> Arc<T> { | |
159 | /// Constructs a new reference counted instance of `T`. | |
d6dbca35 | 160 | pub fn try_new(contents: T) -> Result<Self, AllocError> { |
9dc04365 WAF |
161 | // INVARIANT: The refcount is initialised to a non-zero value. |
162 | let value = ArcInner { | |
163 | // SAFETY: There are no safety requirements for this FFI call. | |
164 | refcount: Opaque::new(unsafe { bindings::REFCOUNT_INIT(1) }), | |
165 | data: contents, | |
166 | }; | |
167 | ||
168 | let inner = Box::try_new(value)?; | |
169 | ||
170 | // SAFETY: We just created `inner` with a reference count of 1, which is owned by the new | |
171 | // `Arc` object. | |
172 | Ok(unsafe { Self::from_inner(Box::leak(inner).into()) }) | |
173 | } | |
92c4a1e7 BL |
174 | |
175 | /// Use the given initializer to in-place initialize a `T`. | |
176 | /// | |
177 | /// If `T: !Unpin` it will not be able to move afterwards. | |
178 | #[inline] | |
179 | pub fn pin_init<E>(init: impl PinInit<T, E>) -> error::Result<Self> | |
180 | where | |
181 | Error: From<E>, | |
182 | { | |
183 | UniqueArc::pin_init(init).map(|u| u.into()) | |
184 | } | |
185 | ||
186 | /// Use the given initializer to in-place initialize a `T`. | |
187 | /// | |
188 | /// This is equivalent to [`pin_init`], since an [`Arc`] is always pinned. | |
189 | #[inline] | |
190 | pub fn init<E>(init: impl Init<T, E>) -> error::Result<Self> | |
191 | where | |
192 | Error: From<E>, | |
193 | { | |
194 | UniqueArc::init(init).map(|u| u.into()) | |
195 | } | |
9dc04365 WAF |
196 | } |
197 | ||
198 | impl<T: ?Sized> Arc<T> { | |
199 | /// Constructs a new [`Arc`] from an existing [`ArcInner`]. | |
200 | /// | |
201 | /// # Safety | |
202 | /// | |
203 | /// The caller must ensure that `inner` points to a valid location and has a non-zero reference | |
204 | /// count, one of which will be owned by the new [`Arc`] instance. | |
205 | unsafe fn from_inner(inner: NonNull<ArcInner<T>>) -> Self { | |
206 | // INVARIANT: By the safety requirements, the invariants hold. | |
207 | Arc { | |
208 | ptr: inner, | |
209 | _p: PhantomData, | |
210 | } | |
211 | } | |
17f67160 WAF |
212 | |
213 | /// Returns an [`ArcBorrow`] from the given [`Arc`]. | |
214 | /// | |
215 | /// This is useful when the argument of a function call is an [`ArcBorrow`] (e.g., in a method | |
216 | /// receiver), but we have an [`Arc`] instead. Getting an [`ArcBorrow`] is free when optimised. | |
217 | #[inline] | |
218 | pub fn as_arc_borrow(&self) -> ArcBorrow<'_, T> { | |
219 | // SAFETY: The constraint that the lifetime of the shared reference must outlive that of | |
220 | // the returned `ArcBorrow` ensures that the object remains alive and that no mutable | |
221 | // reference can be created. | |
222 | unsafe { ArcBorrow::new(self.ptr) } | |
223 | } | |
9dc04365 WAF |
224 | } |
225 | ||
0c7ae432 WAF |
226 | impl<T: 'static> ForeignOwnable for Arc<T> { |
227 | type Borrowed<'a> = ArcBorrow<'a, T>; | |
228 | ||
229 | fn into_foreign(self) -> *const core::ffi::c_void { | |
230 | ManuallyDrop::new(self).ptr.as_ptr() as _ | |
231 | } | |
232 | ||
233 | unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> ArcBorrow<'a, T> { | |
234 | // SAFETY: By the safety requirement of this function, we know that `ptr` came from | |
235 | // a previous call to `Arc::into_foreign`. | |
236 | let inner = NonNull::new(ptr as *mut ArcInner<T>).unwrap(); | |
237 | ||
238 | // SAFETY: The safety requirements of `from_foreign` ensure that the object remains alive | |
239 | // for the lifetime of the returned value. Additionally, the safety requirements of | |
240 | // `ForeignOwnable::borrow_mut` ensure that no new mutable references are created. | |
241 | unsafe { ArcBorrow::new(inner) } | |
242 | } | |
243 | ||
244 | unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self { | |
245 | // SAFETY: By the safety requirement of this function, we know that `ptr` came from | |
246 | // a previous call to `Arc::into_foreign`, which guarantees that `ptr` is valid and | |
247 | // holds a reference count increment that is transferrable to us. | |
248 | unsafe { Self::from_inner(NonNull::new(ptr as _).unwrap()) } | |
249 | } | |
250 | } | |
251 | ||
9dc04365 WAF |
252 | impl<T: ?Sized> Deref for Arc<T> { |
253 | type Target = T; | |
254 | ||
255 | fn deref(&self) -> &Self::Target { | |
256 | // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is | |
257 | // safe to dereference it. | |
258 | unsafe { &self.ptr.as_ref().data } | |
259 | } | |
260 | } | |
261 | ||
262 | impl<T: ?Sized> Clone for Arc<T> { | |
263 | fn clone(&self) -> Self { | |
264 | // INVARIANT: C `refcount_inc` saturates the refcount, so it cannot overflow to zero. | |
265 | // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is | |
266 | // safe to increment the refcount. | |
267 | unsafe { bindings::refcount_inc(self.ptr.as_ref().refcount.get()) }; | |
268 | ||
269 | // SAFETY: We just incremented the refcount. This increment is now owned by the new `Arc`. | |
270 | unsafe { Self::from_inner(self.ptr) } | |
271 | } | |
272 | } | |
273 | ||
274 | impl<T: ?Sized> Drop for Arc<T> { | |
275 | fn drop(&mut self) { | |
276 | // SAFETY: By the type invariant, there is necessarily a reference to the object. We cannot | |
277 | // touch `refcount` after it's decremented to a non-zero value because another thread/CPU | |
278 | // may concurrently decrement it to zero and free it. It is ok to have a raw pointer to | |
279 | // freed/invalid memory as long as it is never dereferenced. | |
280 | let refcount = unsafe { self.ptr.as_ref() }.refcount.get(); | |
281 | ||
282 | // INVARIANT: If the refcount reaches zero, there are no other instances of `Arc`, and | |
283 | // this instance is being dropped, so the broken invariant is not observable. | |
284 | // SAFETY: Also by the type invariant, we are allowed to decrement the refcount. | |
285 | let is_zero = unsafe { bindings::refcount_dec_and_test(refcount) }; | |
286 | if is_zero { | |
287 | // The count reached zero, we must free the memory. | |
288 | // | |
289 | // SAFETY: The pointer was initialised from the result of `Box::leak`. | |
290 | unsafe { Box::from_raw(self.ptr.as_ptr()) }; | |
291 | } | |
292 | } | |
293 | } | |
17f67160 | 294 | |
70e42ebb WAF |
295 | impl<T: ?Sized> From<UniqueArc<T>> for Arc<T> { |
296 | fn from(item: UniqueArc<T>) -> Self { | |
297 | item.inner | |
298 | } | |
299 | } | |
300 | ||
301 | impl<T: ?Sized> From<Pin<UniqueArc<T>>> for Arc<T> { | |
302 | fn from(item: Pin<UniqueArc<T>>) -> Self { | |
303 | // SAFETY: The type invariants of `Arc` guarantee that the data is pinned. | |
304 | unsafe { Pin::into_inner_unchecked(item).inner } | |
305 | } | |
306 | } | |
307 | ||
17f67160 WAF |
308 | /// A borrowed reference to an [`Arc`] instance. |
309 | /// | |
310 | /// For cases when one doesn't ever need to increment the refcount on the allocation, it is simpler | |
311 | /// to use just `&T`, which we can trivially get from an `Arc<T>` instance. | |
312 | /// | |
313 | /// However, when one may need to increment the refcount, it is preferable to use an `ArcBorrow<T>` | |
314 | /// over `&Arc<T>` because the latter results in a double-indirection: a pointer (shared reference) | |
315 | /// to a pointer (`Arc<T>`) to the object (`T`). An [`ArcBorrow`] eliminates this double | |
316 | /// indirection while still allowing one to increment the refcount and getting an `Arc<T>` when/if | |
317 | /// needed. | |
318 | /// | |
319 | /// # Invariants | |
320 | /// | |
321 | /// There are no mutable references to the underlying [`Arc`], and it remains valid for the | |
322 | /// lifetime of the [`ArcBorrow`] instance. | |
323 | /// | |
324 | /// # Example | |
325 | /// | |
326 | /// ``` | |
327 | /// use crate::sync::{Arc, ArcBorrow}; | |
328 | /// | |
329 | /// struct Example; | |
330 | /// | |
331 | /// fn do_something(e: ArcBorrow<'_, Example>) -> Arc<Example> { | |
332 | /// e.into() | |
333 | /// } | |
334 | /// | |
335 | /// let obj = Arc::try_new(Example)?; | |
336 | /// let cloned = do_something(obj.as_arc_borrow()); | |
337 | /// | |
338 | /// // Assert that both `obj` and `cloned` point to the same underlying object. | |
339 | /// assert!(core::ptr::eq(&*obj, &*cloned)); | |
340 | /// ``` | |
92a655ae WAF |
341 | /// |
342 | /// Using `ArcBorrow<T>` as the type of `self`: | |
343 | /// | |
344 | /// ``` | |
345 | /// use crate::sync::{Arc, ArcBorrow}; | |
346 | /// | |
347 | /// struct Example { | |
348 | /// a: u32, | |
349 | /// b: u32, | |
350 | /// } | |
351 | /// | |
352 | /// impl Example { | |
353 | /// fn use_reference(self: ArcBorrow<'_, Self>) { | |
354 | /// // ... | |
355 | /// } | |
356 | /// } | |
357 | /// | |
358 | /// let obj = Arc::try_new(Example { a: 10, b: 20 })?; | |
359 | /// obj.as_arc_borrow().use_reference(); | |
360 | /// ``` | |
17f67160 WAF |
361 | pub struct ArcBorrow<'a, T: ?Sized + 'a> { |
362 | inner: NonNull<ArcInner<T>>, | |
363 | _p: PhantomData<&'a ()>, | |
364 | } | |
365 | ||
92a655ae WAF |
366 | // This is to allow [`ArcBorrow`] (and variants) to be used as the type of `self`. |
367 | impl<T: ?Sized> core::ops::Receiver for ArcBorrow<'_, T> {} | |
368 | ||
0748424a WAF |
369 | // This is to allow `ArcBorrow<U>` to be dispatched on when `ArcBorrow<T>` can be coerced into |
370 | // `ArcBorrow<U>`. | |
371 | impl<T: ?Sized + Unsize<U>, U: ?Sized> core::ops::DispatchFromDyn<ArcBorrow<'_, U>> | |
372 | for ArcBorrow<'_, T> | |
373 | { | |
374 | } | |
375 | ||
17f67160 WAF |
376 | impl<T: ?Sized> Clone for ArcBorrow<'_, T> { |
377 | fn clone(&self) -> Self { | |
378 | *self | |
379 | } | |
380 | } | |
381 | ||
382 | impl<T: ?Sized> Copy for ArcBorrow<'_, T> {} | |
383 | ||
384 | impl<T: ?Sized> ArcBorrow<'_, T> { | |
385 | /// Creates a new [`ArcBorrow`] instance. | |
386 | /// | |
387 | /// # Safety | |
388 | /// | |
389 | /// Callers must ensure the following for the lifetime of the returned [`ArcBorrow`] instance: | |
390 | /// 1. That `inner` remains valid; | |
391 | /// 2. That no mutable references to `inner` are created. | |
392 | unsafe fn new(inner: NonNull<ArcInner<T>>) -> Self { | |
393 | // INVARIANT: The safety requirements guarantee the invariants. | |
394 | Self { | |
395 | inner, | |
396 | _p: PhantomData, | |
397 | } | |
398 | } | |
399 | } | |
400 | ||
401 | impl<T: ?Sized> From<ArcBorrow<'_, T>> for Arc<T> { | |
402 | fn from(b: ArcBorrow<'_, T>) -> Self { | |
403 | // SAFETY: The existence of `b` guarantees that the refcount is non-zero. `ManuallyDrop` | |
404 | // guarantees that `drop` isn't called, so it's ok that the temporary `Arc` doesn't own the | |
405 | // increment. | |
406 | ManuallyDrop::new(unsafe { Arc::from_inner(b.inner) }) | |
407 | .deref() | |
408 | .clone() | |
409 | } | |
410 | } | |
411 | ||
412 | impl<T: ?Sized> Deref for ArcBorrow<'_, T> { | |
413 | type Target = T; | |
414 | ||
415 | fn deref(&self) -> &Self::Target { | |
416 | // SAFETY: By the type invariant, the underlying object is still alive with no mutable | |
417 | // references to it, so it is safe to create a shared reference. | |
418 | unsafe { &self.inner.as_ref().data } | |
419 | } | |
420 | } | |
70e42ebb WAF |
421 | |
422 | /// A refcounted object that is known to have a refcount of 1. | |
423 | /// | |
424 | /// It is mutable and can be converted to an [`Arc`] so that it can be shared. | |
425 | /// | |
426 | /// # Invariants | |
427 | /// | |
428 | /// `inner` always has a reference count of 1. | |
429 | /// | |
430 | /// # Examples | |
431 | /// | |
432 | /// In the following example, we make changes to the inner object before turning it into an | |
433 | /// `Arc<Test>` object (after which point, it cannot be mutated directly). Note that `x.into()` | |
434 | /// cannot fail. | |
435 | /// | |
436 | /// ``` | |
437 | /// use kernel::sync::{Arc, UniqueArc}; | |
438 | /// | |
439 | /// struct Example { | |
440 | /// a: u32, | |
441 | /// b: u32, | |
442 | /// } | |
443 | /// | |
444 | /// fn test() -> Result<Arc<Example>> { | |
445 | /// let mut x = UniqueArc::try_new(Example { a: 10, b: 20 })?; | |
446 | /// x.a += 1; | |
447 | /// x.b += 1; | |
448 | /// Ok(x.into()) | |
449 | /// } | |
450 | /// | |
451 | /// # test().unwrap(); | |
452 | /// ``` | |
453 | /// | |
454 | /// In the following example we first allocate memory for a ref-counted `Example` but we don't | |
455 | /// initialise it on allocation. We do initialise it later with a call to [`UniqueArc::write`], | |
456 | /// followed by a conversion to `Arc<Example>`. This is particularly useful when allocation happens | |
457 | /// in one context (e.g., sleepable) and initialisation in another (e.g., atomic): | |
458 | /// | |
459 | /// ``` | |
460 | /// use kernel::sync::{Arc, UniqueArc}; | |
461 | /// | |
462 | /// struct Example { | |
463 | /// a: u32, | |
464 | /// b: u32, | |
465 | /// } | |
466 | /// | |
467 | /// fn test() -> Result<Arc<Example>> { | |
468 | /// let x = UniqueArc::try_new_uninit()?; | |
469 | /// Ok(x.write(Example { a: 10, b: 20 }).into()) | |
470 | /// } | |
471 | /// | |
472 | /// # test().unwrap(); | |
473 | /// ``` | |
474 | /// | |
475 | /// In the last example below, the caller gets a pinned instance of `Example` while converting to | |
476 | /// `Arc<Example>`; this is useful in scenarios where one needs a pinned reference during | |
477 | /// initialisation, for example, when initialising fields that are wrapped in locks. | |
478 | /// | |
479 | /// ``` | |
480 | /// use kernel::sync::{Arc, UniqueArc}; | |
481 | /// | |
482 | /// struct Example { | |
483 | /// a: u32, | |
484 | /// b: u32, | |
485 | /// } | |
486 | /// | |
487 | /// fn test() -> Result<Arc<Example>> { | |
488 | /// let mut pinned = Pin::from(UniqueArc::try_new(Example { a: 10, b: 20 })?); | |
489 | /// // We can modify `pinned` because it is `Unpin`. | |
490 | /// pinned.as_mut().a += 1; | |
491 | /// Ok(pinned.into()) | |
492 | /// } | |
493 | /// | |
494 | /// # test().unwrap(); | |
495 | /// ``` | |
496 | pub struct UniqueArc<T: ?Sized> { | |
497 | inner: Arc<T>, | |
498 | } | |
499 | ||
500 | impl<T> UniqueArc<T> { | |
501 | /// Tries to allocate a new [`UniqueArc`] instance. | |
d6dbca35 | 502 | pub fn try_new(value: T) -> Result<Self, AllocError> { |
70e42ebb WAF |
503 | Ok(Self { |
504 | // INVARIANT: The newly-created object has a ref-count of 1. | |
505 | inner: Arc::try_new(value)?, | |
506 | }) | |
507 | } | |
508 | ||
509 | /// Tries to allocate a new [`UniqueArc`] instance whose contents are not initialised yet. | |
d6dbca35 | 510 | pub fn try_new_uninit() -> Result<UniqueArc<MaybeUninit<T>>, AllocError> { |
701608bd BL |
511 | // INVARIANT: The refcount is initialised to a non-zero value. |
512 | let inner = Box::try_init::<AllocError>(try_init!(ArcInner { | |
513 | // SAFETY: There are no safety requirements for this FFI call. | |
514 | refcount: Opaque::new(unsafe { bindings::REFCOUNT_INIT(1) }), | |
515 | data <- init::uninit::<T, AllocError>(), | |
516 | }? AllocError))?; | |
517 | Ok(UniqueArc { | |
70e42ebb | 518 | // INVARIANT: The newly-created object has a ref-count of 1. |
701608bd BL |
519 | // SAFETY: The pointer from the `Box` is valid. |
520 | inner: unsafe { Arc::from_inner(Box::leak(inner).into()) }, | |
70e42ebb WAF |
521 | }) |
522 | } | |
523 | } | |
524 | ||
525 | impl<T> UniqueArc<MaybeUninit<T>> { | |
526 | /// Converts a `UniqueArc<MaybeUninit<T>>` into a `UniqueArc<T>` by writing a value into it. | |
527 | pub fn write(mut self, value: T) -> UniqueArc<T> { | |
528 | self.deref_mut().write(value); | |
31d95c2f AL |
529 | // SAFETY: We just wrote the value to be initialized. |
530 | unsafe { self.assume_init() } | |
531 | } | |
532 | ||
533 | /// Unsafely assume that `self` is initialized. | |
534 | /// | |
535 | /// # Safety | |
536 | /// | |
537 | /// The caller guarantees that the value behind this pointer has been initialized. It is | |
538 | /// *immediate* UB to call this when the value is not initialized. | |
539 | pub unsafe fn assume_init(self) -> UniqueArc<T> { | |
70e42ebb WAF |
540 | let inner = ManuallyDrop::new(self).inner.ptr; |
541 | UniqueArc { | |
542 | // SAFETY: The new `Arc` is taking over `ptr` from `self.inner` (which won't be | |
543 | // dropped). The types are compatible because `MaybeUninit<T>` is compatible with `T`. | |
544 | inner: unsafe { Arc::from_inner(inner.cast()) }, | |
545 | } | |
546 | } | |
1944caa8 BL |
547 | |
548 | /// Initialize `self` using the given initializer. | |
549 | pub fn init_with<E>(mut self, init: impl Init<T, E>) -> core::result::Result<UniqueArc<T>, E> { | |
550 | // SAFETY: The supplied pointer is valid for initialization. | |
551 | match unsafe { init.__init(self.as_mut_ptr()) } { | |
552 | // SAFETY: Initialization completed successfully. | |
553 | Ok(()) => Ok(unsafe { self.assume_init() }), | |
554 | Err(err) => Err(err), | |
555 | } | |
556 | } | |
557 | ||
558 | /// Pin-initialize `self` using the given pin-initializer. | |
559 | pub fn pin_init_with<E>( | |
560 | mut self, | |
561 | init: impl PinInit<T, E>, | |
562 | ) -> core::result::Result<Pin<UniqueArc<T>>, E> { | |
563 | // SAFETY: The supplied pointer is valid for initialization and we will later pin the value | |
564 | // to ensure it does not move. | |
565 | match unsafe { init.__pinned_init(self.as_mut_ptr()) } { | |
566 | // SAFETY: Initialization completed successfully. | |
567 | Ok(()) => Ok(unsafe { self.assume_init() }.into()), | |
568 | Err(err) => Err(err), | |
569 | } | |
570 | } | |
70e42ebb WAF |
571 | } |
572 | ||
573 | impl<T: ?Sized> From<UniqueArc<T>> for Pin<UniqueArc<T>> { | |
574 | fn from(obj: UniqueArc<T>) -> Self { | |
575 | // SAFETY: It is not possible to move/replace `T` inside a `Pin<UniqueArc<T>>` (unless `T` | |
576 | // is `Unpin`), so it is ok to convert it to `Pin<UniqueArc<T>>`. | |
577 | unsafe { Pin::new_unchecked(obj) } | |
578 | } | |
579 | } | |
580 | ||
581 | impl<T: ?Sized> Deref for UniqueArc<T> { | |
582 | type Target = T; | |
583 | ||
584 | fn deref(&self) -> &Self::Target { | |
585 | self.inner.deref() | |
586 | } | |
587 | } | |
588 | ||
589 | impl<T: ?Sized> DerefMut for UniqueArc<T> { | |
590 | fn deref_mut(&mut self) -> &mut Self::Target { | |
591 | // SAFETY: By the `Arc` type invariant, there is necessarily a reference to the object, so | |
592 | // it is safe to dereference it. Additionally, we know there is only one reference when | |
593 | // it's inside a `UniqueArc`, so it is safe to get a mutable reference. | |
594 | unsafe { &mut self.inner.ptr.as_mut().data } | |
595 | } | |
596 | } | |
00140a83 BF |
597 | |
598 | impl<T: fmt::Display + ?Sized> fmt::Display for UniqueArc<T> { | |
599 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
600 | fmt::Display::fmt(self.deref(), f) | |
601 | } | |
602 | } | |
603 | ||
604 | impl<T: fmt::Display + ?Sized> fmt::Display for Arc<T> { | |
605 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
606 | fmt::Display::fmt(self.deref(), f) | |
607 | } | |
608 | } | |
609 | ||
610 | impl<T: fmt::Debug + ?Sized> fmt::Debug for UniqueArc<T> { | |
611 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
612 | fmt::Debug::fmt(self.deref(), f) | |
613 | } | |
614 | } | |
615 | ||
616 | impl<T: fmt::Debug + ?Sized> fmt::Debug for Arc<T> { | |
617 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
618 | fmt::Debug::fmt(self.deref(), f) | |
619 | } | |
620 | } |