Skip to main content

reifydb_runtime/sync/rwlock/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use std::{
5	fmt,
6	fmt::Debug,
7	ops::{Deref, DerefMut},
8};
9
10use cfg_if::cfg_if;
11
12#[cfg(not(reifydb_single_threaded))]
13pub(crate) mod host;
14#[cfg(loom)]
15pub(crate) mod loom;
16#[cfg(reifydb_single_threaded)]
17pub(crate) mod wasm;
18
19cfg_if! {
20	if #[cfg(loom)] {
21		type RwLockInnerImpl<T> = loom::RwLockInner<T>;
22		type RwLockReadGuardInnerImpl<'a, T> = loom::RwLockReadGuardInner<'a, T>;
23		type RwLockWriteGuardInnerImpl<'a, T> = loom::RwLockWriteGuardInner<'a, T>;
24		type ArcRwLockInnerImpl<T> = host::ArcRwLockInner<T>;
25		type OwnedRwLockReadGuardInnerImpl<T> = host::OwnedRwLockReadGuardInner<T>;
26		type OwnedRwLockWriteGuardInnerImpl<T> = host::OwnedRwLockWriteGuardInner<T>;
27	} else if #[cfg(not(reifydb_single_threaded))] {
28		type RwLockInnerImpl<T> = host::RwLockInner<T>;
29		type RwLockReadGuardInnerImpl<'a, T> = host::RwLockReadGuardInner<'a, T>;
30		type RwLockWriteGuardInnerImpl<'a, T> = host::RwLockWriteGuardInner<'a, T>;
31		type ArcRwLockInnerImpl<T> = host::ArcRwLockInner<T>;
32		type OwnedRwLockReadGuardInnerImpl<T> = host::OwnedRwLockReadGuardInner<T>;
33		type OwnedRwLockWriteGuardInnerImpl<T> = host::OwnedRwLockWriteGuardInner<T>;
34	} else {
35		type RwLockInnerImpl<T> = wasm::RwLockInner<T>;
36		type RwLockReadGuardInnerImpl<'a, T> = wasm::RwLockReadGuardInner<'a, T>;
37		type RwLockWriteGuardInnerImpl<'a, T> = wasm::RwLockWriteGuardInner<'a, T>;
38		type ArcRwLockInnerImpl<T> = wasm::ArcRwLockInner<T>;
39		type OwnedRwLockReadGuardInnerImpl<T> = wasm::OwnedRwLockReadGuardInner<T>;
40		type OwnedRwLockWriteGuardInnerImpl<T> = wasm::OwnedRwLockWriteGuardInner<T>;
41	}
42}
43
44pub struct RwLock<T> {
45	inner: RwLockInnerImpl<T>,
46}
47
48impl<T: Debug> Debug for RwLock<T> {
49	#[inline]
50	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51		self.inner.fmt(f)
52	}
53}
54
55// SAFETY: under reifydb_single_threaded there is no second thread, so the RefCell-backed inner can never
56// be reached concurrently. The impl only satisfies Sync bounds and never backs a real cross-thread share.
57#[cfg(reifydb_single_threaded)]
58unsafe impl<T> Sync for RwLock<T> {}
59
60impl<T> RwLock<T> {
61	#[inline]
62	pub fn new(value: T) -> Self {
63		Self {
64			inner: RwLockInnerImpl::new(value),
65		}
66	}
67
68	#[inline]
69	pub fn read(&self) -> RwLockReadGuard<'_, T> {
70		RwLockReadGuard {
71			inner: self.inner.read(),
72		}
73	}
74
75	#[inline]
76	pub fn write(&self) -> RwLockWriteGuard<'_, T> {
77		RwLockWriteGuard {
78			inner: self.inner.write(),
79		}
80	}
81
82	#[inline]
83	pub fn try_read(&self) -> Option<RwLockReadGuard<'_, T>> {
84		self.inner.try_read().map(|inner| RwLockReadGuard {
85			inner,
86		})
87	}
88
89	#[inline]
90	pub fn try_write(&self) -> Option<RwLockWriteGuard<'_, T>> {
91		self.inner.try_write().map(|inner| RwLockWriteGuard {
92			inner,
93		})
94	}
95}
96
97impl<T: Default> Default for RwLock<T> {
98	#[inline]
99	fn default() -> Self {
100		Self::new(T::default())
101	}
102}
103
104pub struct RwLockReadGuard<'a, T> {
105	inner: RwLockReadGuardInnerImpl<'a, T>,
106}
107
108impl<'a, T> Deref for RwLockReadGuard<'a, T> {
109	type Target = T;
110
111	#[inline]
112	fn deref(&self) -> &T {
113		&self.inner
114	}
115}
116
117impl<'a, T: Debug> Debug for RwLockReadGuard<'a, T> {
118	#[inline]
119	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120		(**self).fmt(f)
121	}
122}
123
124pub struct RwLockWriteGuard<'a, T> {
125	inner: RwLockWriteGuardInnerImpl<'a, T>,
126}
127
128impl<'a, T> Deref for RwLockWriteGuard<'a, T> {
129	type Target = T;
130
131	#[inline]
132	fn deref(&self) -> &T {
133		&self.inner
134	}
135}
136
137impl<'a, T> DerefMut for RwLockWriteGuard<'a, T> {
138	#[inline]
139	fn deref_mut(&mut self) -> &mut T {
140		&mut self.inner
141	}
142}
143
144impl<'a, T: Debug> Debug for RwLockWriteGuard<'a, T> {
145	#[inline]
146	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147		(**self).fmt(f)
148	}
149}
150
151pub struct ArcRwLock<T> {
152	inner: ArcRwLockInnerImpl<T>,
153}
154
155impl<T> Clone for ArcRwLock<T> {
156	#[inline]
157	fn clone(&self) -> Self {
158		Self {
159			inner: self.inner.clone(),
160		}
161	}
162}
163
164#[cfg(reifydb_single_threaded)]
165unsafe impl<T> Send for ArcRwLock<T> {}
166#[cfg(reifydb_single_threaded)]
167unsafe impl<T> Sync for ArcRwLock<T> {}
168
169impl<T: 'static> ArcRwLock<T> {
170	#[inline]
171	pub fn new(value: T) -> Self {
172		Self {
173			inner: ArcRwLockInnerImpl::new(value),
174		}
175	}
176
177	#[inline]
178	pub fn read(&self) -> OwnedRwLockReadGuard<T> {
179		OwnedRwLockReadGuard {
180			inner: self.inner.read(),
181		}
182	}
183
184	#[inline]
185	pub fn write(&self) -> OwnedRwLockWriteGuard<T> {
186		OwnedRwLockWriteGuard {
187			inner: self.inner.write(),
188		}
189	}
190}
191
192pub struct OwnedRwLockReadGuard<T: 'static> {
193	inner: OwnedRwLockReadGuardInnerImpl<T>,
194}
195
196impl<T: 'static> Deref for OwnedRwLockReadGuard<T> {
197	type Target = T;
198
199	#[inline]
200	fn deref(&self) -> &T {
201		&self.inner
202	}
203}
204
205pub struct OwnedRwLockWriteGuard<T: 'static> {
206	inner: OwnedRwLockWriteGuardInnerImpl<T>,
207}
208
209impl<T: 'static> Deref for OwnedRwLockWriteGuard<T> {
210	type Target = T;
211
212	#[inline]
213	fn deref(&self) -> &T {
214		&self.inner
215	}
216}
217
218impl<T: 'static> DerefMut for OwnedRwLockWriteGuard<T> {
219	#[inline]
220	fn deref_mut(&mut self) -> &mut T {
221		&mut self.inner
222	}
223}