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