async_lock

Struct RwLock

source
pub struct RwLock<T: ?Sized> { /* private fields */ }
Expand description

An async reader-writer lock.

This type of lock allows multiple readers or one writer at any point in time.

The locking strategy is write-preferring, which means writers are never starved. Releasing a write lock wakes the next blocked reader and the next blocked writer.

§Examples

use async_lock::RwLock;

let lock = RwLock::new(5);

// Multiple read locks can be held at a time.
let r1 = lock.read().await;
let r2 = lock.read().await;
assert_eq!(*r1, 5);
assert_eq!(*r2, 5);
drop((r1, r2));

// Only one write lock can be held at a time.
let mut w = lock.write().await;
*w += 1;
assert_eq!(*w, 6);

Implementations§

source§

impl<T> RwLock<T>

source

pub const fn new(t: T) -> RwLock<T>

Creates a new reader-writer lock.

§Examples
use async_lock::RwLock;

let lock = RwLock::new(0);
source

pub fn into_inner(self) -> T

Unwraps the lock and returns the inner value.

§Examples
use async_lock::RwLock;

let lock = RwLock::new(5);
assert_eq!(lock.into_inner(), 5);
source

pub fn try_read_arc(self: &Arc<Self>) -> Option<RwLockReadGuardArc<T>>

Attempts to acquire an an owned, reference-counted read lock.

If a read lock could not be acquired at this time, then None is returned. Otherwise, a guard is returned that releases the lock when dropped.

§Examples
use std::sync::Arc;
use async_lock::RwLock;

let lock = Arc::new(RwLock::new(1));

let reader = lock.read_arc().await;
assert_eq!(*reader, 1);

assert!(lock.try_read_arc().is_some());
source

pub fn read_arc<'a>(self: &'a Arc<Self>) -> ReadArc<'a, T>

Acquires an owned, reference-counted read lock.

Returns a guard that releases the lock when dropped.

Note that attempts to acquire a read lock will block if there are also concurrent attempts to acquire a write lock.

§Examples
use std::sync::Arc;
use async_lock::RwLock;

let lock = Arc::new(RwLock::new(1));

let reader = lock.read_arc().await;
assert_eq!(*reader, 1);

assert!(lock.try_read_arc().is_some());
source

pub fn read_arc_blocking(self: &Arc<Self>) -> RwLockReadGuardArc<T>

Acquires an owned, reference-counted read lock.

Returns a guard that releases the lock when dropped.

Note that attempts to acquire a read lock will block if there are also concurrent attempts to acquire a write lock.

§Blocking

Rather than using asynchronous waiting, like the read_arc method, this method will block the current thread until the read lock is acquired.

This method should not be used in an asynchronous context. It is intended to be used in a way that a lock can be used in both asynchronous and synchronous contexts. Calling this method in an asynchronous context may result in a deadlock.

§Examples
use std::sync::Arc;
use async_lock::RwLock;

let lock = Arc::new(RwLock::new(1));

let reader = lock.read_arc_blocking();
assert_eq!(*reader, 1);

assert!(lock.try_read().is_some());
source§

impl<T: ?Sized> RwLock<T>

source

pub fn try_read(&self) -> Option<RwLockReadGuard<'_, T>>

Attempts to acquire a read lock.

If a read lock could not be acquired at this time, then None is returned. Otherwise, a guard is returned that releases the lock when dropped.

§Examples
use async_lock::RwLock;

let lock = RwLock::new(1);

let reader = lock.read().await;
assert_eq!(*reader, 1);

assert!(lock.try_read().is_some());
source

pub fn read(&self) -> Read<'_, T>

Acquires a read lock.

Returns a guard that releases the lock when dropped.

Note that attempts to acquire a read lock will block if there are also concurrent attempts to acquire a write lock.

§Examples
use async_lock::RwLock;

let lock = RwLock::new(1);

let reader = lock.read().await;
assert_eq!(*reader, 1);

assert!(lock.try_read().is_some());
source

pub fn read_blocking(&self) -> RwLockReadGuard<'_, T>

Acquires a read lock.

Returns a guard that releases the lock when dropped.

Note that attempts to acquire a read lock will block if there are also concurrent attempts to acquire a write lock.

§Blocking

Rather than using asynchronous waiting, like the read method, this method will block the current thread until the read lock is acquired.

This method should not be used in an asynchronous context. It is intended to be used in a way that a lock can be used in both asynchronous and synchronous contexts. Calling this method in an asynchronous context may result in a deadlock.

§Examples
use async_lock::RwLock;

let lock = RwLock::new(1);

let reader = lock.read_blocking();
assert_eq!(*reader, 1);

assert!(lock.try_read().is_some());
source

pub fn try_upgradable_read(&self) -> Option<RwLockUpgradableReadGuard<'_, T>>

Attempts to acquire a read lock with the possiblity to upgrade to a write lock.

If a read lock could not be acquired at this time, then None is returned. Otherwise, a guard is returned that releases the lock when dropped.

Upgradable read lock reserves the right to be upgraded to a write lock, which means there can be at most one upgradable read lock at a time.

§Examples
use async_lock::{RwLock, RwLockUpgradableReadGuard};

let lock = RwLock::new(1);

let reader = lock.upgradable_read().await;
assert_eq!(*reader, 1);
assert_eq!(*lock.try_read().unwrap(), 1);

let mut writer = RwLockUpgradableReadGuard::upgrade(reader).await;
*writer = 2;
source

pub fn upgradable_read(&self) -> UpgradableRead<'_, T>

Acquires a read lock with the possiblity to upgrade to a write lock.

Returns a guard that releases the lock when dropped.

Upgradable read lock reserves the right to be upgraded to a write lock, which means there can be at most one upgradable read lock at a time.

Note that attempts to acquire an upgradable read lock will block if there are concurrent attempts to acquire another upgradable read lock or a write lock.

§Examples
use async_lock::{RwLock, RwLockUpgradableReadGuard};

let lock = RwLock::new(1);

let reader = lock.upgradable_read().await;
assert_eq!(*reader, 1);
assert_eq!(*lock.try_read().unwrap(), 1);

let mut writer = RwLockUpgradableReadGuard::upgrade(reader).await;
*writer = 2;
source

pub fn upgradable_read_blocking(&self) -> RwLockUpgradableReadGuard<'_, T>

Attempts to acquire a read lock with the possiblity to upgrade to a write lock.

Returns a guard that releases the lock when dropped.

Upgradable read lock reserves the right to be upgraded to a write lock, which means there can be at most one upgradable read lock at a time.

Note that attempts to acquire an upgradable read lock will block if there are concurrent attempts to acquire another upgradable read lock or a write lock.

§Blocking

Rather than using asynchronous waiting, like the upgradable_read method, this method will block the current thread until the read lock is acquired.

This method should not be used in an asynchronous context. It is intended to be used in a way that a lock can be used in both asynchronous and synchronous contexts. Calling this method in an asynchronous context may result in a deadlock.

§Examples
use async_lock::{RwLock, RwLockUpgradableReadGuard};

let lock = RwLock::new(1);

let reader = lock.upgradable_read_blocking();
assert_eq!(*reader, 1);
assert_eq!(*lock.try_read().unwrap(), 1);

let mut writer = RwLockUpgradableReadGuard::upgrade_blocking(reader);
*writer = 2;
source

pub fn upgradable_read_arc_blocking( self: &Arc<Self>, ) -> RwLockUpgradableReadGuardArc<T>

Attempts to acquire an owned, reference-counted read lock with the possiblity to upgrade to a write lock.

Returns a guard that releases the lock when dropped.

Upgradable read lock reserves the right to be upgraded to a write lock, which means there can be at most one upgradable read lock at a time.

Note that attempts to acquire an upgradable read lock will block if there are concurrent attempts to acquire another upgradable read lock or a write lock.

§Blocking

Rather than using asynchronous waiting, like the upgradable_read_arc method, this method will block the current thread until the read lock is acquired.

This method should not be used in an asynchronous context. It is intended to be used in a way that a lock can be used in both asynchronous and synchronous contexts. Calling this method in an asynchronous context may result in a deadlock.

§Examples
use std::sync::Arc;
use async_lock::{RwLock, RwLockUpgradableReadGuardArc};

let lock = Arc::new(RwLock::new(1));

let reader = lock.upgradable_read_arc_blocking();
assert_eq!(*reader, 1);
assert_eq!(*lock.try_read().unwrap(), 1);

let mut writer = RwLockUpgradableReadGuardArc::upgrade_blocking(reader);
*writer = 2;
source

pub fn try_upgradable_read_arc( self: &Arc<Self>, ) -> Option<RwLockUpgradableReadGuardArc<T>>

Attempts to acquire an owned, reference-counted read lock with the possiblity to upgrade to a write lock.

If a read lock could not be acquired at this time, then None is returned. Otherwise, a guard is returned that releases the lock when dropped.

Upgradable read lock reserves the right to be upgraded to a write lock, which means there can be at most one upgradable read lock at a time.

§Examples
use std::sync::Arc;
use async_lock::{RwLock, RwLockUpgradableReadGuardArc};

let lock = Arc::new(RwLock::new(1));

let reader = lock.upgradable_read_arc().await;
assert_eq!(*reader, 1);
assert_eq!(*lock.try_read_arc().unwrap(), 1);

let mut writer = RwLockUpgradableReadGuardArc::upgrade(reader).await;
*writer = 2;
source

pub fn upgradable_read_arc<'a>(self: &'a Arc<Self>) -> UpgradableReadArc<'a, T>

Acquires an owned, reference-counted read lock with the possiblity to upgrade to a write lock.

Returns a guard that releases the lock when dropped.

Upgradable read lock reserves the right to be upgraded to a write lock, which means there can be at most one upgradable read lock at a time.

Note that attempts to acquire an upgradable read lock will block if there are concurrent attempts to acquire another upgradable read lock or a write lock.

§Examples
use std::sync::Arc;
use async_lock::{RwLock, RwLockUpgradableReadGuardArc};

let lock = Arc::new(RwLock::new(1));

let reader = lock.upgradable_read_arc().await;
assert_eq!(*reader, 1);
assert_eq!(*lock.try_read_arc().unwrap(), 1);

let mut writer = RwLockUpgradableReadGuardArc::upgrade(reader).await;
*writer = 2;
source

pub fn try_write(&self) -> Option<RwLockWriteGuard<'_, T>>

Attempts to acquire a write lock.

If a write lock could not be acquired at this time, then None is returned. Otherwise, a guard is returned that releases the lock when dropped.

§Examples
use async_lock::RwLock;

let lock = RwLock::new(1);

assert!(lock.try_write().is_some());
let reader = lock.read().await;
assert!(lock.try_write().is_none());
source

pub fn write(&self) -> Write<'_, T>

Acquires a write lock.

Returns a guard that releases the lock when dropped.

§Examples
use async_lock::RwLock;

let lock = RwLock::new(1);

let writer = lock.write().await;
assert!(lock.try_read().is_none());
source

pub fn write_blocking(&self) -> RwLockWriteGuard<'_, T>

Acquires a write lock.

Returns a guard that releases the lock when dropped.

§Blocking

Rather than using asynchronous waiting, like the write method, this method will block the current thread until the write lock is acquired.

This method should not be used in an asynchronous context. It is intended to be used in a way that a lock can be used in both asynchronous and synchronous contexts. Calling this method in an asynchronous context may result in a deadlock.

§Examples
use async_lock::RwLock;

let lock = RwLock::new(1);

let writer = lock.write_blocking();
assert!(lock.try_read().is_none());
source

pub fn try_write_arc(self: &Arc<Self>) -> Option<RwLockWriteGuardArc<T>>

Attempts to acquire an owned, reference-counted write lock.

If a write lock could not be acquired at this time, then None is returned. Otherwise, a guard is returned that releases the lock when dropped.

§Examples
use std::sync::Arc;
use async_lock::RwLock;

let lock = Arc::new(RwLock::new(1));

assert!(lock.try_write_arc().is_some());
let reader = lock.read_arc().await;
assert!(lock.try_write_arc().is_none());
source

pub fn write_arc<'a>(self: &'a Arc<Self>) -> WriteArc<'a, T>

Acquires an owned, reference-counted write lock.

Returns a guard that releases the lock when dropped.

§Examples
use std::sync::Arc;
use async_lock::RwLock;

let lock = Arc::new(RwLock::new(1));

let writer = lock.write_arc().await;
assert!(lock.try_read_arc().is_none());
source

pub fn write_arc_blocking(self: &Arc<Self>) -> RwLockWriteGuardArc<T>

Acquires an owned, reference-counted write lock.

Returns a guard that releases the lock when dropped.

§Blocking

Rather than using asynchronous waiting, like the write_arc method, this method will block the current thread until the write lock is acquired.

This method should not be used in an asynchronous context. It is intended to be used in a way that a lock can be used in both asynchronous and synchronous contexts. Calling this method in an asynchronous context may result in a deadlock.

§Examples
use std::sync::Arc;
use async_lock::RwLock;

let lock = Arc::new(RwLock::new(1));

let writer = lock.write_arc_blocking();
assert!(lock.try_read().is_none());
source

pub fn get_mut(&mut self) -> &mut T

Returns a mutable reference to the inner value.

Since this call borrows the lock mutably, no actual locking takes place. The mutable borrow statically guarantees no locks exist.

§Examples
use async_lock::RwLock;

let mut lock = RwLock::new(1);

*lock.get_mut() = 2;
assert_eq!(*lock.read().await, 2);

Trait Implementations§

source§

impl<T: Debug + ?Sized> Debug for RwLock<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: Default + ?Sized> Default for RwLock<T>

source§

fn default() -> RwLock<T>

Returns the “default value” for a type. Read more
source§

impl<T> From<T> for RwLock<T>

source§

fn from(val: T) -> RwLock<T>

Converts to this type from the input type.
source§

impl<T: Send + ?Sized> Send for RwLock<T>

source§

impl<T: Send + Sync + ?Sized> Sync for RwLock<T>

Auto Trait Implementations§

§

impl<T> !Freeze for RwLock<T>

§

impl<T> !RefUnwindSafe for RwLock<T>

§

impl<T> Unpin for RwLock<T>
where T: Unpin + ?Sized,

§

impl<T> UnwindSafe for RwLock<T>
where T: UnwindSafe + ?Sized,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<!> for T

source§

fn from(t: !) -> T

Converts to this type from the input type.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.