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 let data = unsafe { data.as_ref() }?;
488 unsafe { self.0.update_tag(self) };
489 self.0
490 .try_lock()
491 .filter(|access| access.state.is_read_accessible())
492 .map(|mut access| {
493 access.acquire_read_access();
494 ValueReadAccess {
495 lifetime: self.0.clone(),
496 data,
497 }
498 })
499 }
500
501 pub async unsafe fn read_ptr_async<'a, T: ?Sized + 'a>(
508 &'a self,
509 data: *const T,
510 ) -> ValueReadAccess<'a, T> {
511 loop {
512 if let Some(access) = unsafe { self.read_ptr(data) } {
513 return access;
514 }
515 poll_fn(|cx| {
516 cx.waker().wake_by_ref();
517 Poll::<ValueReadAccess<'a, T>>::Pending
518 })
519 .await;
520 }
521 }
522
523 pub fn write<'a, T: ?Sized>(&'a self, data: &'a mut T) -> Option<ValueWriteAccess<'a, T>> {
526 unsafe { self.0.update_tag(self) };
527 self.0
528 .try_lock()
529 .filter(|access| access.state.is_write_accessible())
530 .map(|mut access| {
531 access.acquire_write_access();
532 ValueWriteAccess {
533 lifetime: self.0.clone(),
534 data,
535 }
536 })
537 }
538
539 pub async fn write_async<'a, T: ?Sized>(&'a self, data: &'a mut T) -> ValueWriteAccess<'a, T> {
541 unsafe { self.write_ptr_async(data as *mut T).await }
542 }
543
544 pub unsafe fn write_ptr<T: ?Sized>(&'_ self, data: *mut T) -> Option<ValueWriteAccess<'_, T>> {
551 let data = unsafe { data.as_mut() }?;
552 unsafe { self.0.update_tag(self) };
553 self.0
554 .try_lock()
555 .filter(|access| access.state.is_write_accessible())
556 .map(|mut access| {
557 access.acquire_write_access();
558 ValueWriteAccess {
559 lifetime: self.0.clone(),
560 data,
561 }
562 })
563 }
564
565 pub async unsafe fn write_ptr_async<'a, T: ?Sized + 'a>(
572 &'a self,
573 data: *mut T,
574 ) -> ValueWriteAccess<'a, T> {
575 loop {
576 if let Some(access) = unsafe { self.write_ptr(data) } {
577 return access;
578 }
579 poll_fn(|cx| {
580 cx.waker().wake_by_ref();
581 Poll::<ValueWriteAccess<'a, T>>::Pending
582 })
583 .await;
584 }
585 }
586
587 pub fn try_read_lock(&self) -> Option<ReadLock> {
590 unsafe { self.0.update_tag(self) };
591 let mut access = self.0.lock();
592 if !access.state.is_read_accessible() {
593 return None;
594 }
595 access.acquire_read_access();
596 Some(ReadLock {
597 lifetime: self.0.clone(),
598 })
599 }
600
601 pub fn read_lock(&self) -> ReadLock {
603 unsafe { self.0.update_tag(self) };
604 let mut access = self.0.lock();
605 while !access.state.is_read_accessible() {
606 std::hint::spin_loop();
607 }
608 access.acquire_read_access();
609 ReadLock {
610 lifetime: self.0.clone(),
611 }
612 }
613
614 pub async fn read_lock_async(&self) -> ReadLock {
616 loop {
617 unsafe { self.0.update_tag(self) };
618 let mut access = self.0.lock();
619 if access.state.is_read_accessible() {
620 access.acquire_read_access();
621 return ReadLock {
622 lifetime: self.0.clone(),
623 };
624 }
625 poll_fn(|cx| {
626 cx.waker().wake_by_ref();
627 Poll::<ReadLock>::Pending
628 })
629 .await;
630 }
631 }
632
633 pub fn try_write_lock(&self) -> Option<WriteLock> {
636 unsafe { self.0.update_tag(self) };
637 let mut access = self.0.lock();
638 if !access.state.is_write_accessible() {
639 return None;
640 }
641 access.acquire_write_access();
642 Some(WriteLock {
643 lifetime: self.0.clone(),
644 })
645 }
646
647 pub fn write_lock(&self) -> WriteLock {
649 unsafe { self.0.update_tag(self) };
650 let mut access = self.0.lock();
651 while !access.state.is_write_accessible() {
652 std::hint::spin_loop();
653 }
654 access.acquire_write_access();
655 WriteLock {
656 lifetime: self.0.clone(),
657 }
658 }
659
660 pub async fn write_lock_async(&self) -> WriteLock {
662 loop {
663 unsafe { self.0.update_tag(self) };
664 let mut access = self.0.lock();
665 if access.state.is_write_accessible() {
666 access.acquire_write_access();
667 return WriteLock {
668 lifetime: self.0.clone(),
669 };
670 }
671 poll_fn(|cx| {
672 cx.waker().wake_by_ref();
673 Poll::<WriteLock>::Pending
674 })
675 .await;
676 }
677 }
678
679 pub async fn wait_for_read_access(&self) {
681 loop {
682 if self.state().is_read_accessible() {
683 return;
684 }
685 poll_fn(|cx| {
686 cx.waker().wake_by_ref();
687 Poll::<()>::Pending
688 })
689 .await;
690 }
691 }
692
693 pub async fn wait_for_write_access(&self) {
695 loop {
696 if self.state().is_write_accessible() {
697 return;
698 }
699 poll_fn(|cx| {
700 cx.waker().wake_by_ref();
701 Poll::<()>::Pending
702 })
703 .await;
704 }
705 }
706}
707
708pub struct LifetimeRef(LifetimeWeakState);
713
714impl Drop for LifetimeRef {
715 fn drop(&mut self) {
716 if let Some(owner) = unsafe { self.0.upgrade_unchecked() }
717 && let Some(mut access) = owner.try_lock()
718 {
719 access.release_reader();
720 }
721 }
722}
723
724impl LifetimeRef {
725 pub fn state(&self) -> &LifetimeWeakState {
727 &self.0
728 }
729
730 pub fn tag(&self) -> usize {
732 self.0.tag
733 }
734
735 pub fn exists(&self) -> bool {
737 self.0.upgrade().is_some()
738 }
739
740 pub fn can_read(&self) -> bool {
742 self.0
743 .upgrade()
744 .map(|state| state.can_read())
745 .unwrap_or(false)
746 }
747
748 pub fn is_read_accessible(&self) -> bool {
750 self.0
751 .upgrade()
752 .map(|state| state.is_read_accessible())
753 .unwrap_or(false)
754 }
755
756 pub fn is_in_use(&self) -> bool {
758 self.0
759 .upgrade()
760 .map(|state| state.is_in_use())
761 .unwrap_or(false)
762 }
763
764 pub fn is_owned_by(&self, other: &Lifetime) -> bool {
766 self.0.is_owned_by(&other.0)
767 }
768
769 pub fn borrow(&self) -> Option<LifetimeRef> {
771 self.0
772 .upgrade()?
773 .try_lock()
774 .filter(|access| access.state.can_read())
775 .map(|mut access| {
776 access.acquire_reader();
777 LifetimeRef(self.0.clone())
778 })
779 }
780
781 pub async fn borrow_async(&self) -> LifetimeRef {
783 loop {
784 if let Some(lifetime_ref) = self.borrow() {
785 return lifetime_ref;
786 }
787 poll_fn(|cx| {
788 cx.waker().wake_by_ref();
789 Poll::<LifetimeRef>::Pending
790 })
791 .await;
792 }
793 }
794
795 pub fn lazy(&self) -> LifetimeLazy {
797 LifetimeLazy(self.0.clone())
798 }
799
800 pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
803 let state = self.0.upgrade()?;
804 let mut access = state.try_lock()?;
805 if access.state.is_read_accessible() {
806 access.acquire_read_access();
807 drop(access);
808 Some(ValueReadAccess {
809 lifetime: state,
810 data,
811 })
812 } else {
813 None
814 }
815 }
816
817 pub async fn read_async<'a, T: ?Sized>(&'a self, data: &'a T) -> ValueReadAccess<'a, T> {
819 loop {
820 if let Some(access) = self.read(data) {
821 return access;
822 }
823 poll_fn(|cx| {
824 cx.waker().wake_by_ref();
825 Poll::<ValueReadAccess<'a, T>>::Pending
826 })
827 .await;
828 }
829 }
830
831 pub unsafe fn read_ptr<T: ?Sized>(&'_ self, data: *const T) -> Option<ValueReadAccess<'_, T>> {
838 let data = unsafe { data.as_ref() }?;
839 let state = self.0.upgrade()?;
840 let mut access = state.try_lock()?;
841 if access.state.is_read_accessible() {
842 access.acquire_read_access();
843 drop(access);
844 Some(ValueReadAccess {
845 lifetime: state,
846 data,
847 })
848 } else {
849 None
850 }
851 }
852
853 pub async unsafe fn read_ptr_async<'a, T: ?Sized + 'a>(
860 &'a self,
861 data: *const T,
862 ) -> ValueReadAccess<'a, T> {
863 loop {
864 if let Some(access) = unsafe { self.read_ptr(data) } {
865 return access;
866 }
867 poll_fn(|cx| {
868 cx.waker().wake_by_ref();
869 Poll::<ValueReadAccess<'a, T>>::Pending
870 })
871 .await;
872 }
873 }
874
875 pub fn try_read_lock(&self) -> Option<ReadLock> {
877 let state = self.0.upgrade()?;
878 let mut access = state.lock();
879 if !access.state.is_read_accessible() {
880 return None;
881 }
882 access.acquire_read_access();
883 Some(ReadLock {
884 lifetime: state.clone(),
885 })
886 }
887
888 pub fn read_lock(&self) -> Option<ReadLock> {
891 let state = self.0.upgrade()?;
892 let mut access = state.lock();
893 while !access.state.is_read_accessible() {
894 std::hint::spin_loop();
895 }
896 access.acquire_read_access();
897 Some(ReadLock {
898 lifetime: state.clone(),
899 })
900 }
901
902 pub async fn read_lock_async(&self) -> ReadLock {
904 loop {
905 if let Some(lock) = self.read_lock() {
906 return lock;
907 }
908 poll_fn(|cx| {
909 cx.waker().wake_by_ref();
910 Poll::<ReadLock>::Pending
911 })
912 .await;
913 }
914 }
915
916 pub fn consume<T: ?Sized>(self, data: &'_ T) -> Result<ValueReadAccess<'_, T>, Self> {
921 let state = match self.0.upgrade() {
922 Some(state) => state,
923 None => return Err(self),
924 };
925 let mut access = match state.try_lock() {
926 Some(access) => access,
927 None => return Err(self),
928 };
929 if access.state.is_read_accessible() {
930 access.acquire_read_access();
931 drop(access);
932 Ok(ValueReadAccess {
933 lifetime: state,
934 data,
935 })
936 } else {
937 Err(self)
938 }
939 }
940
941 pub async fn wait_for_read_access(&self) {
943 loop {
944 let Some(state) = self.0.upgrade() else {
945 return;
946 };
947 if state.is_read_accessible() {
948 return;
949 }
950 poll_fn(|cx| {
951 cx.waker().wake_by_ref();
952 Poll::<()>::Pending
953 })
954 .await;
955 }
956 }
957
958 pub async fn wait_for_write_access(&self) {
960 loop {
961 let Some(state) = self.0.upgrade() else {
962 return;
963 };
964 if state.is_write_accessible() {
965 return;
966 }
967 poll_fn(|cx| {
968 cx.waker().wake_by_ref();
969 Poll::<()>::Pending
970 })
971 .await;
972 }
973 }
974}
975
976pub struct LifetimeRefMut(LifetimeWeakState, usize);
982
983impl Drop for LifetimeRefMut {
984 fn drop(&mut self) {
985 if let Some(state) = unsafe { self.0.upgrade_unchecked() }
986 && let Some(mut access) = state.try_lock()
987 {
988 access.release_writer(self.1);
989 }
990 }
991}
992
993impl LifetimeRefMut {
994 pub fn state(&self) -> &LifetimeWeakState {
996 &self.0
997 }
998
999 pub fn tag(&self) -> usize {
1001 self.0.tag
1002 }
1003
1004 pub fn depth(&self) -> usize {
1006 self.1
1007 }
1008
1009 pub fn exists(&self) -> bool {
1011 self.0.upgrade().is_some()
1012 }
1013
1014 pub fn can_read(&self) -> bool {
1016 self.0
1017 .upgrade()
1018 .map(|state| state.can_read())
1019 .unwrap_or(false)
1020 }
1021
1022 pub fn can_write(&self) -> bool {
1024 self.0
1025 .upgrade()
1026 .map(|state| state.can_write(self.1))
1027 .unwrap_or(false)
1028 }
1029
1030 pub fn is_read_accessible(&self) -> bool {
1032 self.0
1033 .upgrade()
1034 .map(|state| state.is_read_accessible())
1035 .unwrap_or(false)
1036 }
1037
1038 pub fn is_write_accessible(&self) -> bool {
1040 self.0
1041 .upgrade()
1042 .map(|state| state.is_write_accessible())
1043 .unwrap_or(false)
1044 }
1045
1046 pub fn is_in_use(&self) -> bool {
1048 self.0
1049 .upgrade()
1050 .map(|state| state.is_in_use())
1051 .unwrap_or(false)
1052 }
1053
1054 pub fn is_owned_by(&self, other: &Lifetime) -> bool {
1056 self.0.is_owned_by(&other.0)
1057 }
1058
1059 pub fn borrow(&self) -> Option<LifetimeRef> {
1062 self.0
1063 .upgrade()?
1064 .try_lock()
1065 .filter(|access| access.state.can_read())
1066 .map(|mut access| {
1067 access.acquire_reader();
1068 LifetimeRef(self.0.clone())
1069 })
1070 }
1071
1072 pub async fn borrow_async(&self) -> LifetimeRef {
1074 loop {
1075 if let Some(lifetime_ref) = self.borrow() {
1076 return lifetime_ref;
1077 }
1078 poll_fn(|cx| {
1079 cx.waker().wake_by_ref();
1080 Poll::<LifetimeRef>::Pending
1081 })
1082 .await;
1083 }
1084 }
1085
1086 pub fn borrow_mut(&self) -> Option<LifetimeRefMut> {
1089 self.0
1090 .upgrade()?
1091 .try_lock()
1092 .filter(|access| access.state.can_write(self.1))
1093 .map(|mut access| {
1094 let id = access.acquire_writer();
1095 LifetimeRefMut(self.0.clone(), id)
1096 })
1097 }
1098
1099 pub async fn borrow_mut_async(&self) -> LifetimeRefMut {
1101 loop {
1102 if let Some(lifetime_ref_mut) = self.borrow_mut() {
1103 return lifetime_ref_mut;
1104 }
1105 poll_fn(|cx| {
1106 cx.waker().wake_by_ref();
1107 Poll::<LifetimeRefMut>::Pending
1108 })
1109 .await;
1110 }
1111 }
1112
1113 pub fn lazy(&self) -> LifetimeLazy {
1115 LifetimeLazy(self.0.clone())
1116 }
1117
1118 pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
1121 let state = self.0.upgrade()?;
1122 let mut access = state.try_lock()?;
1123 if access.state.is_read_accessible() {
1124 access.acquire_read_access();
1125 drop(access);
1126 Some(ValueReadAccess {
1127 lifetime: state,
1128 data,
1129 })
1130 } else {
1131 None
1132 }
1133 }
1134
1135 pub async fn read_async<'a, T: ?Sized>(&'a self, data: &'a T) -> ValueReadAccess<'a, T> {
1137 loop {
1138 if let Some(access) = self.read(data) {
1139 return access;
1140 }
1141 poll_fn(|cx| {
1142 cx.waker().wake_by_ref();
1143 Poll::<ValueReadAccess<'a, T>>::Pending
1144 })
1145 .await;
1146 }
1147 }
1148
1149 pub unsafe fn read_ptr<T: ?Sized>(&'_ self, data: *const T) -> Option<ValueReadAccess<'_, T>> {
1156 let data = unsafe { data.as_ref() }?;
1157 let state = self.0.upgrade()?;
1158 let mut access = state.try_lock()?;
1159 if access.state.is_read_accessible() {
1160 access.acquire_read_access();
1161 drop(access);
1162 Some(ValueReadAccess {
1163 lifetime: state,
1164 data,
1165 })
1166 } else {
1167 None
1168 }
1169 }
1170
1171 pub async unsafe fn read_ptr_async<'a, T: ?Sized + 'a>(
1178 &'a self,
1179 data: *const T,
1180 ) -> ValueReadAccess<'a, T> {
1181 loop {
1182 if let Some(access) = unsafe { self.read_ptr(data) } {
1183 return access;
1184 }
1185 poll_fn(|cx| {
1186 cx.waker().wake_by_ref();
1187 Poll::<ValueReadAccess<'a, T>>::Pending
1188 })
1189 .await;
1190 }
1191 }
1192
1193 pub fn write<'a, T: ?Sized>(&'a self, data: &'a mut T) -> Option<ValueWriteAccess<'a, T>> {
1196 let state = self.0.upgrade()?;
1197 let mut access = state.try_lock()?;
1198 if access.state.is_write_accessible() {
1199 access.acquire_write_access();
1200 drop(access);
1201 Some(ValueWriteAccess {
1202 lifetime: state,
1203 data,
1204 })
1205 } else {
1206 None
1207 }
1208 }
1209
1210 pub async fn write_async<'a, T: ?Sized>(&'a self, data: &'a mut T) -> ValueWriteAccess<'a, T> {
1212 unsafe { self.write_ptr_async(data as *mut T).await }
1213 }
1214
1215 pub unsafe fn write_ptr<T: ?Sized>(&'_ self, data: *mut T) -> Option<ValueWriteAccess<'_, T>> {
1222 let data = unsafe { data.as_mut() }?;
1223 let state = self.0.upgrade()?;
1224 let mut access = state.try_lock()?;
1225 if access.state.is_write_accessible() {
1226 access.acquire_write_access();
1227 drop(access);
1228 Some(ValueWriteAccess {
1229 lifetime: state,
1230 data,
1231 })
1232 } else {
1233 None
1234 }
1235 }
1236
1237 pub async unsafe fn write_ptr_async<'a, T: ?Sized + 'a>(
1244 &'a self,
1245 data: *mut T,
1246 ) -> ValueWriteAccess<'a, T> {
1247 loop {
1248 if let Some(access) = unsafe { self.write_ptr(data) } {
1249 return access;
1250 }
1251 poll_fn(|cx| {
1252 cx.waker().wake_by_ref();
1253 Poll::<ValueWriteAccess<'a, T>>::Pending
1254 })
1255 .await;
1256 }
1257 }
1258
1259 pub fn try_read_lock(&self) -> Option<ReadLock> {
1261 let state = self.0.upgrade()?;
1262 let mut access = state.lock();
1263 if !access.state.is_read_accessible() {
1264 return None;
1265 }
1266 access.acquire_read_access();
1267 Some(ReadLock {
1268 lifetime: state.clone(),
1269 })
1270 }
1271
1272 pub fn read_lock(&self) -> Option<ReadLock> {
1275 let state = self.0.upgrade()?;
1276 let mut access = state.lock();
1277 while !access.state.is_read_accessible() {
1278 std::hint::spin_loop();
1279 }
1280 access.acquire_read_access();
1281 Some(ReadLock {
1282 lifetime: state.clone(),
1283 })
1284 }
1285
1286 pub async fn read_lock_async(&self) -> ReadLock {
1288 loop {
1289 if let Some(lock) = self.read_lock() {
1290 return lock;
1291 }
1292 poll_fn(|cx| {
1293 cx.waker().wake_by_ref();
1294 Poll::<ReadLock>::Pending
1295 })
1296 .await;
1297 }
1298 }
1299
1300 pub fn try_write_lock(&self) -> Option<WriteLock> {
1302 let state = self.0.upgrade()?;
1303 let mut access = state.lock();
1304 if !access.state.is_write_accessible() {
1305 return None;
1306 }
1307 access.acquire_write_access();
1308 Some(WriteLock {
1309 lifetime: state.clone(),
1310 })
1311 }
1312
1313 pub fn write_lock(&self) -> Option<WriteLock> {
1316 let state = self.0.upgrade()?;
1317 let mut access = state.lock();
1318 while !access.state.is_write_accessible() {
1319 std::hint::spin_loop();
1320 }
1321 access.acquire_write_access();
1322 Some(WriteLock {
1323 lifetime: state.clone(),
1324 })
1325 }
1326
1327 pub async fn write_lock_async(&self) -> WriteLock {
1329 loop {
1330 if let Some(lock) = self.write_lock() {
1331 return lock;
1332 }
1333 poll_fn(|cx| {
1334 cx.waker().wake_by_ref();
1335 Poll::<WriteLock>::Pending
1336 })
1337 .await;
1338 }
1339 }
1340
1341 pub fn consume<T: ?Sized>(self, data: &'_ mut T) -> Result<ValueWriteAccess<'_, T>, Self> {
1346 let state = match self.0.upgrade() {
1347 Some(state) => state,
1348 None => return Err(self),
1349 };
1350 let mut access = match state.try_lock() {
1351 Some(access) => access,
1352 None => return Err(self),
1353 };
1354 if access.state.is_write_accessible() {
1355 access.acquire_write_access();
1356 drop(access);
1357 Ok(ValueWriteAccess {
1358 lifetime: state,
1359 data,
1360 })
1361 } else {
1362 Err(self)
1363 }
1364 }
1365
1366 pub async fn wait_for_read_access(&self) {
1368 loop {
1369 let Some(state) = self.0.upgrade() else {
1370 return;
1371 };
1372 if state.is_read_accessible() {
1373 return;
1374 }
1375 poll_fn(|cx| {
1376 cx.waker().wake_by_ref();
1377 Poll::<()>::Pending
1378 })
1379 .await;
1380 }
1381 }
1382
1383 pub async fn wait_for_write_access(&self) {
1385 loop {
1386 let Some(state) = self.0.upgrade() else {
1387 return;
1388 };
1389 if state.is_write_accessible() {
1390 return;
1391 }
1392 poll_fn(|cx| {
1393 cx.waker().wake_by_ref();
1394 Poll::<()>::Pending
1395 })
1396 .await;
1397 }
1398 }
1399}
1400
1401#[derive(Clone)]
1408pub struct LifetimeLazy(LifetimeWeakState);
1409
1410impl LifetimeLazy {
1411 pub fn state(&self) -> &LifetimeWeakState {
1413 &self.0
1414 }
1415
1416 pub fn tag(&self) -> usize {
1418 self.0.tag
1419 }
1420
1421 pub fn exists(&self) -> bool {
1423 self.0.upgrade().is_some()
1424 }
1425
1426 pub fn is_read_accessible(&self) -> bool {
1428 self.0
1429 .upgrade()
1430 .map(|state| state.is_read_accessible())
1431 .unwrap_or(false)
1432 }
1433
1434 pub fn is_write_accessible(&self) -> bool {
1436 self.0
1437 .upgrade()
1438 .map(|state| state.is_write_accessible())
1439 .unwrap_or(false)
1440 }
1441
1442 pub fn is_in_use(&self) -> bool {
1444 self.0
1445 .upgrade()
1446 .map(|state| state.is_in_use())
1447 .unwrap_or(false)
1448 }
1449
1450 pub fn is_owned_by(&self, other: &Lifetime) -> bool {
1452 self.0.is_owned_by(&other.0)
1453 }
1454
1455 pub fn borrow(&self) -> Option<LifetimeRef> {
1457 self.0
1458 .upgrade()?
1459 .try_lock()
1460 .filter(|access| access.state.can_read())
1461 .map(|mut access| {
1462 access.acquire_reader();
1463 LifetimeRef(self.0.clone())
1464 })
1465 }
1466
1467 pub async fn borrow_async(&self) -> LifetimeRef {
1469 loop {
1470 if let Some(lifetime_ref) = self.borrow() {
1471 return lifetime_ref;
1472 }
1473 poll_fn(|cx| {
1474 cx.waker().wake_by_ref();
1475 Poll::<LifetimeRef>::Pending
1476 })
1477 .await;
1478 }
1479 }
1480
1481 pub fn borrow_mut(&self) -> Option<LifetimeRefMut> {
1484 self.0
1485 .upgrade()?
1486 .try_lock()
1487 .filter(|access| access.state.can_write(0))
1488 .map(|mut access| {
1489 let id = access.acquire_writer();
1490 LifetimeRefMut(self.0.clone(), id)
1491 })
1492 }
1493
1494 pub async fn borrow_mut_async(&self) -> LifetimeRefMut {
1496 loop {
1497 if let Some(lifetime_ref_mut) = self.borrow_mut() {
1498 return lifetime_ref_mut;
1499 }
1500 poll_fn(|cx| {
1501 cx.waker().wake_by_ref();
1502 Poll::<LifetimeRefMut>::Pending
1503 })
1504 .await;
1505 }
1506 }
1507
1508 pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
1511 let state = self.0.upgrade()?;
1512 let mut access = state.try_lock()?;
1513 if access.state.is_read_accessible() {
1514 access.acquire_read_access();
1515 drop(access);
1516 Some(ValueReadAccess {
1517 lifetime: state,
1518 data,
1519 })
1520 } else {
1521 None
1522 }
1523 }
1524
1525 pub async fn read_async<'a, T: ?Sized>(&'a self, data: &'a T) -> ValueReadAccess<'a, T> {
1527 loop {
1528 if let Some(access) = self.read(data) {
1529 return access;
1530 }
1531 poll_fn(|cx| {
1532 cx.waker().wake_by_ref();
1533 Poll::<ValueReadAccess<'a, T>>::Pending
1534 })
1535 .await;
1536 }
1537 }
1538
1539 pub unsafe fn read_ptr<T: ?Sized>(&'_ self, data: *const T) -> Option<ValueReadAccess<'_, T>> {
1546 let data = unsafe { data.as_ref() }?;
1547 let state = self.0.upgrade()?;
1548 let mut access = state.try_lock()?;
1549 if access.state.is_read_accessible() {
1550 access.acquire_read_access();
1551 drop(access);
1552 Some(ValueReadAccess {
1553 lifetime: state,
1554 data,
1555 })
1556 } else {
1557 None
1558 }
1559 }
1560
1561 pub async unsafe fn read_ptr_async<'a, T: ?Sized + 'a>(
1568 &'a self,
1569 data: *const T,
1570 ) -> ValueReadAccess<'a, T> {
1571 loop {
1572 if let Some(access) = unsafe { self.read_ptr(data) } {
1573 return access;
1574 }
1575 poll_fn(|cx| {
1576 cx.waker().wake_by_ref();
1577 Poll::<ValueReadAccess<'a, T>>::Pending
1578 })
1579 .await;
1580 }
1581 }
1582
1583 pub fn write<'a, T: ?Sized>(&'a self, data: &'a mut T) -> Option<ValueWriteAccess<'a, T>> {
1586 let state = self.0.upgrade()?;
1587 let mut access = state.try_lock()?;
1588 if access.state.is_write_accessible() {
1589 access.acquire_write_access();
1590 drop(access);
1591 Some(ValueWriteAccess {
1592 lifetime: state,
1593 data,
1594 })
1595 } else {
1596 None
1597 }
1598 }
1599
1600 pub async fn write_async<'a, T: ?Sized>(&'a self, data: &'a mut T) -> ValueWriteAccess<'a, T> {
1602 unsafe { self.write_ptr_async(data as *mut T).await }
1603 }
1604
1605 pub unsafe fn write_ptr<T: ?Sized>(&'_ self, data: *mut T) -> Option<ValueWriteAccess<'_, T>> {
1612 let data = unsafe { data.as_mut() }?;
1613 let state = self.0.upgrade()?;
1614 let mut access = state.try_lock()?;
1615 if access.state.is_write_accessible() {
1616 access.acquire_write_access();
1617 drop(access);
1618 Some(ValueWriteAccess {
1619 lifetime: state,
1620 data,
1621 })
1622 } else {
1623 None
1624 }
1625 }
1626
1627 pub async unsafe fn write_ptr_async<'a, T: ?Sized + 'a>(
1634 &'a self,
1635 data: *mut T,
1636 ) -> ValueWriteAccess<'a, T> {
1637 loop {
1638 if let Some(access) = unsafe { self.write_ptr(data) } {
1639 return access;
1640 }
1641 poll_fn(|cx| {
1642 cx.waker().wake_by_ref();
1643 Poll::<ValueWriteAccess<'a, T>>::Pending
1644 })
1645 .await;
1646 }
1647 }
1648
1649 pub fn consume<T: ?Sized>(self, data: &'_ mut T) -> Result<ValueWriteAccess<'_, T>, Self> {
1653 let state = match self.0.upgrade() {
1654 Some(state) => state,
1655 None => return Err(self),
1656 };
1657 let mut access = match state.try_lock() {
1658 Some(access) => access,
1659 None => return Err(self),
1660 };
1661 if access.state.is_write_accessible() {
1662 access.acquire_write_access();
1663 drop(access);
1664 Ok(ValueWriteAccess {
1665 lifetime: state,
1666 data,
1667 })
1668 } else {
1669 Err(self)
1670 }
1671 }
1672
1673 pub async fn wait_for_read_access(&self) {
1675 loop {
1676 let Some(state) = self.0.upgrade() else {
1677 return;
1678 };
1679 if state.is_read_accessible() {
1680 return;
1681 }
1682 poll_fn(|cx| {
1683 cx.waker().wake_by_ref();
1684 Poll::<()>::Pending
1685 })
1686 .await;
1687 }
1688 }
1689
1690 pub async fn wait_for_write_access(&self) {
1692 loop {
1693 let Some(state) = self.0.upgrade() else {
1694 return;
1695 };
1696 if state.is_write_accessible() {
1697 return;
1698 }
1699 poll_fn(|cx| {
1700 cx.waker().wake_by_ref();
1701 Poll::<()>::Pending
1702 })
1703 .await;
1704 }
1705 }
1706}
1707
1708pub struct ValueReadAccess<'a, T: 'a + ?Sized> {
1712 lifetime: LifetimeState,
1713 data: &'a T,
1714}
1715
1716impl<T: ?Sized> Drop for ValueReadAccess<'_, T> {
1717 fn drop(&mut self) {
1718 self.lifetime.lock().release_read_access();
1719 }
1720}
1721
1722impl<'a, T: ?Sized> ValueReadAccess<'a, T> {
1723 pub unsafe fn new_raw(data: &'a T, lifetime: LifetimeState) -> Self {
1731 Self { lifetime, data }
1732 }
1733}
1734
1735impl<T: ?Sized> Deref for ValueReadAccess<'_, T> {
1736 type Target = T;
1737
1738 fn deref(&self) -> &Self::Target {
1739 self.data
1740 }
1741}
1742
1743impl<'a, T: ?Sized> ValueReadAccess<'a, T> {
1744 pub fn remap<U>(
1748 self,
1749 f: impl FnOnce(&T) -> Option<&U>,
1750 ) -> Result<ValueReadAccess<'a, U>, Self> {
1751 if let Some(data) = f(self.data) {
1752 Ok(ValueReadAccess {
1753 lifetime: self.lifetime.clone(),
1754 data,
1755 })
1756 } else {
1757 Err(self)
1758 }
1759 }
1760}
1761
1762pub struct ValueWriteAccess<'a, T: 'a + ?Sized> {
1768 lifetime: LifetimeState,
1769 data: &'a mut T,
1770}
1771
1772impl<T: ?Sized> Drop for ValueWriteAccess<'_, T> {
1773 fn drop(&mut self) {
1774 self.lifetime.lock().release_write_access();
1775 }
1776}
1777
1778impl<'a, T: ?Sized> ValueWriteAccess<'a, T> {
1779 pub unsafe fn new_raw(data: &'a mut T, lifetime: LifetimeState) -> Self {
1787 Self { lifetime, data }
1788 }
1789}
1790
1791impl<T: ?Sized> Deref for ValueWriteAccess<'_, T> {
1792 type Target = T;
1793
1794 fn deref(&self) -> &Self::Target {
1795 self.data
1796 }
1797}
1798
1799impl<T: ?Sized> DerefMut for ValueWriteAccess<'_, T> {
1800 fn deref_mut(&mut self) -> &mut Self::Target {
1801 self.data
1802 }
1803}
1804
1805impl<'a, T: ?Sized> ValueWriteAccess<'a, T> {
1806 pub fn remap<U>(
1810 self,
1811 f: impl FnOnce(&mut T) -> Option<&mut U>,
1812 ) -> Result<ValueWriteAccess<'a, U>, Self> {
1813 if let Some(data) = f(unsafe { std::mem::transmute::<&mut T, &'a mut T>(&mut *self.data) })
1814 {
1815 Ok(ValueWriteAccess {
1816 lifetime: self.lifetime.clone(),
1817 data,
1818 })
1819 } else {
1820 Err(self)
1821 }
1822 }
1823}
1824
1825pub struct ReadLock {
1830 lifetime: LifetimeState,
1831}
1832
1833impl Drop for ReadLock {
1834 fn drop(&mut self) {
1835 self.lifetime.lock().release_read_access();
1836 }
1837}
1838
1839impl ReadLock {
1840 pub unsafe fn new_raw(lifetime: LifetimeState) -> Self {
1847 Self { lifetime }
1848 }
1849
1850 pub fn using<R>(self, f: impl FnOnce() -> R) -> R {
1852 let result = f();
1853 drop(self);
1854 result
1855 }
1856}
1857
1858pub struct WriteLock {
1862 lifetime: LifetimeState,
1863}
1864
1865impl Drop for WriteLock {
1866 fn drop(&mut self) {
1867 self.lifetime.lock().release_write_access();
1868 }
1869}
1870
1871impl WriteLock {
1872 pub unsafe fn new_raw(lifetime: LifetimeState) -> Self {
1879 Self { lifetime }
1880 }
1881
1882 pub fn using<R>(self, f: impl FnOnce() -> R) -> R {
1884 let result = f();
1885 drop(self);
1886 result
1887 }
1888}
1889
1890#[cfg(test)]
1891mod tests {
1892 use super::*;
1893 use std::thread::*;
1894
1895 fn is_async<T: Send + Sync + ?Sized>() {
1896 println!("{} is async!", std::any::type_name::<T>());
1897 }
1898
1899 #[test]
1900 fn test_lifetimes() {
1901 is_async::<Lifetime>();
1902 is_async::<LifetimeRef>();
1903 is_async::<LifetimeRefMut>();
1904 is_async::<LifetimeLazy>();
1905
1906 let mut value = 0usize;
1907 let lifetime_ref = {
1908 let lifetime = Lifetime::default();
1909 assert!(lifetime.state().can_read());
1910 assert!(lifetime.state().can_write(0));
1911 assert!(lifetime.state().is_read_accessible());
1912 assert!(lifetime.state().is_write_accessible());
1913 let lifetime_lazy = lifetime.lazy();
1914 assert!(lifetime_lazy.read(&42).is_some());
1915 assert!(lifetime_lazy.write(&mut 42).is_some());
1916 {
1917 let access = lifetime.read(&value).unwrap();
1918 assert_eq!(*access, value);
1919 }
1920 {
1921 let mut access = lifetime.write(&mut value).unwrap();
1922 *access = 42;
1923 assert_eq!(*access, 42);
1924 }
1925 {
1926 let lifetime_ref = lifetime.borrow().unwrap();
1927 assert!(lifetime.state().can_read());
1928 assert!(!lifetime.state().can_write(0));
1929 assert!(lifetime_ref.exists());
1930 assert!(lifetime_ref.is_owned_by(&lifetime));
1931 assert!(lifetime.borrow().is_some());
1932 assert!(lifetime.borrow_mut().is_none());
1933 assert!(lifetime_lazy.read(&42).is_some());
1934 assert!(lifetime_lazy.write(&mut 42).is_some());
1935 {
1936 let access = lifetime_ref.read(&value).unwrap();
1937 assert_eq!(*access, 42);
1938 assert!(lifetime_lazy.read(&42).is_some());
1939 assert!(lifetime_lazy.write(&mut 42).is_none());
1940 }
1941 let lifetime_ref2 = lifetime_ref.borrow().unwrap();
1942 {
1943 let access = lifetime_ref2.read(&value).unwrap();
1944 assert_eq!(*access, 42);
1945 assert!(lifetime_lazy.read(&42).is_some());
1946 assert!(lifetime_lazy.write(&mut 42).is_none());
1947 }
1948 }
1949 {
1950 let lifetime_ref_mut = lifetime.borrow_mut().unwrap();
1951 assert_eq!(lifetime.state().writer_depth(), 1);
1952 assert!(!lifetime.state().can_read());
1953 assert!(!lifetime.state().can_write(0));
1954 assert!(lifetime_ref_mut.exists());
1955 assert!(lifetime_ref_mut.is_owned_by(&lifetime));
1956 assert!(lifetime.borrow().is_none());
1957 assert!(lifetime.borrow_mut().is_none());
1958 assert!(lifetime_lazy.read(&42).is_some());
1959 assert!(lifetime_lazy.write(&mut 42).is_some());
1960 {
1961 let mut access = lifetime_ref_mut.write(&mut value).unwrap();
1962 *access = 7;
1963 assert_eq!(*access, 7);
1964 assert!(lifetime_lazy.read(&42).is_none());
1965 assert!(lifetime_lazy.write(&mut 42).is_none());
1966 }
1967 let lifetime_ref_mut2 = lifetime_ref_mut.borrow_mut().unwrap();
1968 assert!(lifetime_lazy.read(&42).is_some());
1969 assert!(lifetime_lazy.write(&mut 42).is_some());
1970 {
1971 assert_eq!(lifetime.state().writer_depth(), 2);
1972 assert!(lifetime.borrow().is_none());
1973 assert!(lifetime_ref_mut.borrow().is_none());
1974 assert!(lifetime.borrow_mut().is_none());
1975 assert!(lifetime_ref_mut.borrow_mut().is_none());
1976 let mut access = lifetime_ref_mut2.write(&mut value).unwrap();
1977 *access = 42;
1978 assert_eq!(*access, 42);
1979 assert!(lifetime.read(&42).is_none());
1980 assert!(lifetime_ref_mut.read(&42).is_none());
1981 assert!(lifetime.write(&mut 42).is_none());
1982 assert!(lifetime_ref_mut.write(&mut 42).is_none());
1983 assert!(lifetime_lazy.read(&42).is_none());
1984 assert!(lifetime_lazy.write(&mut 42).is_none());
1985 assert!(lifetime_lazy.read(&42).is_none());
1986 assert!(lifetime_lazy.write(&mut 42).is_none());
1987 }
1988 }
1989 assert_eq!(lifetime.state().writer_depth(), 0);
1990 lifetime.borrow().unwrap()
1991 };
1992 assert!(!lifetime_ref.exists());
1993 assert_eq!(value, 42);
1994 }
1995
1996 #[test]
1997 fn test_lifetimes_multithread() {
1998 let lifetime = Lifetime::default();
1999 let lifetime_ref = lifetime.borrow().unwrap();
2000 assert!(lifetime_ref.exists());
2001 assert!(lifetime_ref.is_owned_by(&lifetime));
2002 drop(lifetime);
2003 assert!(!lifetime_ref.exists());
2004 let lifetime = Lifetime::default();
2005 let lifetime = spawn(move || {
2006 let value_ref = lifetime.borrow().unwrap();
2007 assert!(value_ref.exists());
2008 assert!(value_ref.is_owned_by(&lifetime));
2009 lifetime
2010 })
2011 .join()
2012 .unwrap();
2013 assert!(!lifetime_ref.exists());
2014 assert!(!lifetime_ref.is_owned_by(&lifetime));
2015 }
2016
2017 #[test]
2018 fn test_lifetimes_move_invalidation() {
2019 let lifetime = Lifetime::default();
2020 let lifetime_ref = lifetime.borrow().unwrap();
2021 assert_eq!(lifetime_ref.tag(), lifetime.tag());
2022 assert!(lifetime_ref.exists());
2023 let lifetime_ref2 = lifetime_ref;
2024 assert_eq!(lifetime_ref2.tag(), lifetime.tag());
2025 assert!(lifetime_ref2.exists());
2026 let lifetime = Box::new(lifetime);
2027 assert_ne!(lifetime_ref2.tag(), lifetime.tag());
2028 assert!(!lifetime_ref2.exists());
2029 let lifetime = *lifetime;
2030 assert_ne!(lifetime_ref2.tag(), lifetime.tag());
2031 assert!(!lifetime_ref2.exists());
2032 }
2033
2034 #[pollster::test]
2035 async fn test_lifetime_async() {
2036 let mut value = 42usize;
2037 let lifetime = Lifetime::default();
2038 assert_eq!(*lifetime.read_async(&value).await, 42);
2039 {
2040 let lifetime_ref = lifetime.borrow_async().await;
2041 {
2042 let access = lifetime_ref.read_async(&value).await;
2043 assert_eq!(*access, 42);
2044 }
2045 }
2046 {
2047 let lifetime_ref_mut = lifetime.borrow_mut_async().await;
2048 {
2049 let mut access = lifetime_ref_mut.write_async(&mut value).await;
2050 *access = 7;
2051 assert_eq!(*access, 7);
2052 }
2053 assert_eq!(*lifetime.read_async(&value).await, 7);
2054 }
2055 {
2056 let mut access = lifetime.write_async(&mut value).await;
2057 *access = 84;
2058 }
2059 {
2060 let access = lifetime.read_async(&value).await;
2061 assert_eq!(*access, 84);
2062 }
2063 }
2064
2065 #[test]
2066 fn test_lifetime_locks() {
2067 let lifetime = Lifetime::default();
2068 assert!(lifetime.state().is_read_accessible());
2069 assert!(lifetime.state().is_write_accessible());
2070
2071 let read_lock = lifetime.read_lock();
2072 assert!(lifetime.state().is_read_accessible());
2073 assert!(!lifetime.state().is_write_accessible());
2074
2075 drop(read_lock);
2076 assert!(lifetime.state().is_read_accessible());
2077 assert!(lifetime.state().is_write_accessible());
2078
2079 let read_lock = lifetime.read_lock();
2080 assert!(lifetime.state().is_read_accessible());
2081 assert!(!lifetime.state().is_write_accessible());
2082
2083 let read_lock2 = lifetime.read_lock();
2084 assert!(lifetime.state().is_read_accessible());
2085 assert!(!lifetime.state().is_write_accessible());
2086
2087 drop(read_lock);
2088 assert!(lifetime.state().is_read_accessible());
2089 assert!(!lifetime.state().is_write_accessible());
2090
2091 drop(read_lock2);
2092 assert!(lifetime.state().is_read_accessible());
2093 assert!(lifetime.state().is_write_accessible());
2094
2095 let write_lock = lifetime.write_lock();
2096 assert!(!lifetime.state().is_read_accessible());
2097 assert!(!lifetime.state().is_write_accessible());
2098
2099 assert!(lifetime.try_read_lock().is_none());
2100 assert!(lifetime.try_write_lock().is_none());
2101
2102 drop(write_lock);
2103 assert!(lifetime.state().is_read_accessible());
2104 assert!(lifetime.state().is_write_accessible());
2105
2106 let data = ();
2107 let read_access = lifetime.read(&data).unwrap();
2108 assert!(lifetime.state().is_read_accessible());
2109 assert!(!lifetime.state().is_write_accessible());
2110 assert!(!lifetime.state().is_locked());
2112
2113 drop(read_access);
2114 assert!(lifetime.try_read_lock().is_some());
2115 assert!(lifetime.try_write_lock().is_some());
2116 }
2117
2118 #[test]
2119 fn test_read_access_guards_coexist() {
2120 let mut value = 42usize;
2121 let lifetime = Lifetime::default();
2122
2123 let first = lifetime.read(&value).unwrap();
2124 let second = lifetime.read(&value).unwrap();
2125 let third = lifetime.read(&value).unwrap();
2126 assert_eq!(*first, 42);
2127 assert_eq!(*second, 42);
2128 assert_eq!(*third, 42);
2129
2130 assert!(!lifetime.state().is_locked());
2132 assert!(lifetime.state().is_read_accessible());
2133 assert!(!lifetime.state().is_write_accessible());
2135 assert!(lifetime.try_write_lock().is_none());
2136 let lock = lifetime.try_read_lock().unwrap();
2137
2138 drop(lock);
2139 drop(third);
2140 drop(second);
2141 assert!(!lifetime.state().is_write_accessible());
2142 drop(first);
2143 assert!(lifetime.state().is_write_accessible());
2144
2145 *lifetime.write(&mut value).unwrap() = 10;
2146 assert_eq!(value, 10);
2147 }
2148
2149 #[test]
2150 fn test_write_access_guard_excludes_readers() {
2151 let mut value = 42usize;
2152 let lifetime = Lifetime::default();
2153
2154 let guard = lifetime.write(&mut value).unwrap();
2155 assert!(!lifetime.state().is_locked());
2156 assert!(!lifetime.state().is_read_accessible());
2157 assert!(lifetime.try_read_lock().is_none());
2158 assert!(lifetime.lazy().read(&0).is_none());
2159
2160 drop(guard);
2161 assert!(lifetime.state().is_read_accessible());
2162 assert!(lifetime.try_read_lock().is_some());
2163 }
2164
2165 #[test]
2166 fn test_null_pointer_leaves_no_access_behind() {
2167 let lifetime = Lifetime::default();
2168
2169 assert!(unsafe { lifetime.read_ptr(std::ptr::null::<usize>()) }.is_none());
2170 assert!(unsafe { lifetime.write_ptr(std::ptr::null_mut::<usize>()) }.is_none());
2171
2172 assert!(lifetime.state().is_read_accessible());
2174 assert!(lifetime.state().is_write_accessible());
2175 assert!(lifetime.try_write_lock().is_some());
2176 }
2177
2178 #[test]
2179 fn test_read_access_guards_across_threads() {
2180 let lifetime = Arc::new(Lifetime::default());
2181 let value = Arc::new(7usize);
2182
2183 let threads = (0..8)
2184 .map(|_| {
2185 let lifetime = lifetime.clone();
2186 let value = value.clone();
2187 spawn(move || {
2188 let mut taken = 0usize;
2189 for _ in 0..1000 {
2190 if let Some(access) = lifetime.read(value.as_ref()) {
2191 assert_eq!(*access, 7);
2192 taken += 1;
2193 }
2194 }
2195 taken
2196 })
2197 })
2198 .collect::<Vec<_>>();
2199 let total = threads
2200 .into_iter()
2201 .map(|thread| thread.join().unwrap())
2202 .sum::<usize>();
2203 assert!(total > 0);
2204
2205 assert!(lifetime.state().is_write_accessible());
2207 }
2208}