lib.rs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #![no_std]
  2. use alloc::sync::Arc;
  3. use core::{marker::PhantomData, mem::ManuallyDrop, ops::Deref, ptr::NonNull};
  4. extern crate alloc;
  5. /// BorrowedArc is a wrapper around `Arc` that allows us to create an `Arc` from a raw pointer
  6. /// that was created by `Arc::into_raw` when we are confident about that the original `Arc`
  7. /// would be still valid during the whold lifetime of `BorrowedArc`.
  8. ///
  9. /// # Example
  10. ///
  11. /// ```should_run
  12. /// use pointers::BorrowedArc;
  13. /// use alloc::sync::Arc;
  14. ///
  15. /// let arc = Arc::new(42);
  16. /// let ptr = NonNull::new(Arc::into_raw(arc.clone())).unwrap();
  17. ///
  18. /// // We know that the original `Arc` is still valid.
  19. /// let borrowed_arc = unsafe { BorrowedArc::from_raw(ptr) };
  20. ///
  21. /// let arc_reference: &Arc<i32> = &borrowed_arc;
  22. /// assert_eq!(**arc_reference, 42);
  23. /// ```
  24. pub struct BorrowedArc<'a, T: ?Sized> {
  25. arc: ManuallyDrop<Arc<T>>,
  26. _phantom: PhantomData<&'a ()>,
  27. }
  28. impl<'a, T: ?Sized> BorrowedArc<'a, T> {
  29. /// # Safety
  30. /// If `ptr` is not a valid pointer to an `Arc<T>`, this will lead to undefined behavior.
  31. ///
  32. /// If the `Arc<T>` is dropped while `BorrowedArc` is still in use, this will lead
  33. /// to undefined behavior.
  34. pub unsafe fn from_raw(ptr: NonNull<T>) -> Self {
  35. Self {
  36. arc: ManuallyDrop::new(unsafe { Arc::from_raw(ptr.as_ptr()) }),
  37. _phantom: PhantomData,
  38. }
  39. }
  40. pub fn new(ptr: &'a Arc<T>) -> Self {
  41. Self {
  42. arc: ManuallyDrop::new(unsafe { core::mem::transmute_copy(ptr) }),
  43. _phantom: PhantomData,
  44. }
  45. }
  46. pub fn borrow(&self) -> &'a T {
  47. let reference: &T = &self.arc;
  48. let ptr = reference as *const T;
  49. // SAFETY: `ptr` is a valid pointer to `T` because `reference` is a valid reference to `T`.
  50. // `ptr` is also guaranteed to be valid for the lifetime `'lt` because it is derived from
  51. // `self.arc` which is guaranteed to be valid for the lifetime `'lt`.
  52. unsafe { ptr.as_ref().unwrap() }
  53. }
  54. }
  55. impl<'a, T: ?Sized> Deref for BorrowedArc<'a, T> {
  56. type Target = Arc<T>;
  57. fn deref(&self) -> &Self::Target {
  58. &self.arc
  59. }
  60. }
  61. impl<'a, T: ?Sized> AsRef<Arc<T>> for BorrowedArc<'a, T> {
  62. fn as_ref(&self) -> &Arc<T> {
  63. &self.arc
  64. }
  65. }