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