turbo_trace_server/
store_container.rs1use std::{
2 ops::{Deref, DerefMut},
3 sync::{
4 RwLock, RwLockReadGuard, RwLockWriteGuard,
5 atomic::{AtomicBool, Ordering},
6 },
7};
8
9use crate::store::Store;
10
11pub struct StoreContainer {
12 store: RwLock<StoreWithGeneration>,
13 want_to_read: AtomicBool,
14}
15
16struct StoreWithGeneration {
17 store: Store,
18 generation: usize,
19}
20
21impl StoreContainer {
22 pub fn new() -> Self {
23 Self {
24 store: RwLock::new(StoreWithGeneration {
25 store: Store::new(),
26 generation: 0,
27 }),
28 want_to_read: AtomicBool::new(false),
29 }
30 }
31
32 pub fn read(&self) -> StoreReadGuard<'_> {
33 if let Ok(guard) = self.store.try_read() {
34 return StoreReadGuard { guard };
35 }
36 self.want_to_read.store(true, Ordering::Relaxed);
37 let guard = StoreReadGuard {
38 guard: self.store.read().unwrap(),
39 };
40 self.want_to_read.store(false, Ordering::Relaxed);
41 guard
42 }
43
44 pub fn write(&self) -> StoreWriteGuard<'_> {
45 let mut guard = self.store.write().unwrap();
46 guard.generation += 1;
47 StoreWriteGuard { guard }
48 }
49
50 pub fn want_to_read(&self) -> bool {
51 self.want_to_read.load(Ordering::Relaxed)
52 }
53}
54
55pub struct StoreReadGuard<'a> {
56 guard: RwLockReadGuard<'a, StoreWithGeneration>,
57}
58
59impl StoreReadGuard<'_> {
60 pub fn generation(&self) -> usize {
61 self.guard.generation
62 }
63}
64
65impl Deref for StoreReadGuard<'_> {
66 type Target = Store;
67
68 fn deref(&self) -> &Self::Target {
69 &self.guard.store
70 }
71}
72
73pub struct StoreWriteGuard<'a> {
74 guard: RwLockWriteGuard<'a, StoreWithGeneration>,
75}
76
77impl Deref for StoreWriteGuard<'_> {
78 type Target = Store;
79
80 fn deref(&self) -> &Self::Target {
81 &self.guard.store
82 }
83}
84
85impl DerefMut for StoreWriteGuard<'_> {
86 fn deref_mut(&mut self) -> &mut Self::Target {
87 &mut self.guard.store
88 }
89}