1use std::{
2 future::poll_fn,
3 ops::{Deref, DerefMut},
4 sync::{
5 Arc, Weak,
6 atomic::{AtomicBool, AtomicUsize, Ordering},
7 },
8 task::Poll,
9};
10
11#[derive(Default)]
12struct LifetimeStateInner {
13 locked: AtomicBool,
14 readers: AtomicUsize,
15 writer: AtomicUsize,
16 read_access: AtomicUsize,
17 write_access: AtomicBool,
18 tag: AtomicUsize,
19}
20
21#[derive(Default, Clone)]
22pub struct LifetimeState {
23 inner: Arc<LifetimeStateInner>,
24}
25
26impl LifetimeState {
27 pub fn can_read(&self) -> bool {
28 self.inner.writer.load(Ordering::Acquire) == 0
29 }
30
31 pub fn can_write(&self, id: usize) -> bool {
32 self.inner.writer.load(Ordering::Acquire) == id
33 && self.inner.readers.load(Ordering::Acquire) == 0
34 }
35
36 pub fn readers_count(&self) -> usize {
37 self.inner.readers.load(Ordering::Acquire)
38 }
39
40 pub fn writer_depth(&self) -> usize {
41 self.inner.writer.load(Ordering::Acquire)
42 }
43
44 pub fn is_read_accessible(&self) -> bool {
45 !self.inner.write_access.load(Ordering::Acquire)
46 }
47
48 pub fn is_write_accessible(&self) -> bool {
49 !self.inner.write_access.load(Ordering::Acquire)
50 && self.inner.read_access.load(Ordering::Acquire) == 0
51 }
52
53 pub fn is_in_use(&self) -> bool {
54 self.inner.read_access.load(Ordering::Acquire) > 0
55 || self.inner.write_access.load(Ordering::Acquire)
56 }
57
58 pub fn is_locked(&self) -> bool {
59 self.inner.locked.load(Ordering::Acquire)
60 }
61
62 pub fn try_lock(&'_ self) -> Option<LifetimeStateAccess<'_>> {
63 if !self.inner.locked.load(Ordering::Acquire) {
64 self.inner.locked.store(true, Ordering::Release);
65 Some(LifetimeStateAccess {
66 state: self,
67 unlock: true,
68 })
69 } else {
70 None
71 }
72 }
73
74 pub fn lock(&'_ self) -> LifetimeStateAccess<'_> {
75 while self.inner.locked.load(Ordering::Acquire) {
76 std::hint::spin_loop();
77 }
78 self.inner.locked.store(true, Ordering::Release);
79 LifetimeStateAccess {
80 state: self,
81 unlock: true,
82 }
83 }
84
85 pub unsafe fn lock_unchecked(&'_ self) -> LifetimeStateAccess<'_> {
87 LifetimeStateAccess {
88 state: self,
89 unlock: true,
90 }
91 }
92
93 pub unsafe fn update_tag(&self, tag: &Lifetime) {
95 let tag = tag as *const Lifetime as usize;
96 self.inner.tag.store(tag, Ordering::Release);
97 }
98
99 pub unsafe fn invalidate_tag(&self) {
101 self.inner.tag.store(0, Ordering::Release);
102 }
103
104 pub fn tag(&self) -> usize {
105 self.inner.tag.load(Ordering::Acquire)
106 }
107
108 pub fn downgrade(&self) -> LifetimeWeakState {
109 LifetimeWeakState {
110 inner: Arc::downgrade(&self.inner),
111 tag: self.inner.tag.load(Ordering::Acquire),
112 }
113 }
114}
115
116#[derive(Clone)]
117pub struct LifetimeWeakState {
118 inner: Weak<LifetimeStateInner>,
119 tag: usize,
120}
121
122impl LifetimeWeakState {
123 pub unsafe fn upgrade_unchecked(&self) -> Option<LifetimeState> {
125 Some(LifetimeState {
126 inner: self.inner.upgrade()?,
127 })
128 }
129
130 pub fn upgrade(&self) -> Option<LifetimeState> {
131 let inner = self.inner.upgrade()?;
132 (inner.tag.load(Ordering::Acquire) == self.tag).then_some(LifetimeState { inner })
133 }
134
135 pub fn is_owned_by(&self, state: &LifetimeState) -> bool {
136 Arc::downgrade(&state.inner).ptr_eq(&self.inner)
137 }
138}
139
140pub struct LifetimeStateAccess<'a> {
141 state: &'a LifetimeState,
142 unlock: bool,
143}
144
145impl Drop for LifetimeStateAccess<'_> {
146 fn drop(&mut self) {
147 if self.unlock {
148 self.state.inner.locked.store(false, Ordering::Release);
149 }
150 }
151}
152
153impl LifetimeStateAccess<'_> {
154 pub fn state(&self) -> &LifetimeState {
155 self.state
156 }
157
158 pub fn unlock(&mut self, value: bool) {
159 self.unlock = value;
160 }
161
162 pub fn acquire_reader(&mut self) {
163 let v = self.state.inner.readers.load(Ordering::Acquire) + 1;
164 self.state.inner.readers.store(v, Ordering::Release);
165 }
166
167 pub fn release_reader(&mut self) {
168 let v = self
169 .state
170 .inner
171 .readers
172 .load(Ordering::Acquire)
173 .saturating_sub(1);
174 self.state.inner.readers.store(v, Ordering::Release);
175 }
176
177 #[must_use]
178 pub fn acquire_writer(&mut self) -> usize {
179 let v = self.state.inner.writer.load(Ordering::Acquire) + 1;
180 self.state.inner.writer.store(v, Ordering::Release);
181 v
182 }
183
184 pub fn release_writer(&mut self, id: usize) {
185 let v = self.state.inner.writer.load(Ordering::Acquire);
186 if id <= v {
187 self.state
188 .inner
189 .writer
190 .store(id.saturating_sub(1), Ordering::Release);
191 }
192 }
193
194 pub fn acquire_read_access(&mut self) {
195 let v = self.state.inner.read_access.load(Ordering::Acquire) + 1;
196 self.state.inner.read_access.store(v, Ordering::Release);
197 }
198
199 pub fn release_read_access(&mut self) {
200 let v = self
201 .state
202 .inner
203 .read_access
204 .load(Ordering::Acquire)
205 .saturating_sub(1);
206 self.state.inner.read_access.store(v, Ordering::Release);
207 }
208
209 pub fn acquire_write_access(&mut self) {
210 self.state.inner.write_access.store(true, Ordering::Release);
211 }
212
213 pub fn release_write_access(&mut self) {
214 self.state
215 .inner
216 .write_access
217 .store(false, Ordering::Release);
218 }
219}
220
221#[derive(Default)]
222pub struct Lifetime(LifetimeState);
223
224impl Lifetime {
225 pub fn invalidate(&mut self) {
226 unsafe { self.0.invalidate_tag() };
227 self.0 = Default::default();
228 }
229
230 pub fn state(&self) -> &LifetimeState {
231 unsafe { self.0.update_tag(self) };
232 &self.0
233 }
234
235 pub fn update_tag(&self) {
236 unsafe { self.0.update_tag(self) };
237 }
238
239 pub fn tag(&self) -> usize {
240 unsafe { self.0.update_tag(self) };
241 self.0.tag()
242 }
243
244 pub fn borrow(&self) -> Option<LifetimeRef> {
245 unsafe { self.0.update_tag(self) };
246 self.0
247 .try_lock()
248 .filter(|access| access.state.can_read())
249 .map(|mut access| {
250 access.acquire_reader();
251 LifetimeRef(self.0.downgrade())
252 })
253 }
254
255 pub async fn borrow_async(&self) -> LifetimeRef {
256 loop {
257 if let Some(lifetime_ref) = self.borrow() {
258 return lifetime_ref;
259 }
260 poll_fn(|cx| {
261 cx.waker().wake_by_ref();
262 Poll::<LifetimeRef>::Pending
263 })
264 .await;
265 }
266 }
267
268 pub fn borrow_mut(&self) -> Option<LifetimeRefMut> {
269 unsafe { self.0.update_tag(self) };
270 self.0
271 .try_lock()
272 .filter(|access| access.state.can_write(0))
273 .map(|mut access| {
274 let id = access.acquire_writer();
275 LifetimeRefMut(self.0.downgrade(), id)
276 })
277 }
278
279 pub async fn borrow_mut_async(&self) -> LifetimeRefMut {
280 loop {
281 if let Some(lifetime_ref_mut) = self.borrow_mut() {
282 return lifetime_ref_mut;
283 }
284 poll_fn(|cx| {
285 cx.waker().wake_by_ref();
286 Poll::<LifetimeRefMut>::Pending
287 })
288 .await;
289 }
290 }
291
292 pub fn lazy(&self) -> LifetimeLazy {
293 unsafe { self.0.update_tag(self) };
294 LifetimeLazy(self.0.downgrade())
295 }
296
297 pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
298 unsafe { self.0.update_tag(self) };
299 self.0
300 .try_lock()
301 .filter(|access| access.state.is_read_accessible())
302 .map(|mut access| {
303 access.unlock = false;
304 access.acquire_read_access();
305 ValueReadAccess {
306 lifetime: self.0.clone(),
307 data,
308 }
309 })
310 }
311
312 pub async fn read_async<'a, T: ?Sized>(&'a self, data: &'a T) -> ValueReadAccess<'a, T> {
313 unsafe { self.read_ptr_async(data as *const T).await }
314 }
315
316 pub unsafe fn read_ptr<T: ?Sized>(&'_ self, data: *const T) -> Option<ValueReadAccess<'_, T>> {
318 unsafe { self.0.update_tag(self) };
319 self.0
320 .try_lock()
321 .filter(|access| access.state.is_read_accessible())
322 .and_then(|mut access| {
323 access.unlock = false;
324 access.acquire_read_access();
325 Some(ValueReadAccess {
326 lifetime: self.0.clone(),
327 data: unsafe { data.as_ref() }?,
328 })
329 })
330 }
331
332 pub async unsafe fn read_ptr_async<'a, T: ?Sized + 'a>(
334 &'a self,
335 data: *const T,
336 ) -> ValueReadAccess<'a, T> {
337 loop {
338 if let Some(access) = unsafe { self.read_ptr(data) } {
339 return access;
340 }
341 poll_fn(|cx| {
342 cx.waker().wake_by_ref();
343 Poll::<ValueReadAccess<'a, T>>::Pending
344 })
345 .await;
346 }
347 }
348
349 pub fn write<'a, T: ?Sized>(&'a self, data: &'a mut T) -> Option<ValueWriteAccess<'a, T>> {
350 unsafe { self.0.update_tag(self) };
351 self.0
352 .try_lock()
353 .filter(|access| access.state.is_write_accessible())
354 .map(|mut access| {
355 access.unlock = false;
356 access.acquire_write_access();
357 ValueWriteAccess {
358 lifetime: self.0.clone(),
359 data,
360 }
361 })
362 }
363
364 pub async fn write_async<'a, T: ?Sized>(&'a self, data: &'a mut T) -> ValueWriteAccess<'a, T> {
365 unsafe { self.write_ptr_async(data as *mut T).await }
366 }
367
368 pub unsafe fn write_ptr<T: ?Sized>(&'_ self, data: *mut T) -> Option<ValueWriteAccess<'_, T>> {
370 unsafe { self.0.update_tag(self) };
371 self.0
372 .try_lock()
373 .filter(|access| access.state.is_write_accessible())
374 .and_then(|mut access| {
375 access.unlock = false;
376 access.acquire_write_access();
377 Some(ValueWriteAccess {
378 lifetime: self.0.clone(),
379 data: unsafe { data.as_mut() }?,
380 })
381 })
382 }
383
384 pub async unsafe fn write_ptr_async<'a, T: ?Sized + 'a>(
386 &'a self,
387 data: *mut T,
388 ) -> ValueWriteAccess<'a, T> {
389 loop {
390 if let Some(access) = unsafe { self.write_ptr(data) } {
391 return access;
392 }
393 poll_fn(|cx| {
394 cx.waker().wake_by_ref();
395 Poll::<ValueWriteAccess<'a, T>>::Pending
396 })
397 .await;
398 }
399 }
400
401 pub fn try_read_lock(&self) -> Option<ReadLock> {
402 unsafe { self.0.update_tag(self) };
403 let mut access = self.0.lock();
404 if !access.state.is_read_accessible() {
405 return None;
406 }
407 access.acquire_read_access();
408 Some(ReadLock {
409 lifetime: self.0.clone(),
410 })
411 }
412
413 pub fn read_lock(&self) -> ReadLock {
414 unsafe { self.0.update_tag(self) };
415 let mut access = self.0.lock();
416 while !access.state.is_read_accessible() {
417 std::hint::spin_loop();
418 }
419 access.acquire_read_access();
420 ReadLock {
421 lifetime: self.0.clone(),
422 }
423 }
424
425 pub async fn read_lock_async(&self) -> ReadLock {
426 loop {
427 unsafe { self.0.update_tag(self) };
428 let mut access = self.0.lock();
429 if access.state.is_read_accessible() {
430 access.acquire_read_access();
431 return ReadLock {
432 lifetime: self.0.clone(),
433 };
434 }
435 poll_fn(|cx| {
436 cx.waker().wake_by_ref();
437 Poll::<ReadLock>::Pending
438 })
439 .await;
440 }
441 }
442
443 pub fn try_write_lock(&self) -> Option<WriteLock> {
444 unsafe { self.0.update_tag(self) };
445 let mut access = self.0.lock();
446 if !access.state.is_write_accessible() {
447 return None;
448 }
449 access.acquire_write_access();
450 Some(WriteLock {
451 lifetime: self.0.clone(),
452 })
453 }
454
455 pub fn write_lock(&self) -> WriteLock {
456 unsafe { self.0.update_tag(self) };
457 let mut access = self.0.lock();
458 while !access.state.is_write_accessible() {
459 std::hint::spin_loop();
460 }
461 access.acquire_write_access();
462 WriteLock {
463 lifetime: self.0.clone(),
464 }
465 }
466
467 pub async fn write_lock_async(&self) -> WriteLock {
468 loop {
469 unsafe { self.0.update_tag(self) };
470 let mut access = self.0.lock();
471 if access.state.is_write_accessible() {
472 access.acquire_write_access();
473 return WriteLock {
474 lifetime: self.0.clone(),
475 };
476 }
477 poll_fn(|cx| {
478 cx.waker().wake_by_ref();
479 Poll::<WriteLock>::Pending
480 })
481 .await;
482 }
483 }
484
485 pub async fn wait_for_read_access(&self) {
486 loop {
487 if self.state().is_read_accessible() {
488 return;
489 }
490 poll_fn(|cx| {
491 cx.waker().wake_by_ref();
492 Poll::<()>::Pending
493 })
494 .await;
495 }
496 }
497
498 pub async fn wait_for_write_access(&self) {
499 loop {
500 if self.state().is_write_accessible() {
501 return;
502 }
503 poll_fn(|cx| {
504 cx.waker().wake_by_ref();
505 Poll::<()>::Pending
506 })
507 .await;
508 }
509 }
510}
511
512pub struct LifetimeRef(LifetimeWeakState);
513
514impl Drop for LifetimeRef {
515 fn drop(&mut self) {
516 if let Some(owner) = unsafe { self.0.upgrade_unchecked() }
517 && let Some(mut access) = owner.try_lock()
518 {
519 access.release_reader();
520 }
521 }
522}
523
524impl LifetimeRef {
525 pub fn state(&self) -> &LifetimeWeakState {
526 &self.0
527 }
528
529 pub fn tag(&self) -> usize {
530 self.0.tag
531 }
532
533 pub fn exists(&self) -> bool {
534 self.0.upgrade().is_some()
535 }
536
537 pub fn can_read(&self) -> bool {
538 self.0
539 .upgrade()
540 .map(|state| state.can_read())
541 .unwrap_or(false)
542 }
543
544 pub fn is_read_accessible(&self) -> bool {
545 self.0
546 .upgrade()
547 .map(|state| state.is_read_accessible())
548 .unwrap_or(false)
549 }
550
551 pub fn is_in_use(&self) -> bool {
552 self.0
553 .upgrade()
554 .map(|state| state.is_in_use())
555 .unwrap_or(false)
556 }
557
558 pub fn is_owned_by(&self, other: &Lifetime) -> bool {
559 self.0.is_owned_by(&other.0)
560 }
561
562 pub fn borrow(&self) -> Option<LifetimeRef> {
563 self.0
564 .upgrade()?
565 .try_lock()
566 .filter(|access| access.state.can_read())
567 .map(|mut access| {
568 access.acquire_reader();
569 LifetimeRef(self.0.clone())
570 })
571 }
572
573 pub async fn borrow_async(&self) -> LifetimeRef {
574 loop {
575 if let Some(lifetime_ref) = self.borrow() {
576 return lifetime_ref;
577 }
578 poll_fn(|cx| {
579 cx.waker().wake_by_ref();
580 Poll::<LifetimeRef>::Pending
581 })
582 .await;
583 }
584 }
585
586 pub fn lazy(&self) -> LifetimeLazy {
587 LifetimeLazy(self.0.clone())
588 }
589
590 pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
591 let state = self.0.upgrade()?;
592 let mut access = state.try_lock()?;
593 if access.state.is_read_accessible() {
594 access.unlock = false;
595 access.acquire_read_access();
596 drop(access);
597 Some(ValueReadAccess {
598 lifetime: state,
599 data,
600 })
601 } else {
602 None
603 }
604 }
605
606 pub async fn read_async<'a, T: ?Sized>(&'a self, data: &'a T) -> ValueReadAccess<'a, T> {
607 loop {
608 if let Some(access) = self.read(data) {
609 return access;
610 }
611 poll_fn(|cx| {
612 cx.waker().wake_by_ref();
613 Poll::<ValueReadAccess<'a, T>>::Pending
614 })
615 .await;
616 }
617 }
618
619 pub unsafe fn read_ptr<T: ?Sized>(&'_ self, data: *const T) -> Option<ValueReadAccess<'_, T>> {
621 let state = self.0.upgrade()?;
622 let mut access = state.try_lock()?;
623 if access.state.is_read_accessible() {
624 access.unlock = false;
625 access.acquire_read_access();
626 drop(access);
627 Some(ValueReadAccess {
628 lifetime: state,
629 data: unsafe { data.as_ref() }?,
630 })
631 } else {
632 None
633 }
634 }
635
636 pub async unsafe fn read_ptr_async<'a, T: ?Sized + 'a>(
638 &'a self,
639 data: *const T,
640 ) -> ValueReadAccess<'a, T> {
641 loop {
642 if let Some(access) = unsafe { self.read_ptr(data) } {
643 return access;
644 }
645 poll_fn(|cx| {
646 cx.waker().wake_by_ref();
647 Poll::<ValueReadAccess<'a, T>>::Pending
648 })
649 .await;
650 }
651 }
652
653 pub fn try_read_lock(&self) -> Option<ReadLock> {
654 let state = self.0.upgrade()?;
655 let mut access = state.lock();
656 if !access.state.is_read_accessible() {
657 return None;
658 }
659 access.acquire_read_access();
660 Some(ReadLock {
661 lifetime: state.clone(),
662 })
663 }
664
665 pub fn read_lock(&self) -> Option<ReadLock> {
666 let state = self.0.upgrade()?;
667 let mut access = state.lock();
668 while !access.state.is_read_accessible() {
669 std::hint::spin_loop();
670 }
671 access.acquire_read_access();
672 Some(ReadLock {
673 lifetime: state.clone(),
674 })
675 }
676
677 pub async fn read_lock_async(&self) -> ReadLock {
678 loop {
679 if let Some(lock) = self.read_lock() {
680 return lock;
681 }
682 poll_fn(|cx| {
683 cx.waker().wake_by_ref();
684 Poll::<ReadLock>::Pending
685 })
686 .await;
687 }
688 }
689
690 pub fn consume<T: ?Sized>(self, data: &'_ T) -> Result<ValueReadAccess<'_, T>, Self> {
691 let state = match self.0.upgrade() {
692 Some(state) => state,
693 None => return Err(self),
694 };
695 let mut access = match state.try_lock() {
696 Some(access) => access,
697 None => return Err(self),
698 };
699 if access.state.is_read_accessible() {
700 access.unlock = false;
701 access.acquire_read_access();
702 drop(access);
703 Ok(ValueReadAccess {
704 lifetime: state,
705 data,
706 })
707 } else {
708 Err(self)
709 }
710 }
711
712 pub async fn wait_for_read_access(&self) {
713 loop {
714 let Some(state) = self.0.upgrade() else {
715 return;
716 };
717 if state.is_read_accessible() {
718 return;
719 }
720 poll_fn(|cx| {
721 cx.waker().wake_by_ref();
722 Poll::<()>::Pending
723 })
724 .await;
725 }
726 }
727
728 pub async fn wait_for_write_access(&self) {
729 loop {
730 let Some(state) = self.0.upgrade() else {
731 return;
732 };
733 if state.is_read_accessible() {
734 return;
735 }
736 poll_fn(|cx| {
737 cx.waker().wake_by_ref();
738 Poll::<()>::Pending
739 })
740 .await;
741 }
742 }
743}
744
745pub struct LifetimeRefMut(LifetimeWeakState, usize);
746
747impl Drop for LifetimeRefMut {
748 fn drop(&mut self) {
749 if let Some(state) = unsafe { self.0.upgrade_unchecked() }
750 && let Some(mut access) = state.try_lock()
751 {
752 access.release_writer(self.1);
753 }
754 }
755}
756
757impl LifetimeRefMut {
758 pub fn state(&self) -> &LifetimeWeakState {
759 &self.0
760 }
761
762 pub fn tag(&self) -> usize {
763 self.0.tag
764 }
765
766 pub fn depth(&self) -> usize {
767 self.1
768 }
769
770 pub fn exists(&self) -> bool {
771 self.0.upgrade().is_some()
772 }
773
774 pub fn can_read(&self) -> bool {
775 self.0
776 .upgrade()
777 .map(|state| state.can_read())
778 .unwrap_or(false)
779 }
780
781 pub fn can_write(&self) -> bool {
782 self.0
783 .upgrade()
784 .map(|state| state.can_write(self.1))
785 .unwrap_or(false)
786 }
787
788 pub fn is_read_accessible(&self) -> bool {
789 self.0
790 .upgrade()
791 .map(|state| state.is_read_accessible())
792 .unwrap_or(false)
793 }
794
795 pub fn is_write_accessible(&self) -> bool {
796 self.0
797 .upgrade()
798 .map(|state| state.is_write_accessible())
799 .unwrap_or(false)
800 }
801
802 pub fn is_in_use(&self) -> bool {
803 self.0
804 .upgrade()
805 .map(|state| state.is_in_use())
806 .unwrap_or(false)
807 }
808
809 pub fn is_owned_by(&self, other: &Lifetime) -> bool {
810 self.0.is_owned_by(&other.0)
811 }
812
813 pub fn borrow(&self) -> Option<LifetimeRef> {
814 self.0
815 .upgrade()?
816 .try_lock()
817 .filter(|access| access.state.can_read())
818 .map(|mut access| {
819 access.acquire_reader();
820 LifetimeRef(self.0.clone())
821 })
822 }
823
824 pub async fn borrow_async(&self) -> LifetimeRef {
825 loop {
826 if let Some(lifetime_ref) = self.borrow() {
827 return lifetime_ref;
828 }
829 poll_fn(|cx| {
830 cx.waker().wake_by_ref();
831 Poll::<LifetimeRef>::Pending
832 })
833 .await;
834 }
835 }
836
837 pub fn borrow_mut(&self) -> Option<LifetimeRefMut> {
838 self.0
839 .upgrade()?
840 .try_lock()
841 .filter(|access| access.state.can_write(self.1))
842 .map(|mut access| {
843 let id = access.acquire_writer();
844 LifetimeRefMut(self.0.clone(), id)
845 })
846 }
847
848 pub async fn borrow_mut_async(&self) -> LifetimeRefMut {
849 loop {
850 if let Some(lifetime_ref_mut) = self.borrow_mut() {
851 return lifetime_ref_mut;
852 }
853 poll_fn(|cx| {
854 cx.waker().wake_by_ref();
855 Poll::<LifetimeRefMut>::Pending
856 })
857 .await;
858 }
859 }
860
861 pub fn lazy(&self) -> LifetimeLazy {
862 LifetimeLazy(self.0.clone())
863 }
864
865 pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
866 let state = self.0.upgrade()?;
867 let mut access = state.try_lock()?;
868 if access.state.is_read_accessible() {
869 access.unlock = false;
870 access.acquire_read_access();
871 drop(access);
872 Some(ValueReadAccess {
873 lifetime: state,
874 data,
875 })
876 } else {
877 None
878 }
879 }
880
881 pub async fn read_async<'a, T: ?Sized>(&'a self, data: &'a T) -> ValueReadAccess<'a, T> {
882 loop {
883 if let Some(access) = self.read(data) {
884 return access;
885 }
886 poll_fn(|cx| {
887 cx.waker().wake_by_ref();
888 Poll::<ValueReadAccess<'a, T>>::Pending
889 })
890 .await;
891 }
892 }
893
894 pub unsafe fn read_ptr<T: ?Sized>(&'_ self, data: *const T) -> Option<ValueReadAccess<'_, T>> {
896 let state = self.0.upgrade()?;
897 let mut access = state.try_lock()?;
898 if access.state.is_read_accessible() {
899 access.unlock = false;
900 access.acquire_read_access();
901 drop(access);
902 Some(ValueReadAccess {
903 lifetime: state,
904 data: unsafe { data.as_ref() }?,
905 })
906 } else {
907 None
908 }
909 }
910
911 pub async unsafe fn read_ptr_async<'a, T: ?Sized + 'a>(
913 &'a self,
914 data: *const T,
915 ) -> ValueReadAccess<'a, T> {
916 loop {
917 if let Some(access) = unsafe { self.read_ptr(data) } {
918 return access;
919 }
920 poll_fn(|cx| {
921 cx.waker().wake_by_ref();
922 Poll::<ValueReadAccess<'a, T>>::Pending
923 })
924 .await;
925 }
926 }
927
928 pub fn write<'a, T: ?Sized>(&'a self, data: &'a mut T) -> Option<ValueWriteAccess<'a, T>> {
929 let state = self.0.upgrade()?;
930 let mut access = state.try_lock()?;
931 if access.state.is_write_accessible() {
932 access.unlock = false;
933 access.acquire_write_access();
934 drop(access);
935 Some(ValueWriteAccess {
936 lifetime: state,
937 data,
938 })
939 } else {
940 None
941 }
942 }
943
944 pub async fn write_async<'a, T: ?Sized>(&'a self, data: &'a mut T) -> ValueWriteAccess<'a, T> {
945 unsafe { self.write_ptr_async(data as *mut T).await }
946 }
947
948 pub unsafe fn write_ptr<T: ?Sized>(&'_ self, data: *mut T) -> Option<ValueWriteAccess<'_, T>> {
950 let state = self.0.upgrade()?;
951 let mut access = state.try_lock()?;
952 if access.state.is_write_accessible() {
953 access.unlock = false;
954 access.acquire_write_access();
955 drop(access);
956 Some(ValueWriteAccess {
957 lifetime: state,
958 data: unsafe { data.as_mut() }?,
959 })
960 } else {
961 None
962 }
963 }
964
965 pub async unsafe fn write_ptr_async<'a, T: ?Sized + 'a>(
967 &'a self,
968 data: *mut T,
969 ) -> ValueWriteAccess<'a, T> {
970 loop {
971 if let Some(access) = unsafe { self.write_ptr(data) } {
972 return access;
973 }
974 poll_fn(|cx| {
975 cx.waker().wake_by_ref();
976 Poll::<ValueWriteAccess<'a, T>>::Pending
977 })
978 .await;
979 }
980 }
981
982 pub fn try_read_lock(&self) -> Option<ReadLock> {
983 let state = self.0.upgrade()?;
984 let mut access = state.lock();
985 if !access.state.is_read_accessible() {
986 return None;
987 }
988 access.acquire_read_access();
989 Some(ReadLock {
990 lifetime: state.clone(),
991 })
992 }
993
994 pub fn read_lock(&self) -> Option<ReadLock> {
995 let state = self.0.upgrade()?;
996 let mut access = state.lock();
997 while !access.state.is_read_accessible() {
998 std::hint::spin_loop();
999 }
1000 access.acquire_read_access();
1001 Some(ReadLock {
1002 lifetime: state.clone(),
1003 })
1004 }
1005
1006 pub async fn read_lock_async(&self) -> ReadLock {
1007 loop {
1008 if let Some(lock) = self.read_lock() {
1009 return lock;
1010 }
1011 poll_fn(|cx| {
1012 cx.waker().wake_by_ref();
1013 Poll::<ReadLock>::Pending
1014 })
1015 .await;
1016 }
1017 }
1018
1019 pub fn try_write_lock(&self) -> Option<WriteLock> {
1020 let state = self.0.upgrade()?;
1021 let mut access = state.lock();
1022 if !access.state.is_write_accessible() {
1023 return None;
1024 }
1025 access.acquire_write_access();
1026 Some(WriteLock {
1027 lifetime: state.clone(),
1028 })
1029 }
1030
1031 pub fn write_lock(&self) -> Option<WriteLock> {
1032 let state = self.0.upgrade()?;
1033 let mut access = state.lock();
1034 while !access.state.is_write_accessible() {
1035 std::hint::spin_loop();
1036 }
1037 access.acquire_write_access();
1038 Some(WriteLock {
1039 lifetime: state.clone(),
1040 })
1041 }
1042
1043 pub async fn write_lock_async(&self) -> WriteLock {
1044 loop {
1045 if let Some(lock) = self.write_lock() {
1046 return lock;
1047 }
1048 poll_fn(|cx| {
1049 cx.waker().wake_by_ref();
1050 Poll::<WriteLock>::Pending
1051 })
1052 .await;
1053 }
1054 }
1055
1056 pub fn consume<T: ?Sized>(self, data: &'_ mut T) -> Result<ValueWriteAccess<'_, T>, Self> {
1057 let state = match self.0.upgrade() {
1058 Some(state) => state,
1059 None => return Err(self),
1060 };
1061 let mut access = match state.try_lock() {
1062 Some(access) => access,
1063 None => return Err(self),
1064 };
1065 if access.state.is_write_accessible() {
1066 access.unlock = false;
1067 access.acquire_write_access();
1068 drop(access);
1069 Ok(ValueWriteAccess {
1070 lifetime: state,
1071 data,
1072 })
1073 } else {
1074 Err(self)
1075 }
1076 }
1077
1078 pub async fn wait_for_read_access(&self) {
1079 loop {
1080 let Some(state) = self.0.upgrade() else {
1081 return;
1082 };
1083 if state.is_read_accessible() {
1084 return;
1085 }
1086 poll_fn(|cx| {
1087 cx.waker().wake_by_ref();
1088 Poll::<()>::Pending
1089 })
1090 .await;
1091 }
1092 }
1093
1094 pub async fn wait_for_write_access(&self) {
1095 loop {
1096 let Some(state) = self.0.upgrade() else {
1097 return;
1098 };
1099 if state.is_read_accessible() {
1100 return;
1101 }
1102 poll_fn(|cx| {
1103 cx.waker().wake_by_ref();
1104 Poll::<()>::Pending
1105 })
1106 .await;
1107 }
1108 }
1109}
1110
1111#[derive(Clone)]
1112pub struct LifetimeLazy(LifetimeWeakState);
1113
1114impl LifetimeLazy {
1115 pub fn state(&self) -> &LifetimeWeakState {
1116 &self.0
1117 }
1118
1119 pub fn tag(&self) -> usize {
1120 self.0.tag
1121 }
1122
1123 pub fn exists(&self) -> bool {
1124 self.0.upgrade().is_some()
1125 }
1126
1127 pub fn is_read_accessible(&self) -> bool {
1128 self.0
1129 .upgrade()
1130 .map(|state| state.is_read_accessible())
1131 .unwrap_or(false)
1132 }
1133
1134 pub fn is_write_accessible(&self) -> bool {
1135 self.0
1136 .upgrade()
1137 .map(|state| state.is_write_accessible())
1138 .unwrap_or(false)
1139 }
1140
1141 pub fn is_in_use(&self) -> bool {
1142 self.0
1143 .upgrade()
1144 .map(|state| state.is_in_use())
1145 .unwrap_or(false)
1146 }
1147
1148 pub fn is_owned_by(&self, other: &Lifetime) -> bool {
1149 self.0.is_owned_by(&other.0)
1150 }
1151
1152 pub fn borrow(&self) -> Option<LifetimeRef> {
1153 self.0
1154 .upgrade()?
1155 .try_lock()
1156 .filter(|access| access.state.can_read())
1157 .map(|mut access| {
1158 access.acquire_reader();
1159 LifetimeRef(self.0.clone())
1160 })
1161 }
1162
1163 pub async fn borrow_async(&self) -> LifetimeRef {
1164 loop {
1165 if let Some(lifetime_ref) = self.borrow() {
1166 return lifetime_ref;
1167 }
1168 poll_fn(|cx| {
1169 cx.waker().wake_by_ref();
1170 Poll::<LifetimeRef>::Pending
1171 })
1172 .await;
1173 }
1174 }
1175
1176 pub fn borrow_mut(&self) -> Option<LifetimeRefMut> {
1177 self.0
1178 .upgrade()?
1179 .try_lock()
1180 .filter(|access| access.state.can_write(0))
1181 .map(|mut access| {
1182 let id = access.acquire_writer();
1183 LifetimeRefMut(self.0.clone(), id)
1184 })
1185 }
1186
1187 pub async fn borrow_mut_async(&self) -> LifetimeRefMut {
1188 loop {
1189 if let Some(lifetime_ref_mut) = self.borrow_mut() {
1190 return lifetime_ref_mut;
1191 }
1192 poll_fn(|cx| {
1193 cx.waker().wake_by_ref();
1194 Poll::<LifetimeRefMut>::Pending
1195 })
1196 .await;
1197 }
1198 }
1199
1200 pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
1201 let state = self.0.upgrade()?;
1202 let mut access = state.try_lock()?;
1203 if access.state.is_read_accessible() {
1204 access.unlock = false;
1205 access.acquire_read_access();
1206 drop(access);
1207 Some(ValueReadAccess {
1208 lifetime: state,
1209 data,
1210 })
1211 } else {
1212 None
1213 }
1214 }
1215
1216 pub async fn read_async<'a, T: ?Sized>(&'a self, data: &'a T) -> ValueReadAccess<'a, T> {
1217 loop {
1218 if let Some(access) = self.read(data) {
1219 return access;
1220 }
1221 poll_fn(|cx| {
1222 cx.waker().wake_by_ref();
1223 Poll::<ValueReadAccess<'a, T>>::Pending
1224 })
1225 .await;
1226 }
1227 }
1228
1229 pub unsafe fn read_ptr<T: ?Sized>(&'_ self, data: *const T) -> Option<ValueReadAccess<'_, T>> {
1231 let state = self.0.upgrade()?;
1232 let mut access = state.try_lock()?;
1233 if access.state.is_read_accessible() {
1234 access.unlock = false;
1235 access.acquire_read_access();
1236 drop(access);
1237 Some(ValueReadAccess {
1238 lifetime: state,
1239 data: unsafe { data.as_ref() }?,
1240 })
1241 } else {
1242 None
1243 }
1244 }
1245
1246 pub async unsafe fn read_ptr_async<'a, T: ?Sized + 'a>(
1248 &'a self,
1249 data: *const T,
1250 ) -> ValueReadAccess<'a, T> {
1251 loop {
1252 if let Some(access) = unsafe { self.read_ptr(data) } {
1253 return access;
1254 }
1255 poll_fn(|cx| {
1256 cx.waker().wake_by_ref();
1257 Poll::<ValueReadAccess<'a, T>>::Pending
1258 })
1259 .await;
1260 }
1261 }
1262
1263 pub fn write<'a, T: ?Sized>(&'a self, data: &'a mut T) -> Option<ValueWriteAccess<'a, T>> {
1264 let state = self.0.upgrade()?;
1265 let mut access = state.try_lock()?;
1266 if access.state.is_write_accessible() {
1267 access.unlock = false;
1268 access.acquire_write_access();
1269 drop(access);
1270 Some(ValueWriteAccess {
1271 lifetime: state,
1272 data,
1273 })
1274 } else {
1275 None
1276 }
1277 }
1278
1279 pub async fn write_async<'a, T: ?Sized>(&'a self, data: &'a mut T) -> ValueWriteAccess<'a, T> {
1280 unsafe { self.write_ptr_async(data as *mut T).await }
1281 }
1282
1283 pub unsafe fn write_ptr<T: ?Sized>(&'_ self, data: *mut T) -> Option<ValueWriteAccess<'_, T>> {
1285 let state = self.0.upgrade()?;
1286 let mut access = state.try_lock()?;
1287 if access.state.is_write_accessible() {
1288 access.unlock = false;
1289 access.acquire_write_access();
1290 drop(access);
1291 Some(ValueWriteAccess {
1292 lifetime: state,
1293 data: unsafe { data.as_mut() }?,
1294 })
1295 } else {
1296 None
1297 }
1298 }
1299
1300 pub async unsafe fn write_ptr_async<'a, T: ?Sized + 'a>(
1302 &'a self,
1303 data: *mut T,
1304 ) -> ValueWriteAccess<'a, T> {
1305 loop {
1306 if let Some(access) = unsafe { self.write_ptr(data) } {
1307 return access;
1308 }
1309 poll_fn(|cx| {
1310 cx.waker().wake_by_ref();
1311 Poll::<ValueWriteAccess<'a, T>>::Pending
1312 })
1313 .await;
1314 }
1315 }
1316
1317 pub fn consume<T: ?Sized>(self, data: &'_ mut T) -> Result<ValueWriteAccess<'_, T>, Self> {
1318 let state = match self.0.upgrade() {
1319 Some(state) => state,
1320 None => return Err(self),
1321 };
1322 let mut access = match state.try_lock() {
1323 Some(access) => access,
1324 None => return Err(self),
1325 };
1326 if access.state.is_write_accessible() {
1327 access.unlock = false;
1328 access.acquire_write_access();
1329 drop(access);
1330 Ok(ValueWriteAccess {
1331 lifetime: state,
1332 data,
1333 })
1334 } else {
1335 Err(self)
1336 }
1337 }
1338
1339 pub async fn wait_for_read_access(&self) {
1340 loop {
1341 let Some(state) = self.0.upgrade() else {
1342 return;
1343 };
1344 if state.is_read_accessible() {
1345 return;
1346 }
1347 poll_fn(|cx| {
1348 cx.waker().wake_by_ref();
1349 Poll::<()>::Pending
1350 })
1351 .await;
1352 }
1353 }
1354
1355 pub async fn wait_for_write_access(&self) {
1356 loop {
1357 let Some(state) = self.0.upgrade() else {
1358 return;
1359 };
1360 if state.is_read_accessible() {
1361 return;
1362 }
1363 poll_fn(|cx| {
1364 cx.waker().wake_by_ref();
1365 Poll::<()>::Pending
1366 })
1367 .await;
1368 }
1369 }
1370}
1371
1372pub struct ValueReadAccess<'a, T: 'a + ?Sized> {
1373 lifetime: LifetimeState,
1374 data: &'a T,
1375}
1376
1377impl<T: ?Sized> Drop for ValueReadAccess<'_, T> {
1378 fn drop(&mut self) {
1379 unsafe { self.lifetime.lock_unchecked().release_read_access() };
1380 }
1381}
1382
1383impl<'a, T: ?Sized> ValueReadAccess<'a, T> {
1384 pub unsafe fn new_raw(data: &'a T, lifetime: LifetimeState) -> Self {
1386 Self { lifetime, data }
1387 }
1388}
1389
1390impl<T: ?Sized> Deref for ValueReadAccess<'_, T> {
1391 type Target = T;
1392
1393 fn deref(&self) -> &Self::Target {
1394 self.data
1395 }
1396}
1397
1398impl<'a, T: ?Sized> ValueReadAccess<'a, T> {
1399 pub fn remap<U>(
1400 self,
1401 f: impl FnOnce(&T) -> Option<&U>,
1402 ) -> Result<ValueReadAccess<'a, U>, Self> {
1403 if let Some(data) = f(self.data) {
1404 Ok(ValueReadAccess {
1405 lifetime: self.lifetime.clone(),
1406 data,
1407 })
1408 } else {
1409 Err(self)
1410 }
1411 }
1412}
1413
1414pub struct ValueWriteAccess<'a, T: 'a + ?Sized> {
1415 lifetime: LifetimeState,
1416 data: &'a mut T,
1417}
1418
1419impl<T: ?Sized> Drop for ValueWriteAccess<'_, T> {
1420 fn drop(&mut self) {
1421 unsafe { self.lifetime.lock_unchecked().release_write_access() };
1422 }
1423}
1424
1425impl<'a, T: ?Sized> ValueWriteAccess<'a, T> {
1426 pub unsafe fn new_raw(data: &'a mut T, lifetime: LifetimeState) -> Self {
1428 Self { lifetime, data }
1429 }
1430}
1431
1432impl<T: ?Sized> Deref for ValueWriteAccess<'_, T> {
1433 type Target = T;
1434
1435 fn deref(&self) -> &Self::Target {
1436 self.data
1437 }
1438}
1439
1440impl<T: ?Sized> DerefMut for ValueWriteAccess<'_, T> {
1441 fn deref_mut(&mut self) -> &mut Self::Target {
1442 self.data
1443 }
1444}
1445
1446impl<'a, T: ?Sized> ValueWriteAccess<'a, T> {
1447 pub fn remap<U>(
1448 self,
1449 f: impl FnOnce(&mut T) -> Option<&mut U>,
1450 ) -> Result<ValueWriteAccess<'a, U>, Self> {
1451 if let Some(data) = f(unsafe { std::mem::transmute::<&mut T, &'a mut T>(&mut *self.data) })
1452 {
1453 Ok(ValueWriteAccess {
1454 lifetime: self.lifetime.clone(),
1455 data,
1456 })
1457 } else {
1458 Err(self)
1459 }
1460 }
1461}
1462
1463pub struct ReadLock {
1464 lifetime: LifetimeState,
1465}
1466
1467impl Drop for ReadLock {
1468 fn drop(&mut self) {
1469 unsafe { self.lifetime.lock_unchecked().release_read_access() };
1470 }
1471}
1472
1473impl ReadLock {
1474 pub unsafe fn new_raw(lifetime: LifetimeState) -> Self {
1476 Self { lifetime }
1477 }
1478
1479 pub fn using<R>(self, f: impl FnOnce() -> R) -> R {
1480 let result = f();
1481 drop(self);
1482 result
1483 }
1484}
1485
1486pub struct WriteLock {
1487 lifetime: LifetimeState,
1488}
1489
1490impl Drop for WriteLock {
1491 fn drop(&mut self) {
1492 unsafe { self.lifetime.lock_unchecked().release_write_access() };
1493 }
1494}
1495
1496impl WriteLock {
1497 pub unsafe fn new_raw(lifetime: LifetimeState) -> Self {
1499 Self { lifetime }
1500 }
1501
1502 pub fn using<R>(self, f: impl FnOnce() -> R) -> R {
1503 let result = f();
1504 drop(self);
1505 result
1506 }
1507}
1508
1509#[cfg(test)]
1510mod tests {
1511 use super::*;
1512 use std::thread::*;
1513
1514 fn is_async<T: Send + Sync + ?Sized>() {
1515 println!("{} is async!", std::any::type_name::<T>());
1516 }
1517
1518 #[test]
1519 fn test_lifetimes() {
1520 is_async::<Lifetime>();
1521 is_async::<LifetimeRef>();
1522 is_async::<LifetimeRefMut>();
1523 is_async::<LifetimeLazy>();
1524
1525 let mut value = 0usize;
1526 let lifetime_ref = {
1527 let lifetime = Lifetime::default();
1528 assert!(lifetime.state().can_read());
1529 assert!(lifetime.state().can_write(0));
1530 assert!(lifetime.state().is_read_accessible());
1531 assert!(lifetime.state().is_write_accessible());
1532 let lifetime_lazy = lifetime.lazy();
1533 assert!(lifetime_lazy.read(&42).is_some());
1534 assert!(lifetime_lazy.write(&mut 42).is_some());
1535 {
1536 let access = lifetime.read(&value).unwrap();
1537 assert_eq!(*access, value);
1538 }
1539 {
1540 let mut access = lifetime.write(&mut value).unwrap();
1541 *access = 42;
1542 assert_eq!(*access, 42);
1543 }
1544 {
1545 let lifetime_ref = lifetime.borrow().unwrap();
1546 assert!(lifetime.state().can_read());
1547 assert!(!lifetime.state().can_write(0));
1548 assert!(lifetime_ref.exists());
1549 assert!(lifetime_ref.is_owned_by(&lifetime));
1550 assert!(lifetime.borrow().is_some());
1551 assert!(lifetime.borrow_mut().is_none());
1552 assert!(lifetime_lazy.read(&42).is_some());
1553 assert!(lifetime_lazy.write(&mut 42).is_some());
1554 {
1555 let access = lifetime_ref.read(&value).unwrap();
1556 assert_eq!(*access, 42);
1557 assert!(lifetime_lazy.read(&42).is_none());
1558 assert!(lifetime_lazy.write(&mut 42).is_none());
1559 }
1560 let lifetime_ref2 = lifetime_ref.borrow().unwrap();
1561 {
1562 let access = lifetime_ref2.read(&value).unwrap();
1563 assert_eq!(*access, 42);
1564 assert!(lifetime_lazy.read(&42).is_none());
1565 assert!(lifetime_lazy.write(&mut 42).is_none());
1566 }
1567 }
1568 {
1569 let lifetime_ref_mut = lifetime.borrow_mut().unwrap();
1570 assert_eq!(lifetime.state().writer_depth(), 1);
1571 assert!(!lifetime.state().can_read());
1572 assert!(!lifetime.state().can_write(0));
1573 assert!(lifetime_ref_mut.exists());
1574 assert!(lifetime_ref_mut.is_owned_by(&lifetime));
1575 assert!(lifetime.borrow().is_none());
1576 assert!(lifetime.borrow_mut().is_none());
1577 assert!(lifetime_lazy.read(&42).is_some());
1578 assert!(lifetime_lazy.write(&mut 42).is_some());
1579 {
1580 let mut access = lifetime_ref_mut.write(&mut value).unwrap();
1581 *access = 7;
1582 assert_eq!(*access, 7);
1583 assert!(lifetime_lazy.read(&42).is_none());
1584 assert!(lifetime_lazy.write(&mut 42).is_none());
1585 }
1586 let lifetime_ref_mut2 = lifetime_ref_mut.borrow_mut().unwrap();
1587 assert!(lifetime_lazy.read(&42).is_some());
1588 assert!(lifetime_lazy.write(&mut 42).is_some());
1589 {
1590 assert_eq!(lifetime.state().writer_depth(), 2);
1591 assert!(lifetime.borrow().is_none());
1592 assert!(lifetime_ref_mut.borrow().is_none());
1593 assert!(lifetime.borrow_mut().is_none());
1594 assert!(lifetime_ref_mut.borrow_mut().is_none());
1595 let mut access = lifetime_ref_mut2.write(&mut value).unwrap();
1596 *access = 42;
1597 assert_eq!(*access, 42);
1598 assert!(lifetime.read(&42).is_none());
1599 assert!(lifetime_ref_mut.read(&42).is_none());
1600 assert!(lifetime.write(&mut 42).is_none());
1601 assert!(lifetime_ref_mut.write(&mut 42).is_none());
1602 assert!(lifetime_lazy.read(&42).is_none());
1603 assert!(lifetime_lazy.write(&mut 42).is_none());
1604 assert!(lifetime_lazy.read(&42).is_none());
1605 assert!(lifetime_lazy.write(&mut 42).is_none());
1606 }
1607 }
1608 assert_eq!(lifetime.state().writer_depth(), 0);
1609 lifetime.borrow().unwrap()
1610 };
1611 assert!(!lifetime_ref.exists());
1612 assert_eq!(value, 42);
1613 }
1614
1615 #[test]
1616 fn test_lifetimes_multithread() {
1617 let lifetime = Lifetime::default();
1618 let lifetime_ref = lifetime.borrow().unwrap();
1619 assert!(lifetime_ref.exists());
1620 assert!(lifetime_ref.is_owned_by(&lifetime));
1621 drop(lifetime);
1622 assert!(!lifetime_ref.exists());
1623 let lifetime = Lifetime::default();
1624 let lifetime = spawn(move || {
1625 let value_ref = lifetime.borrow().unwrap();
1626 assert!(value_ref.exists());
1627 assert!(value_ref.is_owned_by(&lifetime));
1628 lifetime
1629 })
1630 .join()
1631 .unwrap();
1632 assert!(!lifetime_ref.exists());
1633 assert!(!lifetime_ref.is_owned_by(&lifetime));
1634 }
1635
1636 #[test]
1637 fn test_lifetimes_move_invalidation() {
1638 let lifetime = Lifetime::default();
1639 let lifetime_ref = lifetime.borrow().unwrap();
1640 assert_eq!(lifetime_ref.tag(), lifetime.tag());
1641 assert!(lifetime_ref.exists());
1642 let lifetime_ref2 = lifetime_ref;
1643 assert_eq!(lifetime_ref2.tag(), lifetime.tag());
1644 assert!(lifetime_ref2.exists());
1645 let lifetime = Box::new(lifetime);
1646 assert_ne!(lifetime_ref2.tag(), lifetime.tag());
1647 assert!(!lifetime_ref2.exists());
1648 let lifetime = *lifetime;
1649 assert_ne!(lifetime_ref2.tag(), lifetime.tag());
1650 assert!(!lifetime_ref2.exists());
1651 }
1652
1653 #[pollster::test]
1654 async fn test_lifetime_async() {
1655 let mut value = 42usize;
1656 let lifetime = Lifetime::default();
1657 assert_eq!(*lifetime.read_async(&value).await, 42);
1658 {
1659 let lifetime_ref = lifetime.borrow_async().await;
1660 {
1661 let access = lifetime_ref.read_async(&value).await;
1662 assert_eq!(*access, 42);
1663 }
1664 }
1665 {
1666 let lifetime_ref_mut = lifetime.borrow_mut_async().await;
1667 {
1668 let mut access = lifetime_ref_mut.write_async(&mut value).await;
1669 *access = 7;
1670 assert_eq!(*access, 7);
1671 }
1672 assert_eq!(*lifetime.read_async(&value).await, 7);
1673 }
1674 {
1675 let mut access = lifetime.write_async(&mut value).await;
1676 *access = 84;
1677 }
1678 {
1679 let access = lifetime.read_async(&value).await;
1680 assert_eq!(*access, 84);
1681 }
1682 }
1683
1684 #[test]
1685 fn test_lifetime_locks() {
1686 let lifetime = Lifetime::default();
1687 assert!(lifetime.state().is_read_accessible());
1688 assert!(lifetime.state().is_write_accessible());
1689
1690 let read_lock = lifetime.read_lock();
1691 assert!(lifetime.state().is_read_accessible());
1692 assert!(!lifetime.state().is_write_accessible());
1693
1694 drop(read_lock);
1695 assert!(lifetime.state().is_read_accessible());
1696 assert!(lifetime.state().is_write_accessible());
1697
1698 let read_lock = lifetime.read_lock();
1699 assert!(lifetime.state().is_read_accessible());
1700 assert!(!lifetime.state().is_write_accessible());
1701
1702 let read_lock2 = lifetime.read_lock();
1703 assert!(lifetime.state().is_read_accessible());
1704 assert!(!lifetime.state().is_write_accessible());
1705
1706 drop(read_lock);
1707 assert!(lifetime.state().is_read_accessible());
1708 assert!(!lifetime.state().is_write_accessible());
1709
1710 drop(read_lock2);
1711 assert!(lifetime.state().is_read_accessible());
1712 assert!(lifetime.state().is_write_accessible());
1713
1714 let write_lock = lifetime.write_lock();
1715 assert!(!lifetime.state().is_read_accessible());
1716 assert!(!lifetime.state().is_write_accessible());
1717
1718 assert!(lifetime.try_read_lock().is_none());
1719 assert!(lifetime.try_write_lock().is_none());
1720
1721 drop(write_lock);
1722 assert!(lifetime.state().is_read_accessible());
1723 assert!(lifetime.state().is_write_accessible());
1724
1725 let data = ();
1726 let read_access = lifetime.read(&data).unwrap();
1727 assert!(lifetime.state().is_read_accessible());
1728 assert!(!lifetime.state().is_write_accessible());
1729 assert!(lifetime.state().is_locked());
1730
1731 drop(read_access);
1732 assert!(lifetime.try_read_lock().is_some());
1733 assert!(lifetime.try_write_lock().is_some());
1734 }
1735}