Struct futures_locks::RwLock

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

A Futures-aware RwLock.

std::sync::RwLock cannot be used in an asynchronous environment like Tokio, because an acquisition can block an entire reactor. This class can be used instead. It functions much like std::sync::RwLock. Unlike that class, it also has a builtin Arc, making it accessible from multiple threads. It’s also safe to clone. Also unlike std::sync::RwLock, this class does not detect lock poisoning.

Implementations§

Create a new RwLock in the unlocked state.

Consumes the RwLock and returns the wrapped data. If the RwLock still has multiple references (not necessarily locked), returns a copy of self instead.

Returns a reference to the underlying data, if there are no other clones of the RwLock.

Since this call borrows the RwLock mutably, no actual locking takes place – the mutable borrow statically guarantees no locks exist. However, if the RwLock has already been cloned, then None will be returned instead.

Examples
let mut lock = RwLock::<u32>::new(0);
*lock.get_mut().unwrap() += 5;
assert_eq!(lock.try_unwrap().unwrap(), 5);

Acquire the RwLock nonexclusively, read-only, blocking the task in the meantime.

When the returned Future is ready, then this task will have read-only access to the protected data.

Examples
let rwlock = RwLock::<u32>::new(42);
let fut = rwlock.read().map(|mut guard| { *guard });
assert_eq!(block_on(fut), 42);

Acquire the RwLock exclusively, read-write, blocking the task in the meantime.

When the returned Future is ready, then this task will have read-write access to the protected data.

Examples
let rwlock = RwLock::<u32>::new(42);
let fut = rwlock.write().map(|mut guard| { *guard = 5;});
block_on(fut);
assert_eq!(rwlock.try_unwrap().unwrap(), 5);

Attempts to acquire the RwLock nonexclusively.

If the operation would block, returns Err instead. Otherwise, returns a guard (not a Future).

Examples
let mut lock = RwLock::<u32>::new(5);
let r = match lock.try_read() {
    Ok(guard) => *guard,
    Err(_) => panic!("Better luck next time!")
};
assert_eq!(5, r);

Attempts to acquire the RwLock exclusively.

If the operation would block, returns Err instead. Otherwise, returns a guard (not a Future).

Examples
let mut lock = RwLock::<u32>::new(5);
match lock.try_write() {
    Ok(mut guard) => *guard += 5,
    Err(_) => panic!("Better luck next time!")
}
assert_eq!(10, lock.try_unwrap().unwrap());
Available on crate feature tokio only.

Acquires a RwLock nonexclusively and performs a computation on its guarded value in a separate task. Returns a Future containing the result of the computation.

When using Tokio, this method will often hold the RwLock for less time than chaining a computation to read. The reason is that Tokio polls all tasks promptly upon notification. However, Tokio does not guarantee that it will poll all futures promptly when their owning task gets notified. So it’s best to hold RwLocks within their own tasks, lest their continuations get blocked by slow stacked combinators.

Examples
let rwlock = RwLock::<u32>::new(5);
let mut rt = Runtime::new().unwrap();
let r = rt.block_on(async {
    rwlock.with_read(|mut guard| {
        ready(*guard)
    }).await
});
assert_eq!(r, 5);
Available on crate feature tokio only.

Like with_read but for Futures that aren’t Send. Spawns a new task on a single-threaded Runtime to complete the Future.

Examples
// Note: Rc is not `Send`
let rwlock = RwLock::<Rc<u32>>::new(Rc::new(5));
let mut rt = Runtime::new().unwrap();
let r = rt.block_on(async {
    rwlock.with_read_local(|mut guard| {
        ready(**guard)
    }).await
});
assert_eq!(r, 5);
Available on crate feature tokio only.

Acquires a RwLock exclusively and performs a computation on its guarded value in a separate task. Returns a Future containing the result of the computation.

When using Tokio, this method will often hold the RwLock for less time than chaining a computation to write. The reason is that Tokio polls all tasks promptly upon notification. However, Tokio does not guarantee that it will poll all futures promptly when their owning task gets notified. So it’s best to hold RwLocks within their own tasks, lest their continuations get blocked by slow stacked combinators.

Examples
let rwlock = RwLock::<u32>::new(0);
let mut rt = Runtime::new().unwrap();
let r = rt.block_on(async {
    rwlock.with_write(|mut guard| {
        *guard += 5;
        ready(())
    }).await
});
assert_eq!(rwlock.try_unwrap().unwrap(), 5);
Available on crate feature tokio only.

Like with_write but for Futures that aren’t Send. Spawns a new task on a single-threaded Runtime to complete the Future.

Examples
// Note: Rc is not `Send`
let rwlock = RwLock::<Rc<u32>>::new(Rc::new(0));
let mut rt = Runtime::new().unwrap();
let r = rt.block_on(async {
    rwlock.with_write_local(|mut guard| {
        *Rc::get_mut(&mut *guard).unwrap() += 5;
        ready(())
    }).await
});
assert_eq!(*rwlock.try_unwrap().unwrap(), 5);

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.