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