intuicio_data/
lifetime.rs

1use std::{
2    ops::{Deref, DerefMut},
3    sync::{
4        Arc, Weak,
5        atomic::{AtomicBool, AtomicUsize, Ordering},
6    },
7};
8
9#[derive(Default)]
10struct LifetimeStateInner {
11    locked: AtomicBool,
12    readers: AtomicUsize,
13    writer: AtomicUsize,
14    read_access: AtomicUsize,
15    write_access: AtomicBool,
16    tag: AtomicUsize,
17}
18
19#[derive(Default, Clone)]
20pub struct LifetimeState {
21    inner: Arc<LifetimeStateInner>,
22}
23
24impl LifetimeState {
25    pub fn can_read(&self) -> bool {
26        self.inner.writer.load(Ordering::Acquire) == 0
27    }
28
29    pub fn can_write(&self, id: usize) -> bool {
30        self.inner.writer.load(Ordering::Acquire) == id
31            && self.inner.readers.load(Ordering::Acquire) == 0
32    }
33
34    pub fn writer_depth(&self) -> usize {
35        self.inner.writer.load(Ordering::Acquire)
36    }
37
38    pub fn is_read_accessible(&self) -> bool {
39        !self.inner.write_access.load(Ordering::Acquire)
40    }
41
42    pub fn is_write_accessible(&self) -> bool {
43        !self.inner.write_access.load(Ordering::Acquire)
44            && self.inner.read_access.load(Ordering::Acquire) == 0
45    }
46
47    pub fn is_in_use(&self) -> bool {
48        self.inner.read_access.load(Ordering::Acquire) > 0
49            || self.inner.write_access.load(Ordering::Acquire)
50    }
51
52    pub fn is_locked(&self) -> bool {
53        self.inner.locked.load(Ordering::Acquire)
54    }
55
56    pub fn try_lock(&self) -> Option<LifetimeStateAccess> {
57        if !self.inner.locked.load(Ordering::Acquire) {
58            self.inner.locked.store(true, Ordering::Release);
59            Some(LifetimeStateAccess {
60                state: self,
61                unlock: true,
62            })
63        } else {
64            None
65        }
66    }
67
68    pub fn lock(&self) -> LifetimeStateAccess {
69        while self.inner.locked.load(Ordering::Acquire) {
70            std::hint::spin_loop();
71        }
72        self.inner.locked.store(true, Ordering::Release);
73        LifetimeStateAccess {
74            state: self,
75            unlock: true,
76        }
77    }
78
79    /// # Safety
80    pub unsafe fn lock_unchecked(&self) -> LifetimeStateAccess {
81        LifetimeStateAccess {
82            state: self,
83            unlock: true,
84        }
85    }
86
87    /// # Safety
88    pub unsafe fn update_tag(&self, tag: &Lifetime) {
89        let tag = tag as *const Lifetime as usize;
90        self.inner.tag.store(tag, Ordering::Release);
91    }
92
93    pub fn tag(&self) -> usize {
94        self.inner.tag.load(Ordering::Acquire)
95    }
96
97    pub fn downgrade(&self) -> LifetimeWeakState {
98        LifetimeWeakState {
99            inner: Arc::downgrade(&self.inner),
100            tag: self.inner.tag.load(Ordering::Acquire),
101        }
102    }
103}
104
105#[derive(Clone)]
106pub struct LifetimeWeakState {
107    inner: Weak<LifetimeStateInner>,
108    tag: usize,
109}
110
111impl LifetimeWeakState {
112    /// # Safety
113    pub unsafe fn upgrade_unchecked(&self) -> Option<LifetimeState> {
114        Some(LifetimeState {
115            inner: self.inner.upgrade()?,
116        })
117    }
118
119    pub fn upgrade(&self) -> Option<LifetimeState> {
120        let inner = self.inner.upgrade()?;
121        (inner.tag.load(Ordering::Acquire) == self.tag).then_some(LifetimeState { inner })
122    }
123
124    pub fn is_owned_by(&self, state: &LifetimeState) -> bool {
125        Arc::downgrade(&state.inner).ptr_eq(&self.inner)
126    }
127}
128
129pub struct LifetimeStateAccess<'a> {
130    state: &'a LifetimeState,
131    unlock: bool,
132}
133
134impl Drop for LifetimeStateAccess<'_> {
135    fn drop(&mut self) {
136        if self.unlock {
137            self.state.inner.locked.store(false, Ordering::Release);
138        }
139    }
140}
141
142impl LifetimeStateAccess<'_> {
143    pub fn state(&self) -> &LifetimeState {
144        self.state
145    }
146
147    pub fn unlock(&mut self, value: bool) {
148        self.unlock = value;
149    }
150
151    pub fn acquire_reader(&mut self) {
152        let v = self.state.inner.readers.load(Ordering::Acquire) + 1;
153        self.state.inner.readers.store(v, Ordering::Release);
154    }
155
156    pub fn release_reader(&mut self) {
157        let v = self
158            .state
159            .inner
160            .readers
161            .load(Ordering::Acquire)
162            .saturating_sub(1);
163        self.state.inner.readers.store(v, Ordering::Release);
164    }
165
166    #[must_use]
167    pub fn acquire_writer(&mut self) -> usize {
168        let v = self.state.inner.writer.load(Ordering::Acquire) + 1;
169        self.state.inner.writer.store(v, Ordering::Release);
170        v
171    }
172
173    pub fn release_writer(&mut self, id: usize) {
174        let v = self.state.inner.writer.load(Ordering::Acquire);
175        if id <= v {
176            self.state
177                .inner
178                .writer
179                .store(id.saturating_sub(1), Ordering::Release);
180        }
181    }
182
183    pub fn acquire_read_access(&mut self) {
184        let v = self.state.inner.read_access.load(Ordering::Acquire) + 1;
185        self.state.inner.read_access.store(v, Ordering::Release);
186    }
187
188    pub fn release_read_access(&mut self) {
189        let v = self
190            .state
191            .inner
192            .read_access
193            .load(Ordering::Acquire)
194            .saturating_sub(1);
195        self.state.inner.read_access.store(v, Ordering::Release);
196    }
197
198    pub fn acquire_write_access(&mut self) {
199        self.state.inner.write_access.store(true, Ordering::Release);
200    }
201
202    pub fn release_write_access(&mut self) {
203        self.state
204            .inner
205            .write_access
206            .store(false, Ordering::Release);
207    }
208}
209
210#[derive(Default)]
211pub struct Lifetime(LifetimeState);
212
213impl Lifetime {
214    pub fn state(&self) -> &LifetimeState {
215        unsafe { self.0.update_tag(self) };
216        &self.0
217    }
218
219    pub fn update_tag(&self) {
220        unsafe { self.0.update_tag(self) };
221    }
222
223    pub fn tag(&self) -> usize {
224        unsafe { self.0.update_tag(self) };
225        self.0.tag()
226    }
227
228    pub fn borrow(&self) -> Option<LifetimeRef> {
229        unsafe { self.0.update_tag(self) };
230        self.0
231            .try_lock()
232            .filter(|access| access.state.can_read())
233            .map(|mut access| {
234                access.acquire_reader();
235                LifetimeRef(self.0.downgrade())
236            })
237    }
238
239    pub fn borrow_mut(&self) -> Option<LifetimeRefMut> {
240        unsafe { self.0.update_tag(self) };
241        self.0
242            .try_lock()
243            .filter(|access| access.state.can_write(0))
244            .map(|mut access| {
245                let id = access.acquire_writer();
246                LifetimeRefMut(self.0.downgrade(), id)
247            })
248    }
249
250    pub fn lazy(&self) -> LifetimeLazy {
251        unsafe { self.0.update_tag(self) };
252        LifetimeLazy(self.0.downgrade())
253    }
254
255    pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
256        unsafe { self.0.update_tag(self) };
257        self.0
258            .try_lock()
259            .filter(|access| access.state.is_read_accessible())
260            .map(|mut access| {
261                access.unlock = false;
262                access.acquire_read_access();
263                ValueReadAccess {
264                    lifetime: self.0.clone(),
265                    data,
266                }
267            })
268    }
269
270    /// # Safety
271    pub unsafe fn read_ptr<T: ?Sized>(&self, data: *const T) -> Option<ValueReadAccess<T>> {
272        unsafe { self.0.update_tag(self) };
273        self.0
274            .try_lock()
275            .filter(|access| access.state.is_read_accessible())
276            .and_then(|mut access| {
277                access.unlock = false;
278                access.acquire_read_access();
279                Some(ValueReadAccess {
280                    lifetime: self.0.clone(),
281                    data: unsafe { data.as_ref() }?,
282                })
283            })
284    }
285
286    pub fn write<'a, T: ?Sized>(&'a self, data: &'a mut T) -> Option<ValueWriteAccess<'a, T>> {
287        unsafe { self.0.update_tag(self) };
288        self.0
289            .try_lock()
290            .filter(|access| access.state.is_write_accessible())
291            .map(|mut access| {
292                access.unlock = false;
293                access.acquire_write_access();
294                ValueWriteAccess {
295                    lifetime: self.0.clone(),
296                    data,
297                }
298            })
299    }
300
301    /// # Safety
302    pub unsafe fn write_ptr<T: ?Sized>(&self, data: *mut T) -> Option<ValueWriteAccess<T>> {
303        unsafe { self.0.update_tag(self) };
304        self.0
305            .try_lock()
306            .filter(|access| access.state.is_write_accessible())
307            .and_then(|mut access| {
308                access.unlock = false;
309                access.acquire_write_access();
310                Some(ValueWriteAccess {
311                    lifetime: self.0.clone(),
312                    data: unsafe { data.as_mut() }?,
313                })
314            })
315    }
316
317    pub fn read_lock(&self) -> ReadLock {
318        unsafe { self.0.update_tag(self) };
319        let mut access = self.0.lock();
320        while !access.state.is_read_accessible() {
321            std::hint::spin_loop();
322        }
323        access.unlock = false;
324        access.acquire_read_access();
325        ReadLock {
326            lifetime: self.0.clone(),
327        }
328    }
329
330    pub fn write_lock(&self) -> WriteLock {
331        unsafe { self.0.update_tag(self) };
332        let mut access = self.0.lock();
333        while !access.state.is_write_accessible() {
334            std::hint::spin_loop();
335        }
336        access.unlock = false;
337        access.acquire_write_access();
338        WriteLock {
339            lifetime: self.0.clone(),
340        }
341    }
342}
343
344pub struct LifetimeRef(LifetimeWeakState);
345
346impl Drop for LifetimeRef {
347    fn drop(&mut self) {
348        if let Some(owner) = unsafe { self.0.upgrade_unchecked() } {
349            if let Some(mut access) = owner.try_lock() {
350                access.release_reader();
351            }
352        }
353    }
354}
355
356impl LifetimeRef {
357    pub fn state(&self) -> &LifetimeWeakState {
358        &self.0
359    }
360
361    pub fn tag(&self) -> usize {
362        self.0.tag
363    }
364
365    pub fn exists(&self) -> bool {
366        self.0.upgrade().is_some()
367    }
368
369    pub fn can_read(&self) -> bool {
370        self.0
371            .upgrade()
372            .map(|state| state.can_read())
373            .unwrap_or(false)
374    }
375
376    pub fn is_read_accessible(&self) -> bool {
377        self.0
378            .upgrade()
379            .map(|state| state.is_read_accessible())
380            .unwrap_or(false)
381    }
382
383    pub fn is_in_use(&self) -> bool {
384        self.0
385            .upgrade()
386            .map(|state| state.is_in_use())
387            .unwrap_or(false)
388    }
389
390    pub fn is_owned_by(&self, other: &Lifetime) -> bool {
391        self.0.is_owned_by(&other.0)
392    }
393
394    pub fn borrow(&self) -> Option<LifetimeRef> {
395        self.0
396            .upgrade()?
397            .try_lock()
398            .filter(|access| access.state.can_read())
399            .map(|mut access| {
400                access.acquire_reader();
401                LifetimeRef(self.0.clone())
402            })
403    }
404
405    pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
406        let state = self.0.upgrade()?;
407        let mut access = state.try_lock()?;
408        if access.state.is_read_accessible() {
409            access.unlock = false;
410            access.acquire_read_access();
411            drop(access);
412            Some(ValueReadAccess {
413                lifetime: state,
414                data,
415            })
416        } else {
417            None
418        }
419    }
420
421    /// # Safety
422    pub unsafe fn read_ptr<T: ?Sized>(&self, data: *const T) -> Option<ValueReadAccess<T>> {
423        let state = self.0.upgrade()?;
424        let mut access = state.try_lock()?;
425        if access.state.is_read_accessible() {
426            access.unlock = false;
427            access.acquire_read_access();
428            drop(access);
429            Some(ValueReadAccess {
430                lifetime: state,
431                data: unsafe { data.as_ref() }?,
432            })
433        } else {
434            None
435        }
436    }
437
438    pub fn read_lock(&self) -> Option<ReadLock> {
439        let state = self.0.upgrade()?;
440        let mut access = state.lock();
441        while !access.state.is_read_accessible() {
442            std::hint::spin_loop();
443        }
444        access.unlock = false;
445        access.acquire_read_access();
446        Some(ReadLock {
447            lifetime: state.clone(),
448        })
449    }
450
451    pub fn consume<T: ?Sized>(self, data: &T) -> Result<ValueReadAccess<T>, Self> {
452        let state = match self.0.upgrade() {
453            Some(state) => state,
454            None => return Err(self),
455        };
456        let mut access = match state.try_lock() {
457            Some(access) => access,
458            None => return Err(self),
459        };
460        if access.state.is_read_accessible() {
461            access.unlock = false;
462            access.acquire_read_access();
463            drop(access);
464            Ok(ValueReadAccess {
465                lifetime: state,
466                data,
467            })
468        } else {
469            Err(self)
470        }
471    }
472}
473
474pub struct LifetimeRefMut(LifetimeWeakState, usize);
475
476impl Drop for LifetimeRefMut {
477    fn drop(&mut self) {
478        if let Some(state) = unsafe { self.0.upgrade_unchecked() } {
479            if let Some(mut access) = state.try_lock() {
480                access.release_writer(self.1);
481            }
482        }
483    }
484}
485
486impl LifetimeRefMut {
487    pub fn state(&self) -> &LifetimeWeakState {
488        &self.0
489    }
490
491    pub fn tag(&self) -> usize {
492        self.0.tag
493    }
494
495    pub fn depth(&self) -> usize {
496        self.1
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 can_write(&self) -> bool {
511        self.0
512            .upgrade()
513            .map(|state| state.can_write(self.1))
514            .unwrap_or(false)
515    }
516
517    pub fn is_read_accessible(&self) -> bool {
518        self.0
519            .upgrade()
520            .map(|state| state.is_read_accessible())
521            .unwrap_or(false)
522    }
523
524    pub fn is_write_accessible(&self) -> bool {
525        self.0
526            .upgrade()
527            .map(|state| state.is_write_accessible())
528            .unwrap_or(false)
529    }
530
531    pub fn is_in_use(&self) -> bool {
532        self.0
533            .upgrade()
534            .map(|state| state.is_in_use())
535            .unwrap_or(false)
536    }
537
538    pub fn is_owned_by(&self, other: &Lifetime) -> bool {
539        self.0.is_owned_by(&other.0)
540    }
541
542    pub fn borrow(&self) -> Option<LifetimeRef> {
543        self.0
544            .upgrade()?
545            .try_lock()
546            .filter(|access| access.state.can_read())
547            .map(|mut access| {
548                access.acquire_reader();
549                LifetimeRef(self.0.clone())
550            })
551    }
552
553    pub fn borrow_mut(&self) -> Option<LifetimeRefMut> {
554        self.0
555            .upgrade()?
556            .try_lock()
557            .filter(|access| access.state.can_write(self.1))
558            .map(|mut access| {
559                let id = access.acquire_writer();
560                LifetimeRefMut(self.0.clone(), id)
561            })
562    }
563
564    pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
565        let state = self.0.upgrade()?;
566        let mut access = state.try_lock()?;
567        if access.state.is_read_accessible() {
568            access.unlock = false;
569            access.acquire_read_access();
570            drop(access);
571            Some(ValueReadAccess {
572                lifetime: state,
573                data,
574            })
575        } else {
576            None
577        }
578    }
579
580    /// # Safety
581    pub unsafe fn read_ptr<T: ?Sized>(&self, data: *const T) -> Option<ValueReadAccess<T>> {
582        let state = self.0.upgrade()?;
583        let mut access = state.try_lock()?;
584        if access.state.is_read_accessible() {
585            access.unlock = false;
586            access.acquire_read_access();
587            drop(access);
588            Some(ValueReadAccess {
589                lifetime: state,
590                data: unsafe { data.as_ref() }?,
591            })
592        } else {
593            None
594        }
595    }
596
597    pub fn write<'a, T: ?Sized>(&'a self, data: &'a mut T) -> Option<ValueWriteAccess<'a, T>> {
598        let state = self.0.upgrade()?;
599        let mut access = state.try_lock()?;
600        if access.state.is_write_accessible() {
601            access.unlock = false;
602            access.acquire_write_access();
603            drop(access);
604            Some(ValueWriteAccess {
605                lifetime: state,
606                data,
607            })
608        } else {
609            None
610        }
611    }
612
613    /// # Safety
614    pub unsafe fn write_ptr<T: ?Sized>(&self, data: *mut T) -> Option<ValueWriteAccess<T>> {
615        let state = self.0.upgrade()?;
616        let mut access = state.try_lock()?;
617        if access.state.is_write_accessible() {
618            access.unlock = false;
619            access.acquire_write_access();
620            drop(access);
621            Some(ValueWriteAccess {
622                lifetime: state,
623                data: unsafe { data.as_mut() }?,
624            })
625        } else {
626            None
627        }
628    }
629
630    pub fn read_lock(&self) -> Option<ReadLock> {
631        let state = self.0.upgrade()?;
632        let mut access = state.lock();
633        while !access.state.is_read_accessible() {
634            std::hint::spin_loop();
635        }
636        access.unlock = false;
637        access.acquire_read_access();
638        Some(ReadLock {
639            lifetime: state.clone(),
640        })
641    }
642
643    pub fn write_lock(&self) -> Option<WriteLock> {
644        let state = self.0.upgrade()?;
645        let mut access = state.lock();
646        while !access.state.is_write_accessible() {
647            std::hint::spin_loop();
648        }
649        access.unlock = false;
650        access.acquire_write_access();
651        Some(WriteLock {
652            lifetime: state.clone(),
653        })
654    }
655
656    pub fn consume<T: ?Sized>(self, data: &mut T) -> Result<ValueWriteAccess<T>, Self> {
657        let state = match self.0.upgrade() {
658            Some(state) => state,
659            None => return Err(self),
660        };
661        let mut access = match state.try_lock() {
662            Some(access) => access,
663            None => return Err(self),
664        };
665        if access.state.is_write_accessible() {
666            access.unlock = false;
667            access.acquire_write_access();
668            drop(access);
669            Ok(ValueWriteAccess {
670                lifetime: state,
671                data,
672            })
673        } else {
674            Err(self)
675        }
676    }
677}
678
679#[derive(Clone)]
680pub struct LifetimeLazy(LifetimeWeakState);
681
682impl LifetimeLazy {
683    pub fn state(&self) -> &LifetimeWeakState {
684        &self.0
685    }
686
687    pub fn tag(&self) -> usize {
688        self.0.tag
689    }
690
691    pub fn exists(&self) -> bool {
692        self.0.upgrade().is_some()
693    }
694
695    pub fn is_read_accessible(&self) -> bool {
696        self.0
697            .upgrade()
698            .map(|state| state.is_read_accessible())
699            .unwrap_or(false)
700    }
701
702    pub fn is_write_accessible(&self) -> bool {
703        self.0
704            .upgrade()
705            .map(|state| state.is_write_accessible())
706            .unwrap_or(false)
707    }
708
709    pub fn is_in_use(&self) -> bool {
710        self.0
711            .upgrade()
712            .map(|state| state.is_in_use())
713            .unwrap_or(false)
714    }
715
716    pub fn is_owned_by(&self, other: &Lifetime) -> bool {
717        self.0.is_owned_by(&other.0)
718    }
719
720    pub fn borrow(&self) -> Option<LifetimeRef> {
721        self.0
722            .upgrade()?
723            .try_lock()
724            .filter(|access| access.state.can_read())
725            .map(|mut access| {
726                access.acquire_reader();
727                LifetimeRef(self.0.clone())
728            })
729    }
730
731    pub fn borrow_mut(&self) -> Option<LifetimeRefMut> {
732        self.0
733            .upgrade()?
734            .try_lock()
735            .filter(|access| access.state.can_write(0))
736            .map(|mut access| {
737                let id = access.acquire_writer();
738                LifetimeRefMut(self.0.clone(), id)
739            })
740    }
741
742    pub fn read<'a, T: ?Sized>(&'a self, data: &'a T) -> Option<ValueReadAccess<'a, T>> {
743        let state = self.0.upgrade()?;
744        let mut access = state.try_lock()?;
745        if access.state.is_read_accessible() {
746            access.unlock = false;
747            access.acquire_read_access();
748            drop(access);
749            Some(ValueReadAccess {
750                lifetime: state,
751                data,
752            })
753        } else {
754            None
755        }
756    }
757
758    /// # Safety
759    pub unsafe fn read_ptr<T: ?Sized>(&self, data: *const T) -> Option<ValueReadAccess<T>> {
760        let state = self.0.upgrade()?;
761        let mut access = state.try_lock()?;
762        if access.state.is_read_accessible() {
763            access.unlock = false;
764            access.acquire_read_access();
765            drop(access);
766            Some(ValueReadAccess {
767                lifetime: state,
768                data: unsafe { data.as_ref() }?,
769            })
770        } else {
771            None
772        }
773    }
774
775    pub fn write<'a, T: ?Sized>(&'a self, data: &'a mut T) -> Option<ValueWriteAccess<'a, T>> {
776        let state = self.0.upgrade()?;
777        let mut access = state.try_lock()?;
778        if access.state.is_write_accessible() {
779            access.unlock = false;
780            access.acquire_write_access();
781            drop(access);
782            Some(ValueWriteAccess {
783                lifetime: state,
784                data,
785            })
786        } else {
787            None
788        }
789    }
790
791    /// # Safety
792    pub unsafe fn write_ptr<T: ?Sized>(&self, data: *mut T) -> Option<ValueWriteAccess<T>> {
793        let state = self.0.upgrade()?;
794        let mut access = state.try_lock()?;
795        if access.state.is_write_accessible() {
796            access.unlock = false;
797            access.acquire_write_access();
798            drop(access);
799            Some(ValueWriteAccess {
800                lifetime: state,
801                data: unsafe { data.as_mut() }?,
802            })
803        } else {
804            None
805        }
806    }
807
808    pub fn consume<T: ?Sized>(self, data: &mut T) -> Result<ValueWriteAccess<T>, Self> {
809        let state = match self.0.upgrade() {
810            Some(state) => state,
811            None => return Err(self),
812        };
813        let mut access = match state.try_lock() {
814            Some(access) => access,
815            None => return Err(self),
816        };
817        if access.state.is_write_accessible() {
818            access.unlock = false;
819            access.acquire_write_access();
820            drop(access);
821            Ok(ValueWriteAccess {
822                lifetime: state,
823                data,
824            })
825        } else {
826            Err(self)
827        }
828    }
829}
830
831pub struct ValueReadAccess<'a, T: 'a + ?Sized> {
832    lifetime: LifetimeState,
833    data: &'a T,
834}
835
836impl<T: ?Sized> Drop for ValueReadAccess<'_, T> {
837    fn drop(&mut self) {
838        unsafe { self.lifetime.lock_unchecked().release_read_access() };
839    }
840}
841
842impl<'a, T: ?Sized> ValueReadAccess<'a, T> {
843    /// # Safety
844    pub unsafe fn new_raw(data: &'a T, lifetime: LifetimeState) -> Self {
845        Self { lifetime, data }
846    }
847}
848
849impl<T: ?Sized> Deref for ValueReadAccess<'_, T> {
850    type Target = T;
851
852    fn deref(&self) -> &Self::Target {
853        self.data
854    }
855}
856
857impl<'a, T: ?Sized> ValueReadAccess<'a, T> {
858    pub fn remap<U>(
859        self,
860        f: impl FnOnce(&T) -> Option<&U>,
861    ) -> Result<ValueReadAccess<'a, U>, Self> {
862        if let Some(data) = f(self.data) {
863            Ok(ValueReadAccess {
864                lifetime: self.lifetime.clone(),
865                data,
866            })
867        } else {
868            Err(self)
869        }
870    }
871}
872
873pub struct ValueWriteAccess<'a, T: 'a + ?Sized> {
874    lifetime: LifetimeState,
875    data: &'a mut T,
876}
877
878impl<T: ?Sized> Drop for ValueWriteAccess<'_, T> {
879    fn drop(&mut self) {
880        unsafe { self.lifetime.lock_unchecked().release_write_access() };
881    }
882}
883
884impl<'a, T: ?Sized> ValueWriteAccess<'a, T> {
885    /// # Safety
886    pub unsafe fn new_raw(data: &'a mut T, lifetime: LifetimeState) -> Self {
887        Self { lifetime, data }
888    }
889}
890
891impl<T: ?Sized> Deref for ValueWriteAccess<'_, T> {
892    type Target = T;
893
894    fn deref(&self) -> &Self::Target {
895        self.data
896    }
897}
898
899impl<T: ?Sized> DerefMut for ValueWriteAccess<'_, T> {
900    fn deref_mut(&mut self) -> &mut Self::Target {
901        self.data
902    }
903}
904
905impl<'a, T: ?Sized> ValueWriteAccess<'a, T> {
906    pub fn remap<U>(
907        self,
908        f: impl FnOnce(&mut T) -> Option<&mut U>,
909    ) -> Result<ValueWriteAccess<'a, U>, Self> {
910        if let Some(data) = f(unsafe { std::mem::transmute::<&mut T, &'a mut T>(&mut *self.data) })
911        {
912            Ok(ValueWriteAccess {
913                lifetime: self.lifetime.clone(),
914                data,
915            })
916        } else {
917            Err(self)
918        }
919    }
920}
921
922pub struct ReadLock {
923    lifetime: LifetimeState,
924}
925
926impl Drop for ReadLock {
927    fn drop(&mut self) {
928        unsafe { self.lifetime.lock_unchecked().release_read_access() };
929    }
930}
931
932impl ReadLock {
933    /// # Safety
934    pub unsafe fn new_raw(lifetime: LifetimeState) -> Self {
935        Self { lifetime }
936    }
937
938    pub fn using<R>(self, f: impl FnOnce() -> R) -> R {
939        let result = f();
940        drop(self);
941        result
942    }
943}
944
945pub struct WriteLock {
946    lifetime: LifetimeState,
947}
948
949impl Drop for WriteLock {
950    fn drop(&mut self) {
951        unsafe { self.lifetime.lock_unchecked().release_write_access() };
952    }
953}
954
955impl WriteLock {
956    /// # Safety
957    pub unsafe fn new_raw(lifetime: LifetimeState) -> Self {
958        Self { lifetime }
959    }
960
961    pub fn using<R>(self, f: impl FnOnce() -> R) -> R {
962        let result = f();
963        drop(self);
964        result
965    }
966}
967
968#[cfg(test)]
969mod tests {
970    use super::*;
971    use std::thread::*;
972
973    fn is_async<T: Send + Sync + ?Sized>() {
974        println!("{} is async!", std::any::type_name::<T>());
975    }
976
977    #[test]
978    fn test_lifetimes() {
979        is_async::<Lifetime>();
980        is_async::<LifetimeRef>();
981        is_async::<LifetimeRefMut>();
982        is_async::<LifetimeLazy>();
983
984        let mut value = 0usize;
985        let lifetime_ref = {
986            let lifetime = Lifetime::default();
987            assert!(lifetime.state().can_read());
988            assert!(lifetime.state().can_write(0));
989            assert!(lifetime.state().is_read_accessible());
990            assert!(lifetime.state().is_write_accessible());
991            let lifetime_lazy = lifetime.lazy();
992            assert!(lifetime_lazy.read(&42).is_some());
993            assert!(lifetime_lazy.write(&mut 42).is_some());
994            {
995                let access = lifetime.read(&value).unwrap();
996                assert_eq!(*access, value);
997            }
998            {
999                let mut access = lifetime.write(&mut value).unwrap();
1000                *access = 42;
1001                assert_eq!(*access, 42);
1002            }
1003            {
1004                let lifetime_ref = lifetime.borrow().unwrap();
1005                assert!(lifetime.state().can_read());
1006                assert!(!lifetime.state().can_write(0));
1007                assert!(lifetime_ref.exists());
1008                assert!(lifetime_ref.is_owned_by(&lifetime));
1009                assert!(lifetime.borrow().is_some());
1010                assert!(lifetime.borrow_mut().is_none());
1011                assert!(lifetime_lazy.read(&42).is_some());
1012                assert!(lifetime_lazy.write(&mut 42).is_some());
1013                {
1014                    let access = lifetime_ref.read(&value).unwrap();
1015                    assert_eq!(*access, 42);
1016                    assert!(lifetime_lazy.read(&42).is_none());
1017                    assert!(lifetime_lazy.write(&mut 42).is_none());
1018                }
1019                let lifetime_ref2 = lifetime_ref.borrow().unwrap();
1020                {
1021                    let access = lifetime_ref2.read(&value).unwrap();
1022                    assert_eq!(*access, 42);
1023                    assert!(lifetime_lazy.read(&42).is_none());
1024                    assert!(lifetime_lazy.write(&mut 42).is_none());
1025                }
1026            }
1027            {
1028                let lifetime_ref_mut = lifetime.borrow_mut().unwrap();
1029                assert_eq!(lifetime.state().writer_depth(), 1);
1030                assert!(!lifetime.state().can_read());
1031                assert!(!lifetime.state().can_write(0));
1032                assert!(lifetime_ref_mut.exists());
1033                assert!(lifetime_ref_mut.is_owned_by(&lifetime));
1034                assert!(lifetime.borrow().is_none());
1035                assert!(lifetime.borrow_mut().is_none());
1036                assert!(lifetime_lazy.read(&42).is_some());
1037                assert!(lifetime_lazy.write(&mut 42).is_some());
1038                {
1039                    let mut access = lifetime_ref_mut.write(&mut value).unwrap();
1040                    *access = 7;
1041                    assert_eq!(*access, 7);
1042                    assert!(lifetime_lazy.read(&42).is_none());
1043                    assert!(lifetime_lazy.write(&mut 42).is_none());
1044                }
1045                let lifetime_ref_mut2 = lifetime_ref_mut.borrow_mut().unwrap();
1046                assert!(lifetime_lazy.read(&42).is_some());
1047                assert!(lifetime_lazy.write(&mut 42).is_some());
1048                {
1049                    assert_eq!(lifetime.state().writer_depth(), 2);
1050                    assert!(lifetime.borrow().is_none());
1051                    assert!(lifetime_ref_mut.borrow().is_none());
1052                    assert!(lifetime.borrow_mut().is_none());
1053                    assert!(lifetime_ref_mut.borrow_mut().is_none());
1054                    let mut access = lifetime_ref_mut2.write(&mut value).unwrap();
1055                    *access = 42;
1056                    assert_eq!(*access, 42);
1057                    assert!(lifetime.read(&42).is_none());
1058                    assert!(lifetime_ref_mut.read(&42).is_none());
1059                    assert!(lifetime.write(&mut 42).is_none());
1060                    assert!(lifetime_ref_mut.write(&mut 42).is_none());
1061                    assert!(lifetime_lazy.read(&42).is_none());
1062                    assert!(lifetime_lazy.write(&mut 42).is_none());
1063                    assert!(lifetime_lazy.read(&42).is_none());
1064                    assert!(lifetime_lazy.write(&mut 42).is_none());
1065                }
1066            }
1067            assert_eq!(lifetime.state().writer_depth(), 0);
1068            lifetime.borrow().unwrap()
1069        };
1070        assert!(!lifetime_ref.exists());
1071        assert_eq!(value, 42);
1072    }
1073
1074    #[test]
1075    fn test_lifetimes_multithread() {
1076        let lifetime = Lifetime::default();
1077        let lifetime_ref = lifetime.borrow().unwrap();
1078        assert!(lifetime_ref.exists());
1079        assert!(lifetime_ref.is_owned_by(&lifetime));
1080        drop(lifetime);
1081        assert!(!lifetime_ref.exists());
1082        let lifetime = Lifetime::default();
1083        let lifetime = spawn(move || {
1084            let value_ref = lifetime.borrow().unwrap();
1085            assert!(value_ref.exists());
1086            assert!(value_ref.is_owned_by(&lifetime));
1087            lifetime
1088        })
1089        .join()
1090        .unwrap();
1091        assert!(!lifetime_ref.exists());
1092        assert!(!lifetime_ref.is_owned_by(&lifetime));
1093    }
1094
1095    #[test]
1096    fn test_lifetimes_move_invalidation() {
1097        let lifetime = Lifetime::default();
1098        let lifetime_ref = lifetime.borrow().unwrap();
1099        assert_eq!(lifetime_ref.tag(), lifetime.tag());
1100        assert!(lifetime_ref.exists());
1101        let lifetime_ref2 = lifetime_ref;
1102        assert_eq!(lifetime_ref2.tag(), lifetime.tag());
1103        assert!(lifetime_ref2.exists());
1104        let lifetime = Box::new(lifetime);
1105        assert_ne!(lifetime_ref2.tag(), lifetime.tag());
1106        assert!(!lifetime_ref2.exists());
1107        let lifetime = *lifetime;
1108        assert_ne!(lifetime_ref2.tag(), lifetime.tag());
1109        assert!(!lifetime_ref2.exists());
1110    }
1111}