1use {
5 crate::{ANCHOR_DROPPED, ANCHOR_POISONED, ANCHOR_STILL_IN_USE},
6 std::{
7 borrow::Borrow,
8 fmt::Debug,
9 marker::PhantomData,
10 mem::ManuallyDrop,
11 ops::{Deref, DerefMut},
12 panic::{RefUnwindSafe, UnwindSafe},
13 ptr::NonNull,
14 sync::{Arc, Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard, Weak},
15 },
16 wyz::pipe::*,
17};
18
19#[derive(Debug, Clone, Copy)]
22#[repr(transparent)]
23struct SSNonNull<T: ?Sized>(NonNull<T>);
24unsafe impl<T: ?Sized + Send> Send for SSNonNull<T> {
25 }
27unsafe impl<T: ?Sized + Sync> Sync for SSNonNull<T> {
28 }
30impl<T: ?Sized> From<&T> for SSNonNull<T> {
31 #[inline]
32 fn from(value: &T) -> Self {
33 Self(value.into())
34 }
35}
36impl<T: ?Sized> From<&mut T> for SSNonNull<T> {
37 #[inline]
38 fn from(value: &mut T) -> Self {
39 Self(value.into())
40 }
41}
42impl<T: ?Sized> Deref for SSNonNull<T> {
43 type Target = NonNull<T>;
44 #[inline]
45 fn deref(&self) -> &Self::Target {
46 &self.0
47 }
48}
49impl<T: ?Sized> DerefMut for SSNonNull<T> {
50 #[inline]
51 fn deref_mut(&mut self) -> &mut Self::Target {
52 &mut self.0
53 }
54}
55
56#[derive(Debug)]
78#[repr(transparent)]
79pub struct Anchor<'a, T: ?Sized> {
80 reference: ManuallyDrop<Arc<SSNonNull<T>>>,
82
83 _phantom: PhantomData<&'a T>,
85}
86
87#[derive(Debug)]
132#[repr(transparent)]
133pub struct RwAnchor<'a, T: ?Sized> {
134 reference: ManuallyDrop<Arc<RwLock<SSNonNull<T>>>>,
136
137 _phantom: PhantomData<&'a mut T>,
139}
140
141#[derive(Debug)]
186#[repr(transparent)]
187pub struct WAnchor<'a, T: ?Sized> {
188 reference: ManuallyDrop<Arc<Mutex<SSNonNull<T>>>>,
190
191 _phantom: PhantomData<&'a mut T>,
193}
194
195impl<'a, T: ?Sized> Anchor<'a, T> {
196 #[inline]
197 pub fn new(reference: &'a T) -> Self {
198 Self {
199 reference: ManuallyDrop::new(Arc::new(reference.into())),
200 _phantom: PhantomData,
201 }
202 }
203
204 #[inline]
205 pub fn portal(&self) -> Portal<T> {
206 self.reference.pipe_deref(Arc::clone).pipe(Portal)
207 }
208
209 #[inline]
210 pub fn weak_portal(&self) -> WeakPortal<T> {
211 Portal::downgrade(&self.portal())
212 }
213}
214
215impl<'a, T: ?Sized> RwAnchor<'a, T> {
216 #[inline]
217 pub fn new(reference: &'a mut T) -> Self {
218 Self {
219 reference: ManuallyDrop::new(Arc::new(RwLock::new(reference.into()))),
220 _phantom: PhantomData,
221 }
222 }
223
224 #[inline]
225 pub fn portal(&self) -> RwPortal<T> {
226 self.reference.pipe_deref(Arc::clone).pipe(RwPortal)
227 }
228
229 #[inline]
230 pub fn weak_portal(&self) -> WeakRwPortal<T> {
231 self.portal().downgrade()
232 }
233}
234
235impl<'a, T: ?Sized> WAnchor<'a, T> {
236 #[inline]
237 pub fn new(reference: &'a mut T) -> Self {
238 Self {
239 reference: ManuallyDrop::new(Arc::new(Mutex::new(reference.into()))),
240 _phantom: PhantomData,
241 }
242 }
243
244 #[inline]
245 pub fn portal(&self) -> WPortal<T> {
246 self.reference.pipe_deref(Arc::clone).pipe(WPortal)
247 }
248
249 #[inline]
250 pub fn weak_portal(&self) -> WeakWPortal<T> {
251 self.portal().downgrade()
252 }
253}
254
255impl<'a, T: ?Sized> Drop for Anchor<'a, T> {
256 fn drop(&mut self) {
277 unsafe {
278 ManuallyDrop::take(&mut self.reference)
280 }
281 .pipe(Arc::try_unwrap)
282 .unwrap_or_else(|_| panic!(ANCHOR_STILL_IN_USE));
283 }
284}
285
286impl<'a, T: ?Sized> Drop for RwAnchor<'a, T> {
287 fn drop(&mut self) {
313 unsafe {
314 ManuallyDrop::take(&mut self.reference)
316 }
317 .pipe(Arc::try_unwrap)
318 .unwrap_or_else(|reference| {
319 let _guard = reference.write();
321 panic!(ANCHOR_STILL_IN_USE);
322 })
323 .into_inner()
324 .unwrap_or_else(|error| Err(error).expect(ANCHOR_POISONED));
325 }
326}
327
328impl<'a, T: ?Sized> Drop for WAnchor<'a, T> {
329 fn drop(&mut self) {
355 unsafe {
356 ManuallyDrop::take(&mut self.reference)
358 }
359 .pipe(Arc::try_unwrap)
360 .unwrap_or_else(|reference| {
361 let _guard = reference.lock();
363 panic!(ANCHOR_STILL_IN_USE);
364 })
365 .into_inner()
366 .unwrap_or_else(|error| Err(error).expect(ANCHOR_POISONED));
367 }
368}
369
370impl<'a, T: ?Sized> UnwindSafe for RwAnchor<'a, T> where T: RefUnwindSafe {}
392
393impl<'a, T: ?Sized> UnwindSafe for WAnchor<'a, T> where T: RefUnwindSafe {}
415
416#[derive(Debug)]
419#[must_use]
420#[repr(transparent)]
421pub struct Portal<T: ?Sized>(Arc<SSNonNull<T>>);
422
423#[derive(Debug)]
426#[must_use]
427#[repr(transparent)]
428pub struct RwPortal<T: ?Sized>(Arc<RwLock<SSNonNull<T>>>);
429
430#[derive(Debug)]
433#[must_use]
434#[repr(transparent)]
435pub struct WPortal<T: ?Sized>(Arc<Mutex<SSNonNull<T>>>);
436
437impl<T: ?Sized> Portal<T> {
438 #[inline]
441 pub fn downgrade(portal: &Self) -> WeakPortal<T> {
442 Arc::downgrade(&portal.0).pipe(WeakPortal)
443 }
444}
445
446impl<T: ?Sized> Deref for Portal<T> {
447 type Target = T;
448 #[inline]
449 fn deref(&self) -> &Self::Target {
450 let pointer = self.0.deref();
451 unsafe {
452 pointer.as_ref()
454 }
455 }
456}
457
458impl<T: ?Sized> Borrow<T> for Portal<T> {
459 #[inline]
460 fn borrow(&self) -> &T {
461 &*self
462 }
463}
464
465impl<T: ?Sized> RwPortal<T> {
466 #[inline]
469 pub fn downgrade(&self) -> WeakRwPortal<T> {
470 Arc::downgrade(&self.0).pipe(WeakRwPortal)
471 }
472
473 #[inline]
474 pub fn read<'a>(&'a self) -> impl Deref<Target = T> + 'a {
475 self.0.read().expect(ANCHOR_POISONED).pipe(PortalReadGuard)
476 }
477
478 #[inline]
479 pub fn write<'a>(&'a self) -> impl DerefMut<Target = T> + 'a {
480 self.0
481 .write()
482 .expect(ANCHOR_POISONED)
483 .pipe(PortalWriteGuard)
484 }
485}
486
487impl<T: ?Sized> WPortal<T> {
488 #[inline]
491 pub fn downgrade(&self) -> WeakWPortal<T> {
492 Arc::downgrade(&self.0).pipe(WeakWPortal)
493 }
494
495 #[inline]
496 pub fn lock<'a>(&'a self) -> impl DerefMut<Target = T> + 'a {
497 self.0.lock().expect(ANCHOR_POISONED).pipe(PortalMutexGuard)
498 }
499}
500
501impl<T: ?Sized> Clone for Portal<T> {
502 #[inline]
503 fn clone(&self) -> Self {
504 self.0.pipe_ref(Arc::clone).pipe(Self)
505 }
506}
507
508impl<T: ?Sized> Clone for RwPortal<T> {
509 #[inline]
510 fn clone(&self) -> Self {
511 self.0.pipe_ref(Arc::clone).pipe(Self)
512 }
513}
514
515impl<T: ?Sized> Clone for WPortal<T> {
516 #[inline]
517 fn clone(&self) -> Self {
518 self.0.pipe_ref(Arc::clone).pipe(Self)
519 }
520}
521
522#[derive(Debug)]
523#[must_use]
524#[repr(transparent)]
525pub struct WeakPortal<T: ?Sized>(Weak<SSNonNull<T>>);
526
527#[derive(Debug)]
528#[must_use]
529#[repr(transparent)]
530pub struct WeakRwPortal<T: ?Sized>(Weak<RwLock<SSNonNull<T>>>);
531
532#[derive(Debug)]
533#[must_use]
534#[repr(transparent)]
535pub struct WeakWPortal<T: ?Sized>(Weak<Mutex<SSNonNull<T>>>);
536
537impl<T: ?Sized> WeakPortal<T> {
538 #[inline]
539 pub fn try_upgrade(&self) -> Option<Portal<T>> {
540 self.0.upgrade().map(Portal)
541 }
542
543 #[inline]
544 pub fn upgrade(&self) -> Portal<T> {
545 self.try_upgrade().expect(ANCHOR_DROPPED)
546 }
547}
548
549impl<T: ?Sized> WeakRwPortal<T> {
550 #[inline]
551 pub fn try_upgrade(&self) -> Option<RwPortal<T>> {
552 self.0.upgrade().map(RwPortal)
553 }
554
555 #[inline]
556 pub fn upgrade(&self) -> RwPortal<T> {
557 self.try_upgrade().expect(ANCHOR_DROPPED)
558 }
559}
560
561impl<T: ?Sized> WeakWPortal<T> {
562 #[inline]
563 pub fn try_upgrade(&self) -> Option<WPortal<T>> {
564 self.0.upgrade().map(WPortal)
565 }
566
567 #[inline]
568 pub fn upgrade(&self) -> WPortal<T> {
569 self.try_upgrade().expect(ANCHOR_DROPPED)
570 }
571}
572
573impl<T: ?Sized> Clone for WeakPortal<T> {
574 #[inline]
575 fn clone(&self) -> Self {
576 self.0.pipe_ref(Weak::clone).pipe(Self)
577 }
578}
579
580impl<T: ?Sized> Clone for WeakRwPortal<T> {
581 #[inline]
582 fn clone(&self) -> Self {
583 self.0.pipe_ref(Weak::clone).pipe(Self)
584 }
585}
586
587impl<T: ?Sized> Clone for WeakWPortal<T> {
588 #[inline]
589 fn clone(&self) -> Self {
590 self.0.pipe_ref(Weak::clone).pipe(Self)
591 }
592}
593
594#[repr(transparent)]
595struct PortalReadGuard<'a, T: 'a + ?Sized>(RwLockReadGuard<'a, SSNonNull<T>>);
596
597#[repr(transparent)]
598struct PortalWriteGuard<'a, T: 'a + ?Sized>(RwLockWriteGuard<'a, SSNonNull<T>>);
599
600#[repr(transparent)]
601struct PortalMutexGuard<'a, T: 'a + ?Sized>(MutexGuard<'a, SSNonNull<T>>);
602
603impl<'a, T: ?Sized> Deref for PortalReadGuard<'a, T> {
604 type Target = T;
605 #[inline]
606 fn deref(&self) -> &T {
607 let pointer = self.0.deref();
608 unsafe {
609 pointer.as_ref()
611 }
612 }
613}
614
615impl<'a, T: ?Sized> Deref for PortalWriteGuard<'a, T> {
616 type Target = T;
617 #[inline]
618 fn deref(&self) -> &T {
619 let pointer = self.0.deref();
620 unsafe {
621 pointer.as_ref()
623 }
624 }
625}
626
627impl<'a, T: ?Sized> Deref for PortalMutexGuard<'a, T> {
628 type Target = T;
629 #[inline]
630 fn deref(&self) -> &T {
631 let pointer = self.0.deref();
632 unsafe {
633 pointer.as_ref()
635 }
636 }
637}
638
639impl<'a, T: ?Sized> DerefMut for PortalWriteGuard<'a, T> {
640 #[inline]
641 fn deref_mut(&mut self) -> &mut T {
642 let pointer = self.0.deref_mut();
643 unsafe {
644 pointer.as_mut()
646 }
647 }
648}
649
650impl<'a, T: ?Sized> DerefMut for PortalMutexGuard<'a, T> {
651 #[inline]
652 fn deref_mut(&mut self) -> &mut T {
653 let pointer = self.0.deref_mut();
654 unsafe {
655 pointer.as_mut()
657 }
658 }
659}
660
661#[cfg(test)]
662mod tests {
663 use super::*;
664
665 fn _auto_trait_assertions() {
666 use {assert_impl::assert_impl, core::any::Any};
668
669 trait S: Send {}
670 trait SS: Send + Sync {}
671
672 assert_impl!(!Send: WAnchor<'_, dyn Any>, WPortal<dyn Any>);
673 assert_impl!(Send: WAnchor<'_, dyn S>, WPortal<dyn S>);
674 assert_impl!(
675 !Send: Anchor<'_, dyn S>,
676 RwAnchor<'_, dyn S>,
677 Portal<dyn S>,
678 RwPortal<dyn S>,
679 );
680 assert_impl!(
681 Send: Anchor<'_, dyn SS>,
682 RwAnchor<'_, dyn SS>,
683 Portal<dyn SS>,
684 RwPortal<dyn SS>,
685 );
686 assert_impl!(
687 !Send: PortalReadGuard<'_, ()>,
688 PortalWriteGuard<'_, ()>,
689 PortalMutexGuard<'_, ()>,
690 );
691
692 assert_impl!(!Sync: WPortal<dyn Any>);
693 assert_impl!(Sync: WPortal<dyn S>);
694 assert_impl!(
695 !Sync: Anchor<'_, dyn S>,
696 RwAnchor<'_, dyn S>,
697 WAnchor<'_, dyn S>,
698 Portal<dyn S>,
699 RwPortal<dyn S>,
700 PortalReadGuard<'_, dyn S>,
701 PortalWriteGuard<'_, dyn S>,
702 PortalMutexGuard<'_, dyn S>,
703 );
704 assert_impl!(
705 Sync: Anchor<'_, dyn SS>,
706 RwAnchor<'_, dyn SS>,
707 WAnchor<'_, dyn SS>,
708 Portal<dyn SS>,
709 RwPortal<dyn SS>,
710 PortalReadGuard<'_, dyn SS>,
711 PortalWriteGuard<'_, dyn SS>,
712 PortalMutexGuard<'_, dyn SS>,
713 );
714
715 assert_impl!(
716 UnwindSafe: PortalReadGuard<'_, dyn Any>,
717 PortalWriteGuard<'_, dyn Any>,
718 PortalMutexGuard<'_, dyn Any>,
719 );
720 assert_impl!(
721 !UnwindSafe: Anchor<'_, dyn UnwindSafe>,
722 Portal<dyn UnwindSafe>,
723 );
724 assert_impl!(
725 UnwindSafe: Anchor<'_, dyn RefUnwindSafe>,
726 RwAnchor<'_, dyn RefUnwindSafe>,
727 WAnchor<'_, dyn RefUnwindSafe>,
728 Portal<dyn RefUnwindSafe>,
729 );
730
731 assert_impl!(
732 RefUnwindSafe: RwPortal<dyn Any>,
733 WPortal<dyn Any>,
734 PortalReadGuard<'_, dyn Any>,
735 PortalWriteGuard<'_, dyn Any>,
736 PortalMutexGuard<'_, dyn Any>,
737 );
738 assert_impl!(
739 !RefUnwindSafe: Anchor<'_, dyn UnwindSafe>,
740 RwAnchor<'_, dyn UnwindSafe>,
741 WAnchor<'_, dyn UnwindSafe>,
742 Portal<dyn UnwindSafe>,
743 );
744 assert_impl!(
745 RefUnwindSafe: Anchor<'_, dyn RefUnwindSafe>,
746 RwAnchor<'_, dyn RefUnwindSafe>,
747 WAnchor<'_, dyn RefUnwindSafe>,
748 Portal<dyn RefUnwindSafe>,
749 );
750
751 assert_impl!(
752 Unpin: Anchor<'_, dyn Any>,
753 RwAnchor<'_, dyn Any>,
754 WAnchor<'_, dyn Any>,
755 Portal<dyn Any>,
756 RwPortal<dyn Any>,
757 WPortal<dyn Any>,
758 PortalReadGuard<'_, dyn Any>,
759 PortalWriteGuard<'_, dyn Any>,
760 PortalMutexGuard<'_, dyn Any>,
761 )
762 }
763
764 fn _impl_trait_assertions() {
765 use {assert_impl::assert_impl, core::any::Any};
766
767 assert_impl!(
768 Clone: Portal<dyn Any>,
769 RwPortal<dyn Any>,
770 WeakPortal<dyn Any>,
771 WeakRwPortal<dyn Any>,
772 );
773
774 assert_impl!(Deref<Target = dyn Any>: Portal<dyn Any>);
775 assert_impl!(Borrow<dyn Any>: Portal<dyn Any>);
776 }
777 }