lib.rs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. #[allow(dead_code)]
  41. pub fn new(ptr: &'a *const T) -> Self {
  42. assert!(!ptr.is_null());
  43. Self {
  44. arc: ManuallyDrop::new(unsafe { Arc::from_raw(*ptr) }),
  45. _phantom: PhantomData,
  46. }
  47. }
  48. pub fn borrow(&self) -> &'a T {
  49. let reference: &T = &self.arc;
  50. let ptr = reference as *const T;
  51. // SAFETY: `ptr` is a valid pointer to `T` because `reference` is a valid reference to `T`.
  52. // `ptr` is also guaranteed to be valid for the lifetime `'lt` because it is derived from
  53. // `self.arc` which is guaranteed to be valid for the lifetime `'lt`.
  54. unsafe { ptr.as_ref().unwrap() }
  55. }
  56. }
  57. impl<'a, T: ?Sized> Deref for BorrowedArc<'a, T> {
  58. type Target = Arc<T>;
  59. fn deref(&self) -> &Self::Target {
  60. &self.arc
  61. }
  62. }
  63. impl<'a, T: ?Sized> AsRef<Arc<T>> for BorrowedArc<'a, T> {
  64. fn as_ref(&self) -> &Arc<T> {
  65. &self.arc
  66. }
  67. }