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