Skip to main content

reifydb_runtime/sync/rwlock/
mod.rs

1// SPDX-License-Identifier: MIT
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 native;
14#[cfg(reifydb_single_threaded)]
15pub(crate) mod wasm;
16
17cfg_if! {
18	if #[cfg(not(reifydb_single_threaded))] {
19		type RwLockInnerImpl<T> = native::RwLockInner<T>;
20		type RwLockReadGuardInnerImpl<'a, T> = native::RwLockReadGuardInner<'a, T>;
21		type RwLockWriteGuardInnerImpl<'a, T> = native::RwLockWriteGuardInner<'a, T>;
22	} else {
23		type RwLockInnerImpl<T> = wasm::RwLockInner<T>;
24		type RwLockReadGuardInnerImpl<'a, T> = wasm::RwLockReadGuardInner<'a, T>;
25		type RwLockWriteGuardInnerImpl<'a, T> = wasm::RwLockWriteGuardInner<'a, T>;
26	}
27}
28
29pub struct RwLock<T> {
30	inner: RwLockInnerImpl<T>,
31}
32
33impl<T: Debug> Debug for RwLock<T> {
34	#[inline]
35	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36		self.inner.fmt(f)
37	}
38}
39
40// SAFETY: Single-threaded targets (WASM/WASI) don't have real concurrency
41#[cfg(reifydb_single_threaded)]
42unsafe impl<T> Sync for RwLock<T> {}
43
44impl<T> RwLock<T> {
45	#[inline]
46	pub fn new(value: T) -> Self {
47		Self {
48			inner: RwLockInnerImpl::new(value),
49		}
50	}
51
52	#[inline]
53	pub fn read(&self) -> RwLockReadGuard<'_, T> {
54		RwLockReadGuard {
55			inner: self.inner.read(),
56		}
57	}
58
59	#[inline]
60	pub fn write(&self) -> RwLockWriteGuard<'_, T> {
61		RwLockWriteGuard {
62			inner: self.inner.write(),
63		}
64	}
65
66	#[inline]
67	pub fn try_read(&self) -> Option<RwLockReadGuard<'_, T>> {
68		self.inner.try_read().map(|inner| RwLockReadGuard {
69			inner,
70		})
71	}
72
73	#[inline]
74	pub fn try_write(&self) -> Option<RwLockWriteGuard<'_, T>> {
75		self.inner.try_write().map(|inner| RwLockWriteGuard {
76			inner,
77		})
78	}
79
80	#[inline]
81	pub fn read_recursive(&self) -> RwLockReadGuard<'_, T> {
82		RwLockReadGuard {
83			inner: self.inner.read_recursive(),
84		}
85	}
86
87	#[inline]
88	pub fn try_read_recursive(&self) -> Option<RwLockReadGuard<'_, T>> {
89		self.inner.try_read_recursive().map(|inner| RwLockReadGuard {
90			inner,
91		})
92	}
93}
94
95impl<T: Default> Default for RwLock<T> {
96	#[inline]
97	fn default() -> Self {
98		Self::new(T::default())
99	}
100}
101
102pub struct RwLockReadGuard<'a, T> {
103	inner: RwLockReadGuardInnerImpl<'a, T>,
104}
105
106impl<'a, T> Deref for RwLockReadGuard<'a, T> {
107	type Target = T;
108
109	#[inline]
110	fn deref(&self) -> &T {
111		&self.inner
112	}
113}
114
115impl<'a, T: Debug> Debug for RwLockReadGuard<'a, T> {
116	#[inline]
117	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118		(**self).fmt(f)
119	}
120}
121
122pub struct RwLockWriteGuard<'a, T> {
123	inner: RwLockWriteGuardInnerImpl<'a, T>,
124}
125
126impl<'a, T> Deref for RwLockWriteGuard<'a, T> {
127	type Target = T;
128
129	#[inline]
130	fn deref(&self) -> &T {
131		&self.inner
132	}
133}
134
135impl<'a, T> DerefMut for RwLockWriteGuard<'a, T> {
136	#[inline]
137	fn deref_mut(&mut self) -> &mut T {
138		&mut self.inner
139	}
140}
141
142impl<'a, T: Debug> Debug for RwLockWriteGuard<'a, T> {
143	#[inline]
144	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145		(**self).fmt(f)
146	}
147}