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    pub async fn wait_for_read_access(&self) {
452        loop {
453            if self.state().is_read_accessible() {
454                return;
455            }
456            poll_fn(|cx| {
457                cx.waker().wake_by_ref();
458                Poll::<()>::Pending
459            })
460            .await;
461        }
462    }
463
464    pub async fn wait_for_write_access(&self) {
465        loop {
466            if self.state().is_write_accessible() {
467                return;
468            }
469            poll_fn(|cx| {
470                cx.waker().wake_by_ref();
471                Poll::<()>::Pending
472            })
473            .await;
474        }
475    }
476}
477
478pub struct LifetimeRef(LifetimeWeakState);
479
480impl Drop for LifetimeRef {
481    fn drop(&mut self) {
482        if let Some(owner) = unsafe { self.0.upgrade_unchecked() }
483            && let Some(mut access) = owner.try_lock()
484        {
485            access.release_reader();
486        }
487    }
488}
489
490impl LifetimeRef {
491    pub fn state(&self) -> &LifetimeWeakState {
492        &self.0
493    }
494
495    pub fn tag(&self) -> usize {
496        self.0.tag
497    }
498
499    pub fn exists(&self) -> bool {
500        self.0.upgrade().is_some()
501    }
502
503    pub fn can_read(&self) -> bool {
504        self.0
505            .upgrade()
506            .map(|state| state.can_read())
507            .unwrap_or(false)
508    }
509
510    pub fn is_read_accessible(&self) -> bool {
511        self.0
512            .upgrade()
513            .map(|state| state.is_read_accessible())
514            .unwrap_or(false)
515    }
516
517    pub fn is_in_use(&self) -> bool {
518        self.0
519            .upgrade()
520            .map(|state| state.is_in_use())
521            .unwrap_or(false)
522    }
523
524    pub fn is_owned_by(&self, other: &Lifetime) -> bool {
525        self.0.is_owned_by(&other.0)
526    }
527
528    pub fn borrow(&self) -> Option<LifetimeRef> {
529        self.0
530            .upgrade()?
531            .try_lock()
532            .filter(|access| access.state.can_read())
533            .map(|mut access| {
534                access.acquire_reader();
535                LifetimeRef(self.0.clone())
536            })
537    }
538
539    pub async fn borrow_async(&self) -> LifetimeRef {
540        loop {
541            if let Some(lifetime_ref) = self.borrow() {
542                return lifetime_ref;
543            }
544            poll_fn(|cx| {
545                cx.waker().wake_by_ref();
546                Poll::<LifetimeRef>::Pending
547            })
548            .await;
549        }
550    }
551
552    pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
553        let state = self.0.upgrade()?;
554        let mut access = state.try_lock()?;
555        if access.state.is_read_accessible() {
556            access.unlock = false;
557            access.acquire_read_access();
558            drop(access);
559            Some(ValueReadAccess {
560                lifetime: state,
561                data,
562            })
563        } else {
564            None
565        }
566    }
567
568    pub async fn read_async<'a, T: ?Sized>(&'a self, data: &'a T) -> ValueReadAccess<'a, T> {
569        loop {
570            if let Some(access) = self.read(data) {
571                return access;
572            }
573            poll_fn(|cx| {
574                cx.waker().wake_by_ref();
575                Poll::<ValueReadAccess<'a, T>>::Pending
576            })
577            .await;
578        }
579    }
580
581    /// # Safety
582    pub unsafe fn read_ptr<T: ?Sized>(&'_ self, data: *const T) -> Option<ValueReadAccess<'_, T>> {
583        let state = self.0.upgrade()?;
584        let mut access = state.try_lock()?;
585        if access.state.is_read_accessible() {
586            access.unlock = false;
587            access.acquire_read_access();
588            drop(access);
589            Some(ValueReadAccess {
590                lifetime: state,
591                data: unsafe { data.as_ref() }?,
592            })
593        } else {
594            None
595        }
596    }
597
598    /// # Safety
599    pub async unsafe fn read_ptr_async<'a, T: ?Sized + 'a>(
600        &'a self,
601        data: *const T,
602    ) -> ValueReadAccess<'a, T> {
603        loop {
604            if let Some(access) = unsafe { self.read_ptr(data) } {
605                return access;
606            }
607            poll_fn(|cx| {
608                cx.waker().wake_by_ref();
609                Poll::<ValueReadAccess<'a, T>>::Pending
610            })
611            .await;
612        }
613    }
614
615    pub fn read_lock(&self) -> Option<ReadLock> {
616        let state = self.0.upgrade()?;
617        let mut access = state.lock();
618        while !access.state.is_read_accessible() {
619            std::hint::spin_loop();
620        }
621        access.unlock = false;
622        access.acquire_read_access();
623        Some(ReadLock {
624            lifetime: state.clone(),
625        })
626    }
627
628    pub async fn read_lock_async(&self) -> ReadLock {
629        loop {
630            if let Some(lock) = self.read_lock() {
631                return lock;
632            }
633            poll_fn(|cx| {
634                cx.waker().wake_by_ref();
635                Poll::<ReadLock>::Pending
636            })
637            .await;
638        }
639    }
640
641    pub fn consume<T: ?Sized>(self, data: &'_ T) -> Result<ValueReadAccess<'_, T>, Self> {
642        let state = match self.0.upgrade() {
643            Some(state) => state,
644            None => return Err(self),
645        };
646        let mut access = match state.try_lock() {
647            Some(access) => access,
648            None => return Err(self),
649        };
650        if access.state.is_read_accessible() {
651            access.unlock = false;
652            access.acquire_read_access();
653            drop(access);
654            Ok(ValueReadAccess {
655                lifetime: state,
656                data,
657            })
658        } else {
659            Err(self)
660        }
661    }
662
663    pub async fn wait_for_read_access(&self) {
664        loop {
665            let Some(state) = self.0.upgrade() else {
666                return;
667            };
668            if state.is_read_accessible() {
669                return;
670            }
671            poll_fn(|cx| {
672                cx.waker().wake_by_ref();
673                Poll::<()>::Pending
674            })
675            .await;
676        }
677    }
678
679    pub async fn wait_for_write_access(&self) {
680        loop {
681            let Some(state) = self.0.upgrade() else {
682                return;
683            };
684            if state.is_read_accessible() {
685                return;
686            }
687            poll_fn(|cx| {
688                cx.waker().wake_by_ref();
689                Poll::<()>::Pending
690            })
691            .await;
692        }
693    }
694}
695
696pub struct LifetimeRefMut(LifetimeWeakState, usize);
697
698impl Drop for LifetimeRefMut {
699    fn drop(&mut self) {
700        if let Some(state) = unsafe { self.0.upgrade_unchecked() }
701            && let Some(mut access) = state.try_lock()
702        {
703            access.release_writer(self.1);
704        }
705    }
706}
707
708impl LifetimeRefMut {
709    pub fn state(&self) -> &LifetimeWeakState {
710        &self.0
711    }
712
713    pub fn tag(&self) -> usize {
714        self.0.tag
715    }
716
717    pub fn depth(&self) -> usize {
718        self.1
719    }
720
721    pub fn exists(&self) -> bool {
722        self.0.upgrade().is_some()
723    }
724
725    pub fn can_read(&self) -> bool {
726        self.0
727            .upgrade()
728            .map(|state| state.can_read())
729            .unwrap_or(false)
730    }
731
732    pub fn can_write(&self) -> bool {
733        self.0
734            .upgrade()
735            .map(|state| state.can_write(self.1))
736            .unwrap_or(false)
737    }
738
739    pub fn is_read_accessible(&self) -> bool {
740        self.0
741            .upgrade()
742            .map(|state| state.is_read_accessible())
743            .unwrap_or(false)
744    }
745
746    pub fn is_write_accessible(&self) -> bool {
747        self.0
748            .upgrade()
749            .map(|state| state.is_write_accessible())
750            .unwrap_or(false)
751    }
752
753    pub fn is_in_use(&self) -> bool {
754        self.0
755            .upgrade()
756            .map(|state| state.is_in_use())
757            .unwrap_or(false)
758    }
759
760    pub fn is_owned_by(&self, other: &Lifetime) -> bool {
761        self.0.is_owned_by(&other.0)
762    }
763
764    pub fn borrow(&self) -> Option<LifetimeRef> {
765        self.0
766            .upgrade()?
767            .try_lock()
768            .filter(|access| access.state.can_read())
769            .map(|mut access| {
770                access.acquire_reader();
771                LifetimeRef(self.0.clone())
772            })
773    }
774
775    pub async fn borrow_async(&self) -> LifetimeRef {
776        loop {
777            if let Some(lifetime_ref) = self.borrow() {
778                return lifetime_ref;
779            }
780            poll_fn(|cx| {
781                cx.waker().wake_by_ref();
782                Poll::<LifetimeRef>::Pending
783            })
784            .await;
785        }
786    }
787
788    pub fn borrow_mut(&self) -> Option<LifetimeRefMut> {
789        self.0
790            .upgrade()?
791            .try_lock()
792            .filter(|access| access.state.can_write(self.1))
793            .map(|mut access| {
794                let id = access.acquire_writer();
795                LifetimeRefMut(self.0.clone(), id)
796            })
797    }
798
799    pub async fn borrow_mut_async(&self) -> LifetimeRefMut {
800        loop {
801            if let Some(lifetime_ref_mut) = self.borrow_mut() {
802                return lifetime_ref_mut;
803            }
804            poll_fn(|cx| {
805                cx.waker().wake_by_ref();
806                Poll::<LifetimeRefMut>::Pending
807            })
808            .await;
809        }
810    }
811
812    pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
813        let state = self.0.upgrade()?;
814        let mut access = state.try_lock()?;
815        if access.state.is_read_accessible() {
816            access.unlock = false;
817            access.acquire_read_access();
818            drop(access);
819            Some(ValueReadAccess {
820                lifetime: state,
821                data,
822            })
823        } else {
824            None
825        }
826    }
827
828    pub async fn read_async<'a, T: ?Sized>(&'a self, data: &'a T) -> ValueReadAccess<'a, T> {
829        loop {
830            if let Some(access) = self.read(data) {
831                return access;
832            }
833            poll_fn(|cx| {
834                cx.waker().wake_by_ref();
835                Poll::<ValueReadAccess<'a, T>>::Pending
836            })
837            .await;
838        }
839    }
840
841    /// # Safety
842    pub unsafe fn read_ptr<T: ?Sized>(&'_ self, data: *const T) -> Option<ValueReadAccess<'_, T>> {
843        let state = self.0.upgrade()?;
844        let mut access = state.try_lock()?;
845        if access.state.is_read_accessible() {
846            access.unlock = false;
847            access.acquire_read_access();
848            drop(access);
849            Some(ValueReadAccess {
850                lifetime: state,
851                data: unsafe { data.as_ref() }?,
852            })
853        } else {
854            None
855        }
856    }
857
858    /// # Safety
859    pub async unsafe fn read_ptr_async<'a, T: ?Sized + 'a>(
860        &'a self,
861        data: *const T,
862    ) -> ValueReadAccess<'a, T> {
863        loop {
864            if let Some(access) = unsafe { self.read_ptr(data) } {
865                return access;
866            }
867            poll_fn(|cx| {
868                cx.waker().wake_by_ref();
869                Poll::<ValueReadAccess<'a, T>>::Pending
870            })
871            .await;
872        }
873    }
874
875    pub fn write<'a, T: ?Sized>(&'a self, data: &'a mut T) -> Option<ValueWriteAccess<'a, T>> {
876        let state = self.0.upgrade()?;
877        let mut access = state.try_lock()?;
878        if access.state.is_write_accessible() {
879            access.unlock = false;
880            access.acquire_write_access();
881            drop(access);
882            Some(ValueWriteAccess {
883                lifetime: state,
884                data,
885            })
886        } else {
887            None
888        }
889    }
890
891    pub async fn write_async<'a, T: ?Sized>(&'a self, data: &'a mut T) -> ValueWriteAccess<'a, T> {
892        unsafe { self.write_ptr_async(data as *mut T).await }
893    }
894
895    /// # Safety
896    pub unsafe fn write_ptr<T: ?Sized>(&'_ self, data: *mut T) -> Option<ValueWriteAccess<'_, T>> {
897        let state = self.0.upgrade()?;
898        let mut access = state.try_lock()?;
899        if access.state.is_write_accessible() {
900            access.unlock = false;
901            access.acquire_write_access();
902            drop(access);
903            Some(ValueWriteAccess {
904                lifetime: state,
905                data: unsafe { data.as_mut() }?,
906            })
907        } else {
908            None
909        }
910    }
911
912    /// # Safety
913    pub async unsafe fn write_ptr_async<'a, T: ?Sized + 'a>(
914        &'a self,
915        data: *mut T,
916    ) -> ValueWriteAccess<'a, T> {
917        loop {
918            if let Some(access) = unsafe { self.write_ptr(data) } {
919                return access;
920            }
921            poll_fn(|cx| {
922                cx.waker().wake_by_ref();
923                Poll::<ValueWriteAccess<'a, T>>::Pending
924            })
925            .await;
926        }
927    }
928
929    pub fn read_lock(&self) -> Option<ReadLock> {
930        let state = self.0.upgrade()?;
931        let mut access = state.lock();
932        while !access.state.is_read_accessible() {
933            std::hint::spin_loop();
934        }
935        access.unlock = false;
936        access.acquire_read_access();
937        Some(ReadLock {
938            lifetime: state.clone(),
939        })
940    }
941
942    pub async fn read_lock_async(&self) -> ReadLock {
943        loop {
944            if let Some(lock) = self.read_lock() {
945                return lock;
946            }
947            poll_fn(|cx| {
948                cx.waker().wake_by_ref();
949                Poll::<ReadLock>::Pending
950            })
951            .await;
952        }
953    }
954
955    pub fn write_lock(&self) -> Option<WriteLock> {
956        let state = self.0.upgrade()?;
957        let mut access = state.lock();
958        while !access.state.is_write_accessible() {
959            std::hint::spin_loop();
960        }
961        access.unlock = false;
962        access.acquire_write_access();
963        Some(WriteLock {
964            lifetime: state.clone(),
965        })
966    }
967
968    pub async fn write_lock_async(&self) -> WriteLock {
969        loop {
970            if let Some(lock) = self.write_lock() {
971                return lock;
972            }
973            poll_fn(|cx| {
974                cx.waker().wake_by_ref();
975                Poll::<WriteLock>::Pending
976            })
977            .await;
978        }
979    }
980
981    pub fn consume<T: ?Sized>(self, data: &'_ mut T) -> Result<ValueWriteAccess<'_, T>, Self> {
982        let state = match self.0.upgrade() {
983            Some(state) => state,
984            None => return Err(self),
985        };
986        let mut access = match state.try_lock() {
987            Some(access) => access,
988            None => return Err(self),
989        };
990        if access.state.is_write_accessible() {
991            access.unlock = false;
992            access.acquire_write_access();
993            drop(access);
994            Ok(ValueWriteAccess {
995                lifetime: state,
996                data,
997            })
998        } else {
999            Err(self)
1000        }
1001    }
1002
1003    pub async fn wait_for_read_access(&self) {
1004        loop {
1005            let Some(state) = self.0.upgrade() else {
1006                return;
1007            };
1008            if state.is_read_accessible() {
1009                return;
1010            }
1011            poll_fn(|cx| {
1012                cx.waker().wake_by_ref();
1013                Poll::<()>::Pending
1014            })
1015            .await;
1016        }
1017    }
1018
1019    pub async fn wait_for_write_access(&self) {
1020        loop {
1021            let Some(state) = self.0.upgrade() else {
1022                return;
1023            };
1024            if state.is_read_accessible() {
1025                return;
1026            }
1027            poll_fn(|cx| {
1028                cx.waker().wake_by_ref();
1029                Poll::<()>::Pending
1030            })
1031            .await;
1032        }
1033    }
1034}
1035
1036#[derive(Clone)]
1037pub struct LifetimeLazy(LifetimeWeakState);
1038
1039impl LifetimeLazy {
1040    pub fn state(&self) -> &LifetimeWeakState {
1041        &self.0
1042    }
1043
1044    pub fn tag(&self) -> usize {
1045        self.0.tag
1046    }
1047
1048    pub fn exists(&self) -> bool {
1049        self.0.upgrade().is_some()
1050    }
1051
1052    pub fn is_read_accessible(&self) -> bool {
1053        self.0
1054            .upgrade()
1055            .map(|state| state.is_read_accessible())
1056            .unwrap_or(false)
1057    }
1058
1059    pub fn is_write_accessible(&self) -> bool {
1060        self.0
1061            .upgrade()
1062            .map(|state| state.is_write_accessible())
1063            .unwrap_or(false)
1064    }
1065
1066    pub fn is_in_use(&self) -> bool {
1067        self.0
1068            .upgrade()
1069            .map(|state| state.is_in_use())
1070            .unwrap_or(false)
1071    }
1072
1073    pub fn is_owned_by(&self, other: &Lifetime) -> bool {
1074        self.0.is_owned_by(&other.0)
1075    }
1076
1077    pub fn borrow(&self) -> Option<LifetimeRef> {
1078        self.0
1079            .upgrade()?
1080            .try_lock()
1081            .filter(|access| access.state.can_read())
1082            .map(|mut access| {
1083                access.acquire_reader();
1084                LifetimeRef(self.0.clone())
1085            })
1086    }
1087
1088    pub async fn borrow_async(&self) -> LifetimeRef {
1089        loop {
1090            if let Some(lifetime_ref) = self.borrow() {
1091                return lifetime_ref;
1092            }
1093            poll_fn(|cx| {
1094                cx.waker().wake_by_ref();
1095                Poll::<LifetimeRef>::Pending
1096            })
1097            .await;
1098        }
1099    }
1100
1101    pub fn borrow_mut(&self) -> Option<LifetimeRefMut> {
1102        self.0
1103            .upgrade()?
1104            .try_lock()
1105            .filter(|access| access.state.can_write(0))
1106            .map(|mut access| {
1107                let id = access.acquire_writer();
1108                LifetimeRefMut(self.0.clone(), id)
1109            })
1110    }
1111
1112    pub async fn borrow_mut_async(&self) -> LifetimeRefMut {
1113        loop {
1114            if let Some(lifetime_ref_mut) = self.borrow_mut() {
1115                return lifetime_ref_mut;
1116            }
1117            poll_fn(|cx| {
1118                cx.waker().wake_by_ref();
1119                Poll::<LifetimeRefMut>::Pending
1120            })
1121            .await;
1122        }
1123    }
1124
1125    pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
1126        let state = self.0.upgrade()?;
1127        let mut access = state.try_lock()?;
1128        if access.state.is_read_accessible() {
1129            access.unlock = false;
1130            access.acquire_read_access();
1131            drop(access);
1132            Some(ValueReadAccess {
1133                lifetime: state,
1134                data,
1135            })
1136        } else {
1137            None
1138        }
1139    }
1140
1141    pub async fn read_async<'a, T: ?Sized>(&'a self, data: &'a T) -> ValueReadAccess<'a, T> {
1142        loop {
1143            if let Some(access) = self.read(data) {
1144                return access;
1145            }
1146            poll_fn(|cx| {
1147                cx.waker().wake_by_ref();
1148                Poll::<ValueReadAccess<'a, T>>::Pending
1149            })
1150            .await;
1151        }
1152    }
1153
1154    /// # Safety
1155    pub unsafe fn read_ptr<T: ?Sized>(&'_ self, data: *const T) -> Option<ValueReadAccess<'_, T>> {
1156        let state = self.0.upgrade()?;
1157        let mut access = state.try_lock()?;
1158        if access.state.is_read_accessible() {
1159            access.unlock = false;
1160            access.acquire_read_access();
1161            drop(access);
1162            Some(ValueReadAccess {
1163                lifetime: state,
1164                data: unsafe { data.as_ref() }?,
1165            })
1166        } else {
1167            None
1168        }
1169    }
1170
1171    /// # Safety
1172    pub async unsafe fn read_ptr_async<'a, T: ?Sized + 'a>(
1173        &'a self,
1174        data: *const T,
1175    ) -> ValueReadAccess<'a, T> {
1176        loop {
1177            if let Some(access) = unsafe { self.read_ptr(data) } {
1178                return access;
1179            }
1180            poll_fn(|cx| {
1181                cx.waker().wake_by_ref();
1182                Poll::<ValueReadAccess<'a, T>>::Pending
1183            })
1184            .await;
1185        }
1186    }
1187
1188    pub fn write<'a, T: ?Sized>(&'a self, data: &'a mut T) -> Option<ValueWriteAccess<'a, T>> {
1189        let state = self.0.upgrade()?;
1190        let mut access = state.try_lock()?;
1191        if access.state.is_write_accessible() {
1192            access.unlock = false;
1193            access.acquire_write_access();
1194            drop(access);
1195            Some(ValueWriteAccess {
1196                lifetime: state,
1197                data,
1198            })
1199        } else {
1200            None
1201        }
1202    }
1203
1204    pub async fn write_async<'a, T: ?Sized>(&'a self, data: &'a mut T) -> ValueWriteAccess<'a, T> {
1205        unsafe { self.write_ptr_async(data as *mut T).await }
1206    }
1207
1208    /// # Safety
1209    pub unsafe fn write_ptr<T: ?Sized>(&'_ self, data: *mut T) -> Option<ValueWriteAccess<'_, T>> {
1210        let state = self.0.upgrade()?;
1211        let mut access = state.try_lock()?;
1212        if access.state.is_write_accessible() {
1213            access.unlock = false;
1214            access.acquire_write_access();
1215            drop(access);
1216            Some(ValueWriteAccess {
1217                lifetime: state,
1218                data: unsafe { data.as_mut() }?,
1219            })
1220        } else {
1221            None
1222        }
1223    }
1224
1225    /// # Safety
1226    pub async unsafe fn write_ptr_async<'a, T: ?Sized + 'a>(
1227        &'a self,
1228        data: *mut T,
1229    ) -> ValueWriteAccess<'a, T> {
1230        loop {
1231            if let Some(access) = unsafe { self.write_ptr(data) } {
1232                return access;
1233            }
1234            poll_fn(|cx| {
1235                cx.waker().wake_by_ref();
1236                Poll::<ValueWriteAccess<'a, T>>::Pending
1237            })
1238            .await;
1239        }
1240    }
1241
1242    pub fn consume<T: ?Sized>(self, data: &'_ mut T) -> Result<ValueWriteAccess<'_, T>, Self> {
1243        let state = match self.0.upgrade() {
1244            Some(state) => state,
1245            None => return Err(self),
1246        };
1247        let mut access = match state.try_lock() {
1248            Some(access) => access,
1249            None => return Err(self),
1250        };
1251        if access.state.is_write_accessible() {
1252            access.unlock = false;
1253            access.acquire_write_access();
1254            drop(access);
1255            Ok(ValueWriteAccess {
1256                lifetime: state,
1257                data,
1258            })
1259        } else {
1260            Err(self)
1261        }
1262    }
1263
1264    pub async fn wait_for_read_access(&self) {
1265        loop {
1266            let Some(state) = self.0.upgrade() else {
1267                return;
1268            };
1269            if state.is_read_accessible() {
1270                return;
1271            }
1272            poll_fn(|cx| {
1273                cx.waker().wake_by_ref();
1274                Poll::<()>::Pending
1275            })
1276            .await;
1277        }
1278    }
1279
1280    pub async fn wait_for_write_access(&self) {
1281        loop {
1282            let Some(state) = self.0.upgrade() else {
1283                return;
1284            };
1285            if state.is_read_accessible() {
1286                return;
1287            }
1288            poll_fn(|cx| {
1289                cx.waker().wake_by_ref();
1290                Poll::<()>::Pending
1291            })
1292            .await;
1293        }
1294    }
1295}
1296
1297pub struct ValueReadAccess<'a, T: 'a + ?Sized> {
1298    lifetime: LifetimeState,
1299    data: &'a T,
1300}
1301
1302impl<T: ?Sized> Drop for ValueReadAccess<'_, T> {
1303    fn drop(&mut self) {
1304        unsafe { self.lifetime.lock_unchecked().release_read_access() };
1305    }
1306}
1307
1308impl<'a, T: ?Sized> ValueReadAccess<'a, T> {
1309    /// # Safety
1310    pub unsafe fn new_raw(data: &'a T, lifetime: LifetimeState) -> Self {
1311        Self { lifetime, data }
1312    }
1313}
1314
1315impl<T: ?Sized> Deref for ValueReadAccess<'_, T> {
1316    type Target = T;
1317
1318    fn deref(&self) -> &Self::Target {
1319        self.data
1320    }
1321}
1322
1323impl<'a, T: ?Sized> ValueReadAccess<'a, T> {
1324    pub fn remap<U>(
1325        self,
1326        f: impl FnOnce(&T) -> Option<&U>,
1327    ) -> Result<ValueReadAccess<'a, U>, Self> {
1328        if let Some(data) = f(self.data) {
1329            Ok(ValueReadAccess {
1330                lifetime: self.lifetime.clone(),
1331                data,
1332            })
1333        } else {
1334            Err(self)
1335        }
1336    }
1337}
1338
1339pub struct ValueWriteAccess<'a, T: 'a + ?Sized> {
1340    lifetime: LifetimeState,
1341    data: &'a mut T,
1342}
1343
1344impl<T: ?Sized> Drop for ValueWriteAccess<'_, T> {
1345    fn drop(&mut self) {
1346        unsafe { self.lifetime.lock_unchecked().release_write_access() };
1347    }
1348}
1349
1350impl<'a, T: ?Sized> ValueWriteAccess<'a, T> {
1351    /// # Safety
1352    pub unsafe fn new_raw(data: &'a mut T, lifetime: LifetimeState) -> Self {
1353        Self { lifetime, data }
1354    }
1355}
1356
1357impl<T: ?Sized> Deref for ValueWriteAccess<'_, T> {
1358    type Target = T;
1359
1360    fn deref(&self) -> &Self::Target {
1361        self.data
1362    }
1363}
1364
1365impl<T: ?Sized> DerefMut for ValueWriteAccess<'_, T> {
1366    fn deref_mut(&mut self) -> &mut Self::Target {
1367        self.data
1368    }
1369}
1370
1371impl<'a, T: ?Sized> ValueWriteAccess<'a, T> {
1372    pub fn remap<U>(
1373        self,
1374        f: impl FnOnce(&mut T) -> Option<&mut U>,
1375    ) -> Result<ValueWriteAccess<'a, U>, Self> {
1376        if let Some(data) = f(unsafe { std::mem::transmute::<&mut T, &'a mut T>(&mut *self.data) })
1377        {
1378            Ok(ValueWriteAccess {
1379                lifetime: self.lifetime.clone(),
1380                data,
1381            })
1382        } else {
1383            Err(self)
1384        }
1385    }
1386}
1387
1388pub struct ReadLock {
1389    lifetime: LifetimeState,
1390}
1391
1392impl Drop for ReadLock {
1393    fn drop(&mut self) {
1394        unsafe { self.lifetime.lock_unchecked().release_read_access() };
1395    }
1396}
1397
1398impl ReadLock {
1399    /// # Safety
1400    pub unsafe fn new_raw(lifetime: LifetimeState) -> Self {
1401        Self { lifetime }
1402    }
1403
1404    pub fn using<R>(self, f: impl FnOnce() -> R) -> R {
1405        let result = f();
1406        drop(self);
1407        result
1408    }
1409}
1410
1411pub struct WriteLock {
1412    lifetime: LifetimeState,
1413}
1414
1415impl Drop for WriteLock {
1416    fn drop(&mut self) {
1417        unsafe { self.lifetime.lock_unchecked().release_write_access() };
1418    }
1419}
1420
1421impl WriteLock {
1422    /// # Safety
1423    pub unsafe fn new_raw(lifetime: LifetimeState) -> Self {
1424        Self { lifetime }
1425    }
1426
1427    pub fn using<R>(self, f: impl FnOnce() -> R) -> R {
1428        let result = f();
1429        drop(self);
1430        result
1431    }
1432}
1433
1434#[cfg(test)]
1435mod tests {
1436    use super::*;
1437    use std::thread::*;
1438
1439    fn is_async<T: Send + Sync + ?Sized>() {
1440        println!("{} is async!", std::any::type_name::<T>());
1441    }
1442
1443    #[test]
1444    fn test_lifetimes() {
1445        is_async::<Lifetime>();
1446        is_async::<LifetimeRef>();
1447        is_async::<LifetimeRefMut>();
1448        is_async::<LifetimeLazy>();
1449
1450        let mut value = 0usize;
1451        let lifetime_ref = {
1452            let lifetime = Lifetime::default();
1453            assert!(lifetime.state().can_read());
1454            assert!(lifetime.state().can_write(0));
1455            assert!(lifetime.state().is_read_accessible());
1456            assert!(lifetime.state().is_write_accessible());
1457            let lifetime_lazy = lifetime.lazy();
1458            assert!(lifetime_lazy.read(&42).is_some());
1459            assert!(lifetime_lazy.write(&mut 42).is_some());
1460            {
1461                let access = lifetime.read(&value).unwrap();
1462                assert_eq!(*access, value);
1463            }
1464            {
1465                let mut access = lifetime.write(&mut value).unwrap();
1466                *access = 42;
1467                assert_eq!(*access, 42);
1468            }
1469            {
1470                let lifetime_ref = lifetime.borrow().unwrap();
1471                assert!(lifetime.state().can_read());
1472                assert!(!lifetime.state().can_write(0));
1473                assert!(lifetime_ref.exists());
1474                assert!(lifetime_ref.is_owned_by(&lifetime));
1475                assert!(lifetime.borrow().is_some());
1476                assert!(lifetime.borrow_mut().is_none());
1477                assert!(lifetime_lazy.read(&42).is_some());
1478                assert!(lifetime_lazy.write(&mut 42).is_some());
1479                {
1480                    let access = lifetime_ref.read(&value).unwrap();
1481                    assert_eq!(*access, 42);
1482                    assert!(lifetime_lazy.read(&42).is_none());
1483                    assert!(lifetime_lazy.write(&mut 42).is_none());
1484                }
1485                let lifetime_ref2 = lifetime_ref.borrow().unwrap();
1486                {
1487                    let access = lifetime_ref2.read(&value).unwrap();
1488                    assert_eq!(*access, 42);
1489                    assert!(lifetime_lazy.read(&42).is_none());
1490                    assert!(lifetime_lazy.write(&mut 42).is_none());
1491                }
1492            }
1493            {
1494                let lifetime_ref_mut = lifetime.borrow_mut().unwrap();
1495                assert_eq!(lifetime.state().writer_depth(), 1);
1496                assert!(!lifetime.state().can_read());
1497                assert!(!lifetime.state().can_write(0));
1498                assert!(lifetime_ref_mut.exists());
1499                assert!(lifetime_ref_mut.is_owned_by(&lifetime));
1500                assert!(lifetime.borrow().is_none());
1501                assert!(lifetime.borrow_mut().is_none());
1502                assert!(lifetime_lazy.read(&42).is_some());
1503                assert!(lifetime_lazy.write(&mut 42).is_some());
1504                {
1505                    let mut access = lifetime_ref_mut.write(&mut value).unwrap();
1506                    *access = 7;
1507                    assert_eq!(*access, 7);
1508                    assert!(lifetime_lazy.read(&42).is_none());
1509                    assert!(lifetime_lazy.write(&mut 42).is_none());
1510                }
1511                let lifetime_ref_mut2 = lifetime_ref_mut.borrow_mut().unwrap();
1512                assert!(lifetime_lazy.read(&42).is_some());
1513                assert!(lifetime_lazy.write(&mut 42).is_some());
1514                {
1515                    assert_eq!(lifetime.state().writer_depth(), 2);
1516                    assert!(lifetime.borrow().is_none());
1517                    assert!(lifetime_ref_mut.borrow().is_none());
1518                    assert!(lifetime.borrow_mut().is_none());
1519                    assert!(lifetime_ref_mut.borrow_mut().is_none());
1520                    let mut access = lifetime_ref_mut2.write(&mut value).unwrap();
1521                    *access = 42;
1522                    assert_eq!(*access, 42);
1523                    assert!(lifetime.read(&42).is_none());
1524                    assert!(lifetime_ref_mut.read(&42).is_none());
1525                    assert!(lifetime.write(&mut 42).is_none());
1526                    assert!(lifetime_ref_mut.write(&mut 42).is_none());
1527                    assert!(lifetime_lazy.read(&42).is_none());
1528                    assert!(lifetime_lazy.write(&mut 42).is_none());
1529                    assert!(lifetime_lazy.read(&42).is_none());
1530                    assert!(lifetime_lazy.write(&mut 42).is_none());
1531                }
1532            }
1533            assert_eq!(lifetime.state().writer_depth(), 0);
1534            lifetime.borrow().unwrap()
1535        };
1536        assert!(!lifetime_ref.exists());
1537        assert_eq!(value, 42);
1538    }
1539
1540    #[test]
1541    fn test_lifetimes_multithread() {
1542        let lifetime = Lifetime::default();
1543        let lifetime_ref = lifetime.borrow().unwrap();
1544        assert!(lifetime_ref.exists());
1545        assert!(lifetime_ref.is_owned_by(&lifetime));
1546        drop(lifetime);
1547        assert!(!lifetime_ref.exists());
1548        let lifetime = Lifetime::default();
1549        let lifetime = spawn(move || {
1550            let value_ref = lifetime.borrow().unwrap();
1551            assert!(value_ref.exists());
1552            assert!(value_ref.is_owned_by(&lifetime));
1553            lifetime
1554        })
1555        .join()
1556        .unwrap();
1557        assert!(!lifetime_ref.exists());
1558        assert!(!lifetime_ref.is_owned_by(&lifetime));
1559    }
1560
1561    #[test]
1562    fn test_lifetimes_move_invalidation() {
1563        let lifetime = Lifetime::default();
1564        let lifetime_ref = lifetime.borrow().unwrap();
1565        assert_eq!(lifetime_ref.tag(), lifetime.tag());
1566        assert!(lifetime_ref.exists());
1567        let lifetime_ref2 = lifetime_ref;
1568        assert_eq!(lifetime_ref2.tag(), lifetime.tag());
1569        assert!(lifetime_ref2.exists());
1570        let lifetime = Box::new(lifetime);
1571        assert_ne!(lifetime_ref2.tag(), lifetime.tag());
1572        assert!(!lifetime_ref2.exists());
1573        let lifetime = *lifetime;
1574        assert_ne!(lifetime_ref2.tag(), lifetime.tag());
1575        assert!(!lifetime_ref2.exists());
1576    }
1577
1578    #[pollster::test]
1579    async fn test_lifetime_async() {
1580        let mut value = 42usize;
1581        let lifetime = Lifetime::default();
1582        assert_eq!(*lifetime.read_async(&value).await, 42);
1583        {
1584            let lifetime_ref = lifetime.borrow_async().await;
1585            {
1586                let access = lifetime_ref.read_async(&value).await;
1587                assert_eq!(*access, 42);
1588            }
1589        }
1590        {
1591            let lifetime_ref_mut = lifetime.borrow_mut_async().await;
1592            {
1593                let mut access = lifetime_ref_mut.write_async(&mut value).await;
1594                *access = 7;
1595                assert_eq!(*access, 7);
1596            }
1597            assert_eq!(*lifetime.read_async(&value).await, 7);
1598        }
1599        {
1600            let mut access = lifetime.write_async(&mut value).await;
1601            *access = 84;
1602        }
1603        {
1604            let access = lifetime.read_async(&value).await;
1605            assert_eq!(*access, 84);
1606        }
1607    }
1608}