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