Skip to main content

reifydb_runtime/sync/rwlock/
mod.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4//! RwLock synchronization primitive.
5
6use std::ops::{Deref, DerefMut};
7
8use cfg_if::cfg_if;
9
10#[cfg(reifydb_target = "native")]
11pub(crate) mod native;
12#[cfg(reifydb_target = "wasm")]
13pub(crate) mod wasm;
14
15cfg_if! {
16	if #[cfg(reifydb_target = "native")] {
17		type RwLockInnerImpl<T> = native::RwLockInner<T>;
18		type RwLockReadGuardInnerImpl<'a, T> = native::RwLockReadGuardInner<'a, T>;
19		type RwLockWriteGuardInnerImpl<'a, T> = native::RwLockWriteGuardInner<'a, T>;
20	} else {
21		type RwLockInnerImpl<T> = wasm::RwLockInner<T>;
22		type RwLockReadGuardInnerImpl<'a, T> = wasm::RwLockReadGuardInner<'a, T>;
23		type RwLockWriteGuardInnerImpl<'a, T> = wasm::RwLockWriteGuardInner<'a, T>;
24	}
25}
26
27/// A reader-writer lock for shared read access and exclusive write access.
28pub struct RwLock<T> {
29	inner: RwLockInnerImpl<T>,
30}
31
32// SAFETY: WASM is single-threaded, so Sync is safe
33#[cfg(reifydb_target = "wasm")]
34unsafe impl<T> Sync for RwLock<T> {}
35
36impl<T> RwLock<T> {
37	/// Creates a new reader-writer lock.
38	#[inline]
39	pub fn new(value: T) -> Self {
40		Self {
41			inner: RwLockInnerImpl::new(value),
42		}
43	}
44
45	/// Acquires a read lock, blocking until it's available.
46	#[inline]
47	pub fn read(&self) -> RwLockReadGuard<'_, T> {
48		RwLockReadGuard {
49			inner: self.inner.read(),
50		}
51	}
52
53	/// Acquires a write lock, blocking until it's available.
54	#[inline]
55	pub fn write(&self) -> RwLockWriteGuard<'_, T> {
56		RwLockWriteGuard {
57			inner: self.inner.write(),
58		}
59	}
60
61	/// Attempts to acquire a read lock without blocking.
62	#[inline]
63	pub fn try_read(&self) -> Option<RwLockReadGuard<'_, T>> {
64		self.inner.try_read().map(|inner| RwLockReadGuard {
65			inner,
66		})
67	}
68
69	/// Attempts to acquire a write lock without blocking.
70	#[inline]
71	pub fn try_write(&self) -> Option<RwLockWriteGuard<'_, T>> {
72		self.inner.try_write().map(|inner| RwLockWriteGuard {
73			inner,
74		})
75	}
76}
77
78/// A guard providing read access to the data protected by an RwLock.
79pub struct RwLockReadGuard<'a, T> {
80	inner: RwLockReadGuardInnerImpl<'a, T>,
81}
82
83impl<'a, T> Deref for RwLockReadGuard<'a, T> {
84	type Target = T;
85
86	#[inline]
87	fn deref(&self) -> &T {
88		&self.inner
89	}
90}
91
92/// A guard providing write access to the data protected by an RwLock.
93pub struct RwLockWriteGuard<'a, T> {
94	inner: RwLockWriteGuardInnerImpl<'a, T>,
95}
96
97impl<'a, T> Deref for RwLockWriteGuard<'a, T> {
98	type Target = T;
99
100	#[inline]
101	fn deref(&self) -> &T {
102		&self.inner
103	}
104}
105
106impl<'a, T> DerefMut for RwLockWriteGuard<'a, T> {
107	#[inline]
108	fn deref_mut(&mut self) -> &mut T {
109		&mut self.inner
110	}
111}