// 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, } 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 { data: RwLock, update_queue: TaskQueue, } impl SyncReadAsyncWriteLock { 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, } } }