summaryrefslogtreecommitdiff
path: root/cli/util/sync/sync_read_async_write_lock.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/util/sync/sync_read_async_write_lock.rs')
-rw-r--r--cli/util/sync/sync_read_async_write_lock.rs62
1 files changed, 62 insertions, 0 deletions
diff --git a/cli/util/sync/sync_read_async_write_lock.rs b/cli/util/sync/sync_read_async_write_lock.rs
new file mode 100644
index 000000000..8bd211aa7
--- /dev/null
+++ b/cli/util/sync/sync_read_async_write_lock.rs
@@ -0,0 +1,62 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+
+use deno_core::parking_lot::RwLock;
+use deno_core::parking_lot::RwLockReadGuard;
+use deno_core::parking_lot::RwLockWriteGuard;
+
+use super::TaskQueue;
+use super::TaskQueuePermit;
+
+/// A lock that can be read synchronously at any time (including when
+/// being written to), but must write asynchronously.
+pub struct SyncReadAsyncWriteLockWriteGuard<'a, T: Send + Sync> {
+ _update_permit: TaskQueuePermit<'a>,
+ data: &'a RwLock<T>,
+}
+
+impl<'a, T: Send + Sync> SyncReadAsyncWriteLockWriteGuard<'a, T> {
+ pub fn read(&self) -> RwLockReadGuard<'_, T> {
+ self.data.read()
+ }
+
+ /// Warning: Only `write()` with data you created within this
+ /// write this `SyncReadAsyncWriteLockWriteGuard`.
+ ///
+ /// ```rs
+ /// let mut data = lock.write().await;
+ ///
+ /// let mut data = data.read().clone();
+ /// data.value = 2;
+ /// *data.write() = data;
+ /// ```
+ pub fn write(&self) -> RwLockWriteGuard<'_, T> {
+ self.data.write()
+ }
+}
+
+/// A lock that can only be
+pub struct SyncReadAsyncWriteLock<T: Send + Sync> {
+ data: RwLock<T>,
+ update_queue: TaskQueue,
+}
+
+impl<T: Send + Sync> SyncReadAsyncWriteLock<T> {
+ pub fn new(data: T) -> Self {
+ Self {
+ data: RwLock::new(data),
+ update_queue: TaskQueue::default(),
+ }
+ }
+
+ pub fn read(&self) -> RwLockReadGuard<'_, T> {
+ self.data.read()
+ }
+
+ pub async fn acquire(&self) -> SyncReadAsyncWriteLockWriteGuard<'_, T> {
+ let update_permit = self.update_queue.acquire().await;
+ SyncReadAsyncWriteLockWriteGuard {
+ _update_permit: update_permit,
+ data: &self.data,
+ }
+ }
+}