intuicio_data/
lifetime.rs

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