obkrnl/context/
arc.rs

1use alloc::sync::Arc;
2use core::ops::Deref;
3
4/// Provides an access to the value of [Arc](alloc::sync::Arc) on [Context](super::Context) without
5/// cloning a reference.
6///
7/// We need this type because return a reference from [Context](super::Context) require static
8/// lifetime, which allow the caller to store it at a global level. Once the value is destroyed that
9/// reference will be invalid. We can solve this by return a cloned [Arc](alloc::sync::Arc) but most
10/// of the time the caller just want a temporary access to the value, which mean the increment and
11/// decrement of a reference is not needed so we invent this type to solve this problem.
12///
13/// This type work by making itself not [Send] and [Sync], which prevent the caller from storing it
14/// at a global level.
15#[repr(transparent)]
16pub struct BorrowedArc<T>(*const T); // A pointer make this type automatically !Send and !Sync.
17
18impl<T> BorrowedArc<T> {
19    /// # Safety
20    /// `v` must be owned by [Arc](alloc::sync::Arc) if not null.
21    pub(super) const unsafe fn new(v: *const T) -> Option<Self> {
22        if v.is_null() { None } else { Some(Self(v)) }
23    }
24
25    /// # Safety
26    /// `v` must be owned by [Arc](alloc::sync::Arc).
27    pub(super) const unsafe fn from_non_null(v: *const T) -> Self {
28        Self(v)
29    }
30
31    /// Note that this is an associated function, which means that you have to call it as
32    /// `BorrowedArc::as_ptr(v)` instead of `v.as_ptr()`. This is so that there is no conflict with
33    /// a method on the inner type.
34    pub fn as_ptr(this: &Self) -> *const T {
35        this.0
36    }
37
38    pub fn into_owned(self) -> Arc<T> {
39        // SAFETY: This is safe because the requirement of new() and from_non_null().
40        unsafe { Arc::increment_strong_count(self.0) };
41        unsafe { Arc::from_raw(self.0) }
42    }
43}
44
45impl<T> Clone for BorrowedArc<T> {
46    fn clone(&self) -> Self {
47        *self
48    }
49}
50
51impl<T> Copy for BorrowedArc<T> {}
52
53impl<T> Deref for BorrowedArc<T> {
54    type Target = T;
55
56    fn deref(&self) -> &Self::Target {
57        unsafe { &*self.0 }
58    }
59}