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