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