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