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