1use std::{
55 future::poll_fn,
56 ops::{Deref, DerefMut},
57 sync::{
58 Arc, Weak,
59 atomic::{AtomicBool, AtomicUsize, Ordering},
60 },
61 task::Poll,
62};
63
64#[derive(Default)]
69struct LifetimeStateInner {
70 locked: AtomicBool,
71 readers: AtomicUsize,
72 writer: AtomicUsize,
73 read_access: AtomicUsize,
74 write_access: AtomicBool,
75 tag: AtomicUsize,
76}
77
78#[derive(Default, Clone)]
83pub struct LifetimeState {
84 inner: Arc<LifetimeStateInner>,
85}
86
87impl LifetimeState {
88 pub fn can_read(&self) -> bool {
90 self.inner.writer.load(Ordering::Acquire) == 0
91 }
92
93 pub fn can_write(&self, id: usize) -> bool {
99 self.inner.writer.load(Ordering::Acquire) == id
100 && self.inner.readers.load(Ordering::Acquire) == 0
101 }
102
103 pub fn readers_count(&self) -> usize {
105 self.inner.readers.load(Ordering::Acquire)
106 }
107
108 pub fn writer_depth(&self) -> usize {
110 self.inner.writer.load(Ordering::Acquire)
111 }
112
113 pub fn is_read_accessible(&self) -> bool {
115 !self.inner.write_access.load(Ordering::Acquire)
116 }
117
118 pub fn is_write_accessible(&self) -> bool {
120 !self.inner.write_access.load(Ordering::Acquire)
121 && self.inner.read_access.load(Ordering::Acquire) == 0
122 }
123
124 pub fn is_in_use(&self) -> bool {
126 self.inner.read_access.load(Ordering::Acquire) > 0
127 || self.inner.write_access.load(Ordering::Acquire)
128 }
129
130 pub fn is_locked(&self) -> bool {
132 self.inner.locked.load(Ordering::Acquire)
133 }
134
135 pub fn try_lock(&'_ self) -> Option<LifetimeStateAccess<'_>> {
137 if self
138 .inner
139 .locked
140 .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
141 .is_ok()
142 {
143 Some(LifetimeStateAccess {
144 state: self,
145 unlock: true,
146 })
147 } else {
148 None
149 }
150 }
151
152 pub fn lock(&'_ self) -> LifetimeStateAccess<'_> {
154 while self
155 .inner
156 .locked
157 .compare_exchange_weak(false, true, Ordering::Acquire, Ordering::Relaxed)
158 .is_err()
159 {
160 std::hint::spin_loop();
161 }
162 LifetimeStateAccess {
163 state: self,
164 unlock: true,
165 }
166 }
167
168 pub unsafe fn lock_unchecked(&'_ self) -> LifetimeStateAccess<'_> {
176 LifetimeStateAccess {
177 state: self,
178 unlock: true,
179 }
180 }
181
182 pub unsafe fn update_tag(&self, tag: &Lifetime) {
189 let tag = tag as *const Lifetime as usize;
190 self.inner.tag.store(tag, Ordering::Release);
191 }
192
193 pub unsafe fn invalidate_tag(&self) {
200 self.inner.tag.store(0, Ordering::Release);
201 }
202
203 pub fn tag(&self) -> usize {
205 self.inner.tag.load(Ordering::Acquire)
206 }
207
208 pub fn downgrade(&self) -> LifetimeWeakState {
210 LifetimeWeakState {
211 inner: Arc::downgrade(&self.inner),
212 tag: self.inner.tag.load(Ordering::Acquire),
213 }
214 }
215}
216
217#[derive(Clone)]
223pub struct LifetimeWeakState {
224 inner: Weak<LifetimeStateInner>,
225 tag: usize,
226}
227
228impl LifetimeWeakState {
229 pub unsafe fn upgrade_unchecked(&self) -> Option<LifetimeState> {
238 Some(LifetimeState {
239 inner: self.inner.upgrade()?,
240 })
241 }
242
243 pub fn upgrade(&self) -> Option<LifetimeState> {
246 let inner = self.inner.upgrade()?;
247 (inner.tag.load(Ordering::Acquire) == self.tag).then_some(LifetimeState { inner })
248 }
249
250 pub fn is_owned_by(&self, state: &LifetimeState) -> bool {
252 Arc::downgrade(&state.inner).ptr_eq(&self.inner)
253 }
254}
255
256pub struct LifetimeStateAccess<'a> {
263 state: &'a LifetimeState,
264 unlock: bool,
265}
266
267impl Drop for LifetimeStateAccess<'_> {
268 fn drop(&mut self) {
269 if self.unlock {
270 self.state.inner.locked.store(false, Ordering::Release);
271 }
272 }
273}
274
275impl LifetimeStateAccess<'_> {
276 pub fn state(&self) -> &LifetimeState {
278 self.state
279 }
280
281 pub fn unlock(&mut self, value: bool) {
287 self.unlock = value;
288 }
289
290 pub fn acquire_reader(&mut self) {
292 let v = self.state.inner.readers.load(Ordering::Acquire) + 1;
293 self.state.inner.readers.store(v, Ordering::Release);
294 }
295
296 pub fn release_reader(&mut self) {
298 let v = self
299 .state
300 .inner
301 .readers
302 .load(Ordering::Acquire)
303 .saturating_sub(1);
304 self.state.inner.readers.store(v, Ordering::Release);
305 }
306
307 #[must_use]
311 pub fn acquire_writer(&mut self) -> usize {
312 let v = self.state.inner.writer.load(Ordering::Acquire) + 1;
313 self.state.inner.writer.store(v, Ordering::Release);
314 v
315 }
316
317 pub fn release_writer(&mut self, id: usize) {
320 let v = self.state.inner.writer.load(Ordering::Acquire);
321 if id <= v {
322 self.state
323 .inner
324 .writer
325 .store(id.saturating_sub(1), Ordering::Release);
326 }
327 }
328
329 pub fn acquire_read_access(&mut self) {
331 let v = self.state.inner.read_access.load(Ordering::Acquire) + 1;
332 self.state.inner.read_access.store(v, Ordering::Release);
333 }
334
335 pub fn release_read_access(&mut self) {
337 let v = self
338 .state
339 .inner
340 .read_access
341 .load(Ordering::Acquire)
342 .saturating_sub(1);
343 self.state.inner.read_access.store(v, Ordering::Release);
344 }
345
346 pub fn acquire_write_access(&mut self) {
348 self.state.inner.write_access.store(true, Ordering::Release);
349 }
350
351 pub fn release_write_access(&mut self) {
353 self.state
354 .inner
355 .write_access
356 .store(false, Ordering::Release);
357 }
358}
359
360#[derive(Default)]
366pub struct Lifetime(LifetimeState);
367
368impl Lifetime {
369 pub fn invalidate(&mut self) {
374 unsafe { self.0.invalidate_tag() };
375 self.0 = Default::default();
376 }
377
378 pub fn state(&self) -> &LifetimeState {
380 unsafe { self.0.update_tag(self) };
381 &self.0
382 }
383
384 pub fn update_tag(&self) {
389 unsafe { self.0.update_tag(self) };
390 }
391
392 pub fn tag(&self) -> usize {
394 unsafe { self.0.update_tag(self) };
395 self.0.tag()
396 }
397
398 pub fn borrow(&self) -> Option<LifetimeRef> {
400 unsafe { self.0.update_tag(self) };
401 self.0
402 .try_lock()
403 .filter(|access| access.state.can_read())
404 .map(|mut access| {
405 access.acquire_reader();
406 LifetimeRef(self.0.downgrade())
407 })
408 }
409
410 pub async fn borrow_async(&self) -> LifetimeRef {
412 loop {
413 if let Some(lifetime_ref) = self.borrow() {
414 return lifetime_ref;
415 }
416 poll_fn(|cx| {
417 cx.waker().wake_by_ref();
418 Poll::<LifetimeRef>::Pending
419 })
420 .await;
421 }
422 }
423
424 pub fn borrow_mut(&self) -> Option<LifetimeRefMut> {
426 unsafe { self.0.update_tag(self) };
427 self.0
428 .try_lock()
429 .filter(|access| access.state.can_write(0))
430 .map(|mut access| {
431 let id = access.acquire_writer();
432 LifetimeRefMut(self.0.downgrade(), id)
433 })
434 }
435
436 pub async fn borrow_mut_async(&self) -> LifetimeRefMut {
438 loop {
439 if let Some(lifetime_ref_mut) = self.borrow_mut() {
440 return lifetime_ref_mut;
441 }
442 poll_fn(|cx| {
443 cx.waker().wake_by_ref();
444 Poll::<LifetimeRefMut>::Pending
445 })
446 .await;
447 }
448 }
449
450 pub fn lazy(&self) -> LifetimeLazy {
452 unsafe { self.0.update_tag(self) };
453 LifetimeLazy(self.0.downgrade())
454 }
455
456 pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
462 unsafe { self.0.update_tag(self) };
463 self.0
464 .try_lock()
465 .filter(|access| access.state.is_read_accessible())
466 .map(|mut access| {
467 access.acquire_read_access();
468 ValueReadAccess {
469 lifetime: self.0.clone(),
470 data,
471 }
472 })
473 }
474
475 pub async fn read_async<'a, T: ?Sized>(&'a self, data: &'a T) -> ValueReadAccess<'a, T> {
477 unsafe { self.read_ptr_async(data as *const T).await }
478 }
479
480 pub unsafe fn read_ptr<T: ?Sized>(&'_ self, data: *const T) -> Option<ValueReadAccess<'_, T>> {
487 if data.is_null() {
488 return None;
489 }
490 unsafe { self.0.update_tag(self) };
491 self.0
492 .try_lock()
493 .filter(|access| access.state.is_read_accessible())
494 .map(|mut access| {
495 access.acquire_read_access();
496 ValueReadAccess {
497 lifetime: self.0.clone(),
498 data: unsafe { &*data },
499 }
500 })
501 }
502
503 pub async unsafe fn read_ptr_async<'a, T: ?Sized + 'a>(
510 &'a self,
511 data: *const T,
512 ) -> ValueReadAccess<'a, T> {
513 loop {
514 if let Some(access) = unsafe { self.read_ptr(data) } {
515 return access;
516 }
517 poll_fn(|cx| {
518 cx.waker().wake_by_ref();
519 Poll::<ValueReadAccess<'a, T>>::Pending
520 })
521 .await;
522 }
523 }
524
525 pub fn write<'a, T: ?Sized>(&'a self, data: &'a mut T) -> Option<ValueWriteAccess<'a, T>> {
528 unsafe { self.0.update_tag(self) };
529 self.0
530 .try_lock()
531 .filter(|access| access.state.is_write_accessible())
532 .map(|mut access| {
533 access.acquire_write_access();
534 ValueWriteAccess {
535 lifetime: self.0.clone(),
536 data,
537 }
538 })
539 }
540
541 pub async fn write_async<'a, T: ?Sized>(&'a self, data: &'a mut T) -> ValueWriteAccess<'a, T> {
543 unsafe { self.write_ptr_async(data as *mut T).await }
544 }
545
546 pub unsafe fn write_ptr<T: ?Sized>(&'_ self, data: *mut T) -> Option<ValueWriteAccess<'_, T>> {
553 if data.is_null() {
554 return None;
555 }
556 unsafe { self.0.update_tag(self) };
557 self.0
558 .try_lock()
559 .filter(|access| access.state.is_write_accessible())
560 .map(|mut access| {
561 access.acquire_write_access();
562 ValueWriteAccess {
563 lifetime: self.0.clone(),
564 data: unsafe { &mut *data },
565 }
566 })
567 }
568
569 pub async unsafe fn write_ptr_async<'a, T: ?Sized + 'a>(
576 &'a self,
577 data: *mut T,
578 ) -> ValueWriteAccess<'a, T> {
579 loop {
580 if let Some(access) = unsafe { self.write_ptr(data) } {
581 return access;
582 }
583 poll_fn(|cx| {
584 cx.waker().wake_by_ref();
585 Poll::<ValueWriteAccess<'a, T>>::Pending
586 })
587 .await;
588 }
589 }
590
591 pub fn try_read_lock(&self) -> Option<ReadLock> {
594 unsafe { self.0.update_tag(self) };
595 let mut access = self.0.lock();
596 if !access.state.is_read_accessible() {
597 return None;
598 }
599 access.acquire_read_access();
600 Some(ReadLock {
601 lifetime: self.0.clone(),
602 })
603 }
604
605 pub fn read_lock(&self) -> ReadLock {
607 unsafe { self.0.update_tag(self) };
608 let mut access = self.0.lock();
609 while !access.state.is_read_accessible() {
610 std::hint::spin_loop();
611 }
612 access.acquire_read_access();
613 ReadLock {
614 lifetime: self.0.clone(),
615 }
616 }
617
618 pub async fn read_lock_async(&self) -> ReadLock {
620 loop {
621 unsafe { self.0.update_tag(self) };
622 let mut access = self.0.lock();
623 if access.state.is_read_accessible() {
624 access.acquire_read_access();
625 return ReadLock {
626 lifetime: self.0.clone(),
627 };
628 }
629 poll_fn(|cx| {
630 cx.waker().wake_by_ref();
631 Poll::<ReadLock>::Pending
632 })
633 .await;
634 }
635 }
636
637 pub fn try_write_lock(&self) -> Option<WriteLock> {
640 unsafe { self.0.update_tag(self) };
641 let mut access = self.0.lock();
642 if !access.state.is_write_accessible() {
643 return None;
644 }
645 access.acquire_write_access();
646 Some(WriteLock {
647 lifetime: self.0.clone(),
648 })
649 }
650
651 pub fn write_lock(&self) -> WriteLock {
653 unsafe { self.0.update_tag(self) };
654 let mut access = self.0.lock();
655 while !access.state.is_write_accessible() {
656 std::hint::spin_loop();
657 }
658 access.acquire_write_access();
659 WriteLock {
660 lifetime: self.0.clone(),
661 }
662 }
663
664 pub async fn write_lock_async(&self) -> WriteLock {
666 loop {
667 unsafe { self.0.update_tag(self) };
668 let mut access = self.0.lock();
669 if access.state.is_write_accessible() {
670 access.acquire_write_access();
671 return WriteLock {
672 lifetime: self.0.clone(),
673 };
674 }
675 poll_fn(|cx| {
676 cx.waker().wake_by_ref();
677 Poll::<WriteLock>::Pending
678 })
679 .await;
680 }
681 }
682
683 pub async fn wait_for_read_access(&self) {
685 loop {
686 if self.state().is_read_accessible() {
687 return;
688 }
689 poll_fn(|cx| {
690 cx.waker().wake_by_ref();
691 Poll::<()>::Pending
692 })
693 .await;
694 }
695 }
696
697 pub async fn wait_for_write_access(&self) {
699 loop {
700 if self.state().is_write_accessible() {
701 return;
702 }
703 poll_fn(|cx| {
704 cx.waker().wake_by_ref();
705 Poll::<()>::Pending
706 })
707 .await;
708 }
709 }
710}
711
712pub struct LifetimeRef(LifetimeWeakState);
717
718impl Drop for LifetimeRef {
719 fn drop(&mut self) {
720 if let Some(owner) = unsafe { self.0.upgrade_unchecked() }
721 && let Some(mut access) = owner.try_lock()
722 {
723 access.release_reader();
724 }
725 }
726}
727
728impl LifetimeRef {
729 pub fn state(&self) -> &LifetimeWeakState {
731 &self.0
732 }
733
734 pub fn tag(&self) -> usize {
736 self.0.tag
737 }
738
739 pub fn exists(&self) -> bool {
741 self.0.upgrade().is_some()
742 }
743
744 pub fn can_read(&self) -> bool {
746 self.0
747 .upgrade()
748 .map(|state| state.can_read())
749 .unwrap_or(false)
750 }
751
752 pub fn is_read_accessible(&self) -> bool {
754 self.0
755 .upgrade()
756 .map(|state| state.is_read_accessible())
757 .unwrap_or(false)
758 }
759
760 pub fn is_in_use(&self) -> bool {
762 self.0
763 .upgrade()
764 .map(|state| state.is_in_use())
765 .unwrap_or(false)
766 }
767
768 pub fn is_owned_by(&self, other: &Lifetime) -> bool {
770 self.0.is_owned_by(&other.0)
771 }
772
773 pub fn borrow(&self) -> Option<LifetimeRef> {
775 self.0
776 .upgrade()?
777 .try_lock()
778 .filter(|access| access.state.can_read())
779 .map(|mut access| {
780 access.acquire_reader();
781 LifetimeRef(self.0.clone())
782 })
783 }
784
785 pub async fn borrow_async(&self) -> LifetimeRef {
787 loop {
788 if let Some(lifetime_ref) = self.borrow() {
789 return lifetime_ref;
790 }
791 poll_fn(|cx| {
792 cx.waker().wake_by_ref();
793 Poll::<LifetimeRef>::Pending
794 })
795 .await;
796 }
797 }
798
799 pub fn lazy(&self) -> LifetimeLazy {
801 LifetimeLazy(self.0.clone())
802 }
803
804 pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
807 let state = self.0.upgrade()?;
808 let mut access = state.try_lock()?;
809 if access.state.is_read_accessible() {
810 access.acquire_read_access();
811 drop(access);
812 Some(ValueReadAccess {
813 lifetime: state,
814 data,
815 })
816 } else {
817 None
818 }
819 }
820
821 pub async fn read_async<'a, T: ?Sized>(&'a self, data: &'a T) -> ValueReadAccess<'a, T> {
823 loop {
824 if let Some(access) = self.read(data) {
825 return access;
826 }
827 poll_fn(|cx| {
828 cx.waker().wake_by_ref();
829 Poll::<ValueReadAccess<'a, T>>::Pending
830 })
831 .await;
832 }
833 }
834
835 pub unsafe fn read_ptr<T: ?Sized>(&'_ self, data: *const T) -> Option<ValueReadAccess<'_, T>> {
842 if data.is_null() {
846 return None;
847 }
848 let state = self.0.upgrade()?;
849 let mut access = state.try_lock()?;
850 if access.state.is_read_accessible() {
851 access.acquire_read_access();
852 drop(access);
853 Some(ValueReadAccess {
854 lifetime: state,
855 data: unsafe { &*data },
856 })
857 } else {
858 None
859 }
860 }
861
862 pub async unsafe fn read_ptr_async<'a, T: ?Sized + 'a>(
869 &'a self,
870 data: *const T,
871 ) -> ValueReadAccess<'a, T> {
872 loop {
873 if let Some(access) = unsafe { self.read_ptr(data) } {
874 return access;
875 }
876 poll_fn(|cx| {
877 cx.waker().wake_by_ref();
878 Poll::<ValueReadAccess<'a, T>>::Pending
879 })
880 .await;
881 }
882 }
883
884 pub fn try_read_lock(&self) -> Option<ReadLock> {
886 let state = self.0.upgrade()?;
887 let mut access = state.lock();
888 if !access.state.is_read_accessible() {
889 return None;
890 }
891 access.acquire_read_access();
892 Some(ReadLock {
893 lifetime: state.clone(),
894 })
895 }
896
897 pub fn read_lock(&self) -> Option<ReadLock> {
900 let state = self.0.upgrade()?;
901 let mut access = state.lock();
902 while !access.state.is_read_accessible() {
903 std::hint::spin_loop();
904 }
905 access.acquire_read_access();
906 Some(ReadLock {
907 lifetime: state.clone(),
908 })
909 }
910
911 pub async fn read_lock_async(&self) -> ReadLock {
913 loop {
914 if let Some(lock) = self.read_lock() {
915 return lock;
916 }
917 poll_fn(|cx| {
918 cx.waker().wake_by_ref();
919 Poll::<ReadLock>::Pending
920 })
921 .await;
922 }
923 }
924
925 pub fn consume<T: ?Sized>(self, data: &'_ T) -> Result<ValueReadAccess<'_, T>, Self> {
930 let state = match self.0.upgrade() {
931 Some(state) => state,
932 None => return Err(self),
933 };
934 let mut access = match state.try_lock() {
935 Some(access) => access,
936 None => return Err(self),
937 };
938 if access.state.is_read_accessible() {
939 access.acquire_read_access();
940 drop(access);
941 Ok(ValueReadAccess {
942 lifetime: state,
943 data,
944 })
945 } else {
946 Err(self)
947 }
948 }
949
950 pub async fn wait_for_read_access(&self) {
952 loop {
953 let Some(state) = self.0.upgrade() else {
954 return;
955 };
956 if state.is_read_accessible() {
957 return;
958 }
959 poll_fn(|cx| {
960 cx.waker().wake_by_ref();
961 Poll::<()>::Pending
962 })
963 .await;
964 }
965 }
966
967 pub async fn wait_for_write_access(&self) {
969 loop {
970 let Some(state) = self.0.upgrade() else {
971 return;
972 };
973 if state.is_write_accessible() {
974 return;
975 }
976 poll_fn(|cx| {
977 cx.waker().wake_by_ref();
978 Poll::<()>::Pending
979 })
980 .await;
981 }
982 }
983}
984
985pub struct LifetimeRefMut(LifetimeWeakState, usize);
991
992impl Drop for LifetimeRefMut {
993 fn drop(&mut self) {
994 if let Some(state) = unsafe { self.0.upgrade_unchecked() }
995 && let Some(mut access) = state.try_lock()
996 {
997 access.release_writer(self.1);
998 }
999 }
1000}
1001
1002impl LifetimeRefMut {
1003 pub fn state(&self) -> &LifetimeWeakState {
1005 &self.0
1006 }
1007
1008 pub fn tag(&self) -> usize {
1010 self.0.tag
1011 }
1012
1013 pub fn depth(&self) -> usize {
1015 self.1
1016 }
1017
1018 pub fn exists(&self) -> bool {
1020 self.0.upgrade().is_some()
1021 }
1022
1023 pub fn can_read(&self) -> bool {
1025 self.0
1026 .upgrade()
1027 .map(|state| state.can_read())
1028 .unwrap_or(false)
1029 }
1030
1031 pub fn can_write(&self) -> bool {
1033 self.0
1034 .upgrade()
1035 .map(|state| state.can_write(self.1))
1036 .unwrap_or(false)
1037 }
1038
1039 pub fn is_read_accessible(&self) -> bool {
1041 self.0
1042 .upgrade()
1043 .map(|state| state.is_read_accessible())
1044 .unwrap_or(false)
1045 }
1046
1047 pub fn is_write_accessible(&self) -> bool {
1049 self.0
1050 .upgrade()
1051 .map(|state| state.is_write_accessible())
1052 .unwrap_or(false)
1053 }
1054
1055 pub fn is_in_use(&self) -> bool {
1057 self.0
1058 .upgrade()
1059 .map(|state| state.is_in_use())
1060 .unwrap_or(false)
1061 }
1062
1063 pub fn is_owned_by(&self, other: &Lifetime) -> bool {
1065 self.0.is_owned_by(&other.0)
1066 }
1067
1068 pub fn borrow(&self) -> Option<LifetimeRef> {
1071 self.0
1072 .upgrade()?
1073 .try_lock()
1074 .filter(|access| access.state.can_read())
1075 .map(|mut access| {
1076 access.acquire_reader();
1077 LifetimeRef(self.0.clone())
1078 })
1079 }
1080
1081 pub async fn borrow_async(&self) -> LifetimeRef {
1083 loop {
1084 if let Some(lifetime_ref) = self.borrow() {
1085 return lifetime_ref;
1086 }
1087 poll_fn(|cx| {
1088 cx.waker().wake_by_ref();
1089 Poll::<LifetimeRef>::Pending
1090 })
1091 .await;
1092 }
1093 }
1094
1095 pub fn borrow_mut(&self) -> Option<LifetimeRefMut> {
1098 self.0
1099 .upgrade()?
1100 .try_lock()
1101 .filter(|access| access.state.can_write(self.1))
1102 .map(|mut access| {
1103 let id = access.acquire_writer();
1104 LifetimeRefMut(self.0.clone(), id)
1105 })
1106 }
1107
1108 pub async fn borrow_mut_async(&self) -> LifetimeRefMut {
1110 loop {
1111 if let Some(lifetime_ref_mut) = self.borrow_mut() {
1112 return lifetime_ref_mut;
1113 }
1114 poll_fn(|cx| {
1115 cx.waker().wake_by_ref();
1116 Poll::<LifetimeRefMut>::Pending
1117 })
1118 .await;
1119 }
1120 }
1121
1122 pub fn lazy(&self) -> LifetimeLazy {
1124 LifetimeLazy(self.0.clone())
1125 }
1126
1127 pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
1130 let state = self.0.upgrade()?;
1131 let mut access = state.try_lock()?;
1132 if access.state.is_read_accessible() {
1133 access.acquire_read_access();
1134 drop(access);
1135 Some(ValueReadAccess {
1136 lifetime: state,
1137 data,
1138 })
1139 } else {
1140 None
1141 }
1142 }
1143
1144 pub async fn read_async<'a, T: ?Sized>(&'a self, data: &'a T) -> ValueReadAccess<'a, T> {
1146 loop {
1147 if let Some(access) = self.read(data) {
1148 return access;
1149 }
1150 poll_fn(|cx| {
1151 cx.waker().wake_by_ref();
1152 Poll::<ValueReadAccess<'a, T>>::Pending
1153 })
1154 .await;
1155 }
1156 }
1157
1158 pub unsafe fn read_ptr<T: ?Sized>(&'_ self, data: *const T) -> Option<ValueReadAccess<'_, T>> {
1165 if data.is_null() {
1169 return None;
1170 }
1171 let state = self.0.upgrade()?;
1172 let mut access = state.try_lock()?;
1173 if access.state.is_read_accessible() {
1174 access.acquire_read_access();
1175 drop(access);
1176 Some(ValueReadAccess {
1177 lifetime: state,
1178 data: unsafe { &*data },
1179 })
1180 } else {
1181 None
1182 }
1183 }
1184
1185 pub async unsafe fn read_ptr_async<'a, T: ?Sized + 'a>(
1192 &'a self,
1193 data: *const T,
1194 ) -> ValueReadAccess<'a, T> {
1195 loop {
1196 if let Some(access) = unsafe { self.read_ptr(data) } {
1197 return access;
1198 }
1199 poll_fn(|cx| {
1200 cx.waker().wake_by_ref();
1201 Poll::<ValueReadAccess<'a, T>>::Pending
1202 })
1203 .await;
1204 }
1205 }
1206
1207 pub fn write<'a, T: ?Sized>(&'a self, data: &'a mut T) -> Option<ValueWriteAccess<'a, T>> {
1210 let state = self.0.upgrade()?;
1211 let mut access = state.try_lock()?;
1212 if access.state.is_write_accessible() {
1213 access.acquire_write_access();
1214 drop(access);
1215 Some(ValueWriteAccess {
1216 lifetime: state,
1217 data,
1218 })
1219 } else {
1220 None
1221 }
1222 }
1223
1224 pub async fn write_async<'a, T: ?Sized>(&'a self, data: &'a mut T) -> ValueWriteAccess<'a, T> {
1226 unsafe { self.write_ptr_async(data as *mut T).await }
1227 }
1228
1229 pub unsafe fn write_ptr<T: ?Sized>(&'_ self, data: *mut T) -> Option<ValueWriteAccess<'_, T>> {
1236 if data.is_null() {
1240 return None;
1241 }
1242 let state = self.0.upgrade()?;
1243 let mut access = state.try_lock()?;
1244 if access.state.is_write_accessible() {
1245 access.acquire_write_access();
1246 drop(access);
1247 Some(ValueWriteAccess {
1248 lifetime: state,
1249 data: unsafe { &mut *data },
1250 })
1251 } else {
1252 None
1253 }
1254 }
1255
1256 pub async unsafe fn write_ptr_async<'a, T: ?Sized + 'a>(
1263 &'a self,
1264 data: *mut T,
1265 ) -> ValueWriteAccess<'a, T> {
1266 loop {
1267 if let Some(access) = unsafe { self.write_ptr(data) } {
1268 return access;
1269 }
1270 poll_fn(|cx| {
1271 cx.waker().wake_by_ref();
1272 Poll::<ValueWriteAccess<'a, T>>::Pending
1273 })
1274 .await;
1275 }
1276 }
1277
1278 pub fn try_read_lock(&self) -> Option<ReadLock> {
1280 let state = self.0.upgrade()?;
1281 let mut access = state.lock();
1282 if !access.state.is_read_accessible() {
1283 return None;
1284 }
1285 access.acquire_read_access();
1286 Some(ReadLock {
1287 lifetime: state.clone(),
1288 })
1289 }
1290
1291 pub fn read_lock(&self) -> Option<ReadLock> {
1294 let state = self.0.upgrade()?;
1295 let mut access = state.lock();
1296 while !access.state.is_read_accessible() {
1297 std::hint::spin_loop();
1298 }
1299 access.acquire_read_access();
1300 Some(ReadLock {
1301 lifetime: state.clone(),
1302 })
1303 }
1304
1305 pub async fn read_lock_async(&self) -> ReadLock {
1307 loop {
1308 if let Some(lock) = self.read_lock() {
1309 return lock;
1310 }
1311 poll_fn(|cx| {
1312 cx.waker().wake_by_ref();
1313 Poll::<ReadLock>::Pending
1314 })
1315 .await;
1316 }
1317 }
1318
1319 pub fn try_write_lock(&self) -> Option<WriteLock> {
1321 let state = self.0.upgrade()?;
1322 let mut access = state.lock();
1323 if !access.state.is_write_accessible() {
1324 return None;
1325 }
1326 access.acquire_write_access();
1327 Some(WriteLock {
1328 lifetime: state.clone(),
1329 })
1330 }
1331
1332 pub fn write_lock(&self) -> Option<WriteLock> {
1335 let state = self.0.upgrade()?;
1336 let mut access = state.lock();
1337 while !access.state.is_write_accessible() {
1338 std::hint::spin_loop();
1339 }
1340 access.acquire_write_access();
1341 Some(WriteLock {
1342 lifetime: state.clone(),
1343 })
1344 }
1345
1346 pub async fn write_lock_async(&self) -> WriteLock {
1348 loop {
1349 if let Some(lock) = self.write_lock() {
1350 return lock;
1351 }
1352 poll_fn(|cx| {
1353 cx.waker().wake_by_ref();
1354 Poll::<WriteLock>::Pending
1355 })
1356 .await;
1357 }
1358 }
1359
1360 pub fn consume<T: ?Sized>(self, data: &'_ mut T) -> Result<ValueWriteAccess<'_, T>, Self> {
1365 let state = match self.0.upgrade() {
1366 Some(state) => state,
1367 None => return Err(self),
1368 };
1369 let mut access = match state.try_lock() {
1370 Some(access) => access,
1371 None => return Err(self),
1372 };
1373 if access.state.is_write_accessible() {
1374 access.acquire_write_access();
1375 drop(access);
1376 Ok(ValueWriteAccess {
1377 lifetime: state,
1378 data,
1379 })
1380 } else {
1381 Err(self)
1382 }
1383 }
1384
1385 pub async fn wait_for_read_access(&self) {
1387 loop {
1388 let Some(state) = self.0.upgrade() else {
1389 return;
1390 };
1391 if state.is_read_accessible() {
1392 return;
1393 }
1394 poll_fn(|cx| {
1395 cx.waker().wake_by_ref();
1396 Poll::<()>::Pending
1397 })
1398 .await;
1399 }
1400 }
1401
1402 pub async fn wait_for_write_access(&self) {
1404 loop {
1405 let Some(state) = self.0.upgrade() else {
1406 return;
1407 };
1408 if state.is_write_accessible() {
1409 return;
1410 }
1411 poll_fn(|cx| {
1412 cx.waker().wake_by_ref();
1413 Poll::<()>::Pending
1414 })
1415 .await;
1416 }
1417 }
1418}
1419
1420#[derive(Clone)]
1427pub struct LifetimeLazy(LifetimeWeakState);
1428
1429impl LifetimeLazy {
1430 pub fn state(&self) -> &LifetimeWeakState {
1432 &self.0
1433 }
1434
1435 pub fn tag(&self) -> usize {
1437 self.0.tag
1438 }
1439
1440 pub fn exists(&self) -> bool {
1442 self.0.upgrade().is_some()
1443 }
1444
1445 pub fn is_read_accessible(&self) -> bool {
1447 self.0
1448 .upgrade()
1449 .map(|state| state.is_read_accessible())
1450 .unwrap_or(false)
1451 }
1452
1453 pub fn is_write_accessible(&self) -> bool {
1455 self.0
1456 .upgrade()
1457 .map(|state| state.is_write_accessible())
1458 .unwrap_or(false)
1459 }
1460
1461 pub fn is_in_use(&self) -> bool {
1463 self.0
1464 .upgrade()
1465 .map(|state| state.is_in_use())
1466 .unwrap_or(false)
1467 }
1468
1469 pub fn is_owned_by(&self, other: &Lifetime) -> bool {
1471 self.0.is_owned_by(&other.0)
1472 }
1473
1474 pub fn borrow(&self) -> Option<LifetimeRef> {
1476 self.0
1477 .upgrade()?
1478 .try_lock()
1479 .filter(|access| access.state.can_read())
1480 .map(|mut access| {
1481 access.acquire_reader();
1482 LifetimeRef(self.0.clone())
1483 })
1484 }
1485
1486 pub async fn borrow_async(&self) -> LifetimeRef {
1488 loop {
1489 if let Some(lifetime_ref) = self.borrow() {
1490 return lifetime_ref;
1491 }
1492 poll_fn(|cx| {
1493 cx.waker().wake_by_ref();
1494 Poll::<LifetimeRef>::Pending
1495 })
1496 .await;
1497 }
1498 }
1499
1500 pub fn borrow_mut(&self) -> Option<LifetimeRefMut> {
1503 self.0
1504 .upgrade()?
1505 .try_lock()
1506 .filter(|access| access.state.can_write(0))
1507 .map(|mut access| {
1508 let id = access.acquire_writer();
1509 LifetimeRefMut(self.0.clone(), id)
1510 })
1511 }
1512
1513 pub async fn borrow_mut_async(&self) -> LifetimeRefMut {
1515 loop {
1516 if let Some(lifetime_ref_mut) = self.borrow_mut() {
1517 return lifetime_ref_mut;
1518 }
1519 poll_fn(|cx| {
1520 cx.waker().wake_by_ref();
1521 Poll::<LifetimeRefMut>::Pending
1522 })
1523 .await;
1524 }
1525 }
1526
1527 pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
1530 let state = self.0.upgrade()?;
1531 let mut access = state.try_lock()?;
1532 if access.state.is_read_accessible() {
1533 access.acquire_read_access();
1534 drop(access);
1535 Some(ValueReadAccess {
1536 lifetime: state,
1537 data,
1538 })
1539 } else {
1540 None
1541 }
1542 }
1543
1544 pub async fn read_async<'a, T: ?Sized>(&'a self, data: &'a T) -> ValueReadAccess<'a, T> {
1546 loop {
1547 if let Some(access) = self.read(data) {
1548 return access;
1549 }
1550 poll_fn(|cx| {
1551 cx.waker().wake_by_ref();
1552 Poll::<ValueReadAccess<'a, T>>::Pending
1553 })
1554 .await;
1555 }
1556 }
1557
1558 pub unsafe fn read_ptr<T: ?Sized>(&'_ self, data: *const T) -> Option<ValueReadAccess<'_, T>> {
1565 if data.is_null() {
1569 return None;
1570 }
1571 let state = self.0.upgrade()?;
1572 let mut access = state.try_lock()?;
1573 if access.state.is_read_accessible() {
1574 access.acquire_read_access();
1575 drop(access);
1576 Some(ValueReadAccess {
1577 lifetime: state,
1578 data: unsafe { &*data },
1579 })
1580 } else {
1581 None
1582 }
1583 }
1584
1585 pub async unsafe fn read_ptr_async<'a, T: ?Sized + 'a>(
1592 &'a self,
1593 data: *const T,
1594 ) -> ValueReadAccess<'a, T> {
1595 loop {
1596 if let Some(access) = unsafe { self.read_ptr(data) } {
1597 return access;
1598 }
1599 poll_fn(|cx| {
1600 cx.waker().wake_by_ref();
1601 Poll::<ValueReadAccess<'a, T>>::Pending
1602 })
1603 .await;
1604 }
1605 }
1606
1607 pub fn write<'a, T: ?Sized>(&'a self, data: &'a mut T) -> Option<ValueWriteAccess<'a, T>> {
1610 let state = self.0.upgrade()?;
1611 let mut access = state.try_lock()?;
1612 if access.state.is_write_accessible() {
1613 access.acquire_write_access();
1614 drop(access);
1615 Some(ValueWriteAccess {
1616 lifetime: state,
1617 data,
1618 })
1619 } else {
1620 None
1621 }
1622 }
1623
1624 pub async fn write_async<'a, T: ?Sized>(&'a self, data: &'a mut T) -> ValueWriteAccess<'a, T> {
1626 unsafe { self.write_ptr_async(data as *mut T).await }
1627 }
1628
1629 pub unsafe fn write_ptr<T: ?Sized>(&'_ self, data: *mut T) -> Option<ValueWriteAccess<'_, T>> {
1636 if data.is_null() {
1640 return None;
1641 }
1642 let state = self.0.upgrade()?;
1643 let mut access = state.try_lock()?;
1644 if access.state.is_write_accessible() {
1645 access.acquire_write_access();
1646 drop(access);
1647 Some(ValueWriteAccess {
1648 lifetime: state,
1649 data: unsafe { &mut *data },
1650 })
1651 } else {
1652 None
1653 }
1654 }
1655
1656 pub async unsafe fn write_ptr_async<'a, T: ?Sized + 'a>(
1663 &'a self,
1664 data: *mut T,
1665 ) -> ValueWriteAccess<'a, T> {
1666 loop {
1667 if let Some(access) = unsafe { self.write_ptr(data) } {
1668 return access;
1669 }
1670 poll_fn(|cx| {
1671 cx.waker().wake_by_ref();
1672 Poll::<ValueWriteAccess<'a, T>>::Pending
1673 })
1674 .await;
1675 }
1676 }
1677
1678 pub fn consume<T: ?Sized>(self, data: &'_ mut T) -> Result<ValueWriteAccess<'_, T>, Self> {
1682 let state = match self.0.upgrade() {
1683 Some(state) => state,
1684 None => return Err(self),
1685 };
1686 let mut access = match state.try_lock() {
1687 Some(access) => access,
1688 None => return Err(self),
1689 };
1690 if access.state.is_write_accessible() {
1691 access.acquire_write_access();
1692 drop(access);
1693 Ok(ValueWriteAccess {
1694 lifetime: state,
1695 data,
1696 })
1697 } else {
1698 Err(self)
1699 }
1700 }
1701
1702 pub async fn wait_for_read_access(&self) {
1704 loop {
1705 let Some(state) = self.0.upgrade() else {
1706 return;
1707 };
1708 if state.is_read_accessible() {
1709 return;
1710 }
1711 poll_fn(|cx| {
1712 cx.waker().wake_by_ref();
1713 Poll::<()>::Pending
1714 })
1715 .await;
1716 }
1717 }
1718
1719 pub async fn wait_for_write_access(&self) {
1721 loop {
1722 let Some(state) = self.0.upgrade() else {
1723 return;
1724 };
1725 if state.is_write_accessible() {
1726 return;
1727 }
1728 poll_fn(|cx| {
1729 cx.waker().wake_by_ref();
1730 Poll::<()>::Pending
1731 })
1732 .await;
1733 }
1734 }
1735}
1736
1737pub struct ValueReadAccess<'a, T: 'a + ?Sized> {
1741 lifetime: LifetimeState,
1742 data: &'a T,
1743}
1744
1745impl<T: ?Sized> Drop for ValueReadAccess<'_, T> {
1746 fn drop(&mut self) {
1747 self.lifetime.lock().release_read_access();
1748 }
1749}
1750
1751impl<'a, T: ?Sized> ValueReadAccess<'a, T> {
1752 pub unsafe fn new_raw(data: &'a T, lifetime: LifetimeState) -> Self {
1760 Self { lifetime, data }
1761 }
1762}
1763
1764impl<T: ?Sized> Deref for ValueReadAccess<'_, T> {
1765 type Target = T;
1766
1767 fn deref(&self) -> &Self::Target {
1768 self.data
1769 }
1770}
1771
1772impl<'a, T: ?Sized> ValueReadAccess<'a, T> {
1773 pub fn remap<U>(
1777 self,
1778 f: impl FnOnce(&T) -> Option<&U>,
1779 ) -> Result<ValueReadAccess<'a, U>, Self> {
1780 if let Some(data) = f(self.data) {
1781 Ok(ValueReadAccess {
1782 lifetime: self.lifetime.clone(),
1783 data,
1784 })
1785 } else {
1786 Err(self)
1787 }
1788 }
1789}
1790
1791pub struct ValueWriteAccess<'a, T: 'a + ?Sized> {
1797 lifetime: LifetimeState,
1798 data: &'a mut T,
1799}
1800
1801impl<T: ?Sized> Drop for ValueWriteAccess<'_, T> {
1802 fn drop(&mut self) {
1803 self.lifetime.lock().release_write_access();
1804 }
1805}
1806
1807impl<'a, T: ?Sized> ValueWriteAccess<'a, T> {
1808 pub unsafe fn new_raw(data: &'a mut T, lifetime: LifetimeState) -> Self {
1816 Self { lifetime, data }
1817 }
1818}
1819
1820impl<T: ?Sized> Deref for ValueWriteAccess<'_, T> {
1821 type Target = T;
1822
1823 fn deref(&self) -> &Self::Target {
1824 self.data
1825 }
1826}
1827
1828impl<T: ?Sized> DerefMut for ValueWriteAccess<'_, T> {
1829 fn deref_mut(&mut self) -> &mut Self::Target {
1830 self.data
1831 }
1832}
1833
1834impl<'a, T: ?Sized> ValueWriteAccess<'a, T> {
1835 pub fn remap<U>(
1839 self,
1840 f: impl FnOnce(&mut T) -> Option<&mut U>,
1841 ) -> Result<ValueWriteAccess<'a, U>, Self> {
1842 if let Some(data) = f(unsafe { std::mem::transmute::<&mut T, &'a mut T>(&mut *self.data) })
1843 {
1844 Ok(ValueWriteAccess {
1845 lifetime: self.lifetime.clone(),
1846 data,
1847 })
1848 } else {
1849 Err(self)
1850 }
1851 }
1852}
1853
1854pub struct ReadLock {
1859 lifetime: LifetimeState,
1860}
1861
1862impl Drop for ReadLock {
1863 fn drop(&mut self) {
1864 self.lifetime.lock().release_read_access();
1865 }
1866}
1867
1868impl ReadLock {
1869 pub unsafe fn new_raw(lifetime: LifetimeState) -> Self {
1876 Self { lifetime }
1877 }
1878
1879 pub fn using<R>(self, f: impl FnOnce() -> R) -> R {
1881 let result = f();
1882 drop(self);
1883 result
1884 }
1885}
1886
1887pub struct WriteLock {
1891 lifetime: LifetimeState,
1892}
1893
1894impl Drop for WriteLock {
1895 fn drop(&mut self) {
1896 self.lifetime.lock().release_write_access();
1897 }
1898}
1899
1900impl WriteLock {
1901 pub unsafe fn new_raw(lifetime: LifetimeState) -> Self {
1908 Self { lifetime }
1909 }
1910
1911 pub fn using<R>(self, f: impl FnOnce() -> R) -> R {
1913 let result = f();
1914 drop(self);
1915 result
1916 }
1917}
1918
1919#[cfg(test)]
1920mod tests {
1921 use super::*;
1922 use std::thread::*;
1923
1924 fn is_async<T: Send + Sync + ?Sized>() {
1925 println!("{} is async!", std::any::type_name::<T>());
1926 }
1927
1928 #[test]
1929 fn test_lifetimes() {
1930 is_async::<Lifetime>();
1931 is_async::<LifetimeRef>();
1932 is_async::<LifetimeRefMut>();
1933 is_async::<LifetimeLazy>();
1934
1935 let mut value = 0usize;
1936 let lifetime_ref = {
1937 let lifetime = Lifetime::default();
1938 assert!(lifetime.state().can_read());
1939 assert!(lifetime.state().can_write(0));
1940 assert!(lifetime.state().is_read_accessible());
1941 assert!(lifetime.state().is_write_accessible());
1942 let lifetime_lazy = lifetime.lazy();
1943 assert!(lifetime_lazy.read(&42).is_some());
1944 assert!(lifetime_lazy.write(&mut 42).is_some());
1945 {
1946 let access = lifetime.read(&value).unwrap();
1947 assert_eq!(*access, value);
1948 }
1949 {
1950 let mut access = lifetime.write(&mut value).unwrap();
1951 *access = 42;
1952 assert_eq!(*access, 42);
1953 }
1954 {
1955 let lifetime_ref = lifetime.borrow().unwrap();
1956 assert!(lifetime.state().can_read());
1957 assert!(!lifetime.state().can_write(0));
1958 assert!(lifetime_ref.exists());
1959 assert!(lifetime_ref.is_owned_by(&lifetime));
1960 assert!(lifetime.borrow().is_some());
1961 assert!(lifetime.borrow_mut().is_none());
1962 assert!(lifetime_lazy.read(&42).is_some());
1963 assert!(lifetime_lazy.write(&mut 42).is_some());
1964 {
1965 let access = lifetime_ref.read(&value).unwrap();
1966 assert_eq!(*access, 42);
1967 assert!(lifetime_lazy.read(&42).is_some());
1968 assert!(lifetime_lazy.write(&mut 42).is_none());
1969 }
1970 let lifetime_ref2 = lifetime_ref.borrow().unwrap();
1971 {
1972 let access = lifetime_ref2.read(&value).unwrap();
1973 assert_eq!(*access, 42);
1974 assert!(lifetime_lazy.read(&42).is_some());
1975 assert!(lifetime_lazy.write(&mut 42).is_none());
1976 }
1977 }
1978 {
1979 let lifetime_ref_mut = lifetime.borrow_mut().unwrap();
1980 assert_eq!(lifetime.state().writer_depth(), 1);
1981 assert!(!lifetime.state().can_read());
1982 assert!(!lifetime.state().can_write(0));
1983 assert!(lifetime_ref_mut.exists());
1984 assert!(lifetime_ref_mut.is_owned_by(&lifetime));
1985 assert!(lifetime.borrow().is_none());
1986 assert!(lifetime.borrow_mut().is_none());
1987 assert!(lifetime_lazy.read(&42).is_some());
1988 assert!(lifetime_lazy.write(&mut 42).is_some());
1989 {
1990 let mut access = lifetime_ref_mut.write(&mut value).unwrap();
1991 *access = 7;
1992 assert_eq!(*access, 7);
1993 assert!(lifetime_lazy.read(&42).is_none());
1994 assert!(lifetime_lazy.write(&mut 42).is_none());
1995 }
1996 let lifetime_ref_mut2 = lifetime_ref_mut.borrow_mut().unwrap();
1997 assert!(lifetime_lazy.read(&42).is_some());
1998 assert!(lifetime_lazy.write(&mut 42).is_some());
1999 {
2000 assert_eq!(lifetime.state().writer_depth(), 2);
2001 assert!(lifetime.borrow().is_none());
2002 assert!(lifetime_ref_mut.borrow().is_none());
2003 assert!(lifetime.borrow_mut().is_none());
2004 assert!(lifetime_ref_mut.borrow_mut().is_none());
2005 let mut access = lifetime_ref_mut2.write(&mut value).unwrap();
2006 *access = 42;
2007 assert_eq!(*access, 42);
2008 assert!(lifetime.read(&42).is_none());
2009 assert!(lifetime_ref_mut.read(&42).is_none());
2010 assert!(lifetime.write(&mut 42).is_none());
2011 assert!(lifetime_ref_mut.write(&mut 42).is_none());
2012 assert!(lifetime_lazy.read(&42).is_none());
2013 assert!(lifetime_lazy.write(&mut 42).is_none());
2014 assert!(lifetime_lazy.read(&42).is_none());
2015 assert!(lifetime_lazy.write(&mut 42).is_none());
2016 }
2017 }
2018 assert_eq!(lifetime.state().writer_depth(), 0);
2019 lifetime.borrow().unwrap()
2020 };
2021 assert!(!lifetime_ref.exists());
2022 assert_eq!(value, 42);
2023 }
2024
2025 #[test]
2026 fn test_lifetimes_multithread() {
2027 let lifetime = Lifetime::default();
2028 let lifetime_ref = lifetime.borrow().unwrap();
2029 assert!(lifetime_ref.exists());
2030 assert!(lifetime_ref.is_owned_by(&lifetime));
2031 drop(lifetime);
2032 assert!(!lifetime_ref.exists());
2033 let lifetime = Lifetime::default();
2034 let lifetime = spawn(move || {
2035 let value_ref = lifetime.borrow().unwrap();
2036 assert!(value_ref.exists());
2037 assert!(value_ref.is_owned_by(&lifetime));
2038 lifetime
2039 })
2040 .join()
2041 .unwrap();
2042 assert!(!lifetime_ref.exists());
2043 assert!(!lifetime_ref.is_owned_by(&lifetime));
2044 }
2045
2046 #[test]
2047 fn test_lifetimes_move_invalidation() {
2048 let lifetime = Lifetime::default();
2049 let lifetime_ref = lifetime.borrow().unwrap();
2050 assert_eq!(lifetime_ref.tag(), lifetime.tag());
2051 assert!(lifetime_ref.exists());
2052 let lifetime_ref2 = lifetime_ref;
2053 assert_eq!(lifetime_ref2.tag(), lifetime.tag());
2054 assert!(lifetime_ref2.exists());
2055 let lifetime = Box::new(lifetime);
2056 assert_ne!(lifetime_ref2.tag(), lifetime.tag());
2057 assert!(!lifetime_ref2.exists());
2058 let lifetime = *lifetime;
2059 assert_ne!(lifetime_ref2.tag(), lifetime.tag());
2060 assert!(!lifetime_ref2.exists());
2061 }
2062
2063 #[pollster::test]
2064 async fn test_lifetime_async() {
2065 let mut value = 42usize;
2066 let lifetime = Lifetime::default();
2067 assert_eq!(*lifetime.read_async(&value).await, 42);
2068 {
2069 let lifetime_ref = lifetime.borrow_async().await;
2070 {
2071 let access = lifetime_ref.read_async(&value).await;
2072 assert_eq!(*access, 42);
2073 }
2074 }
2075 {
2076 let lifetime_ref_mut = lifetime.borrow_mut_async().await;
2077 {
2078 let mut access = lifetime_ref_mut.write_async(&mut value).await;
2079 *access = 7;
2080 assert_eq!(*access, 7);
2081 }
2082 assert_eq!(*lifetime.read_async(&value).await, 7);
2083 }
2084 {
2085 let mut access = lifetime.write_async(&mut value).await;
2086 *access = 84;
2087 }
2088 {
2089 let access = lifetime.read_async(&value).await;
2090 assert_eq!(*access, 84);
2091 }
2092 }
2093
2094 #[test]
2095 fn test_lifetime_locks() {
2096 let lifetime = Lifetime::default();
2097 assert!(lifetime.state().is_read_accessible());
2098 assert!(lifetime.state().is_write_accessible());
2099
2100 let read_lock = lifetime.read_lock();
2101 assert!(lifetime.state().is_read_accessible());
2102 assert!(!lifetime.state().is_write_accessible());
2103
2104 drop(read_lock);
2105 assert!(lifetime.state().is_read_accessible());
2106 assert!(lifetime.state().is_write_accessible());
2107
2108 let read_lock = lifetime.read_lock();
2109 assert!(lifetime.state().is_read_accessible());
2110 assert!(!lifetime.state().is_write_accessible());
2111
2112 let read_lock2 = lifetime.read_lock();
2113 assert!(lifetime.state().is_read_accessible());
2114 assert!(!lifetime.state().is_write_accessible());
2115
2116 drop(read_lock);
2117 assert!(lifetime.state().is_read_accessible());
2118 assert!(!lifetime.state().is_write_accessible());
2119
2120 drop(read_lock2);
2121 assert!(lifetime.state().is_read_accessible());
2122 assert!(lifetime.state().is_write_accessible());
2123
2124 let write_lock = lifetime.write_lock();
2125 assert!(!lifetime.state().is_read_accessible());
2126 assert!(!lifetime.state().is_write_accessible());
2127
2128 assert!(lifetime.try_read_lock().is_none());
2129 assert!(lifetime.try_write_lock().is_none());
2130
2131 drop(write_lock);
2132 assert!(lifetime.state().is_read_accessible());
2133 assert!(lifetime.state().is_write_accessible());
2134
2135 let data = ();
2136 let read_access = lifetime.read(&data).unwrap();
2137 assert!(lifetime.state().is_read_accessible());
2138 assert!(!lifetime.state().is_write_accessible());
2139 assert!(!lifetime.state().is_locked());
2141
2142 drop(read_access);
2143 assert!(lifetime.try_read_lock().is_some());
2144 assert!(lifetime.try_write_lock().is_some());
2145 }
2146
2147 #[test]
2148 fn test_read_access_guards_coexist() {
2149 let mut value = 42usize;
2150 let lifetime = Lifetime::default();
2151
2152 let first = lifetime.read(&value).unwrap();
2153 let second = lifetime.read(&value).unwrap();
2154 let third = lifetime.read(&value).unwrap();
2155 assert_eq!(*first, 42);
2156 assert_eq!(*second, 42);
2157 assert_eq!(*third, 42);
2158
2159 assert!(!lifetime.state().is_locked());
2161 assert!(lifetime.state().is_read_accessible());
2162 assert!(!lifetime.state().is_write_accessible());
2164 assert!(lifetime.try_write_lock().is_none());
2165 let lock = lifetime.try_read_lock().unwrap();
2166
2167 drop(lock);
2168 drop(third);
2169 drop(second);
2170 assert!(!lifetime.state().is_write_accessible());
2171 drop(first);
2172 assert!(lifetime.state().is_write_accessible());
2173
2174 *lifetime.write(&mut value).unwrap() = 10;
2175 assert_eq!(value, 10);
2176 }
2177
2178 #[test]
2179 fn test_write_access_guard_excludes_readers() {
2180 let mut value = 42usize;
2181 let lifetime = Lifetime::default();
2182
2183 let guard = lifetime.write(&mut value).unwrap();
2184 assert!(!lifetime.state().is_locked());
2185 assert!(!lifetime.state().is_read_accessible());
2186 assert!(lifetime.try_read_lock().is_none());
2187 assert!(lifetime.lazy().read(&0).is_none());
2188
2189 drop(guard);
2190 assert!(lifetime.state().is_read_accessible());
2191 assert!(lifetime.try_read_lock().is_some());
2192 }
2193
2194 #[test]
2195 fn test_null_pointer_leaves_no_access_behind() {
2196 let lifetime = Lifetime::default();
2197
2198 assert!(unsafe { lifetime.read_ptr(std::ptr::null::<usize>()) }.is_none());
2199 assert!(unsafe { lifetime.write_ptr(std::ptr::null_mut::<usize>()) }.is_none());
2200
2201 assert!(lifetime.state().is_read_accessible());
2203 assert!(lifetime.state().is_write_accessible());
2204 assert!(lifetime.try_write_lock().is_some());
2205 }
2206
2207 #[test]
2211 fn test_dead_owner_never_dereferences_the_pointer() {
2212 let data = Box::into_raw(Box::new(42usize));
2213 let shared = Lifetime::default();
2214 let exclusive = Lifetime::default();
2215 let unclaimed = Lifetime::default();
2216 let value_ref = shared.borrow().unwrap();
2217 let value_ref_mut = exclusive.borrow_mut().unwrap();
2218 let value_lazy = unclaimed.lazy();
2219
2220 drop((shared, exclusive, unclaimed));
2221 unsafe { drop(Box::from_raw(data)) };
2222
2223 assert!(unsafe { value_ref.read_ptr(data) }.is_none());
2224 assert!(unsafe { value_ref_mut.read_ptr(data) }.is_none());
2225 assert!(unsafe { value_ref_mut.write_ptr(data) }.is_none());
2226 assert!(unsafe { value_lazy.read_ptr(data) }.is_none());
2227 assert!(unsafe { value_lazy.write_ptr(data) }.is_none());
2228 }
2229
2230 #[test]
2231 fn test_read_access_guards_across_threads() {
2232 let lifetime = Arc::new(Lifetime::default());
2233 let value = Arc::new(7usize);
2234
2235 let threads = (0..8)
2236 .map(|_| {
2237 let lifetime = lifetime.clone();
2238 let value = value.clone();
2239 spawn(move || {
2240 let mut taken = 0usize;
2241 for _ in 0..1000 {
2242 if let Some(access) = lifetime.read(value.as_ref()) {
2243 assert_eq!(*access, 7);
2244 taken += 1;
2245 }
2246 }
2247 taken
2248 })
2249 })
2250 .collect::<Vec<_>>();
2251 let total = threads
2252 .into_iter()
2253 .map(|thread| thread.join().unwrap())
2254 .sum::<usize>();
2255 assert!(total > 0);
2256
2257 assert!(lifetime.state().is_write_accessible());
2259 }
2260}