intuicio_data/
lifetime.rs

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