[−][src]Struct futures_locks::RwLock
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.
Methods
impl<T> RwLock<T>
[src]
pub fn new(t: T) -> RwLock<T>
[src]
Create a new RwLock
in the unlocked state.
pub fn try_unwrap(self) -> Result<T, RwLock<T>>
[src]
Consumes the RwLock
and returns the wrapped data. If the RwLock
still has multiple references (not necessarily locked), returns a copy
of self
instead.
impl<T: ?Sized> RwLock<T>
[src]
pub fn get_mut(&mut self) -> Option<&mut T>
[src]
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);
pub fn read(&self) -> RwLockReadFut<T>
[src]
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!(spawn(fut).wait_future(), Ok(42));
pub fn write(&self) -> RwLockWriteFut<T>
[src]
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;}); spawn(fut).wait_future().expect("spawn"); assert_eq!(rwlock.try_unwrap().unwrap(), 5);
pub fn try_read(&self) -> Result<RwLockReadGuard<T>, ()>
[src]
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);
pub fn try_write(&self) -> Result<RwLockWriteGuard<T>, ()>
[src]
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());
impl<T: 'static + ?Sized> RwLock<T>
[src]
pub fn with_read<F, B, R, E>(
&self,
f: F
) -> Result<impl Future<Item = R, Error = E>, SpawnError> where
F: FnOnce(RwLockReadGuard<T>) -> B + Send + 'static,
B: IntoFuture<Item = R, Error = E> + 'static,
<B as IntoFuture>::Future: Send,
R: Send + 'static,
E: Send + 'static,
T: Send,
[src]
&self,
f: F
) -> Result<impl Future<Item = R, Error = E>, SpawnError> where
F: FnOnce(RwLockReadGuard<T>) -> B + Send + 'static,
B: IntoFuture<Item = R, Error = E> + 'static,
<B as IntoFuture>::Future: Send,
R: Send + 'static,
E: Send + 'static,
T: Send,
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 RwLock
s 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(lazy(|| { rwlock.with_read(|mut guard| { Ok(*guard) as Result<u32, ()> }).unwrap() })); assert_eq!(r, Ok(5));
pub fn with_read_local<F, B, R, E>(
&self,
f: F
) -> Result<impl Future<Item = R, Error = E>, SpawnError> where
F: FnOnce(RwLockReadGuard<T>) -> B + 'static,
B: IntoFuture<Item = R, Error = E> + 'static,
R: 'static,
E: 'static,
[src]
&self,
f: F
) -> Result<impl Future<Item = R, Error = E>, SpawnError> where
F: FnOnce(RwLockReadGuard<T>) -> B + 'static,
B: IntoFuture<Item = R, Error = E> + 'static,
R: 'static,
E: 'static,
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 = current_thread::Runtime::new().unwrap(); let r = rt.block_on(lazy(|| { rwlock.with_read_local(|mut guard| { Ok(**guard) as Result<u32, ()> }).unwrap() })); assert_eq!(r, Ok(5));
pub fn with_write<F, B, R, E>(
&self,
f: F
) -> Result<impl Future<Item = R, Error = E>, SpawnError> where
F: FnOnce(RwLockWriteGuard<T>) -> B + Send + 'static,
B: IntoFuture<Item = R, Error = E> + Send + 'static,
<B as IntoFuture>::Future: Send,
R: Send + 'static,
E: Send + 'static,
T: Send,
[src]
&self,
f: F
) -> Result<impl Future<Item = R, Error = E>, SpawnError> where
F: FnOnce(RwLockWriteGuard<T>) -> B + Send + 'static,
B: IntoFuture<Item = R, Error = E> + Send + 'static,
<B as IntoFuture>::Future: Send,
R: Send + 'static,
E: Send + 'static,
T: Send,
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 RwLock
s 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(lazy(|| { rwlock.with_write(|mut guard| { *guard += 5; Ok(()) as Result<(), ()> }).unwrap() })); assert!(r.is_ok()); assert_eq!(rwlock.try_unwrap().unwrap(), 5);
pub fn with_write_local<F, B, R, E>(
&self,
f: F
) -> Result<impl Future<Item = R, Error = E>, SpawnError> where
F: FnOnce(RwLockWriteGuard<T>) -> B + 'static,
B: IntoFuture<Item = R, Error = E> + 'static,
R: 'static,
E: 'static,
[src]
&self,
f: F
) -> Result<impl Future<Item = R, Error = E>, SpawnError> where
F: FnOnce(RwLockWriteGuard<T>) -> B + 'static,
B: IntoFuture<Item = R, Error = E> + 'static,
R: 'static,
E: 'static,
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 = current_thread::Runtime::new().unwrap(); let r = rt.block_on(lazy(|| { rwlock.with_write_local(|mut guard| { *Rc::get_mut(&mut *guard).unwrap() += 5; Ok(()) as Result<(), ()> }).unwrap() })); assert!(r.is_ok()); assert_eq!(*rwlock.try_unwrap().unwrap(), 5);
Trait Implementations
impl<T: ?Sized + Send> Send for RwLock<T>
[src]
impl<T: ?Sized + Send> Sync for RwLock<T>
[src]
impl<T: ?Sized> Clone for RwLock<T>
[src]
impl<T: Default + ?Sized> Default for RwLock<T>
[src]
impl<T: Debug + ?Sized> Debug for RwLock<T>
[src]
Auto Trait Implementations
impl<T: ?Sized> Unpin for RwLock<T>
impl<T> !UnwindSafe for RwLock<T>
impl<T> !RefUnwindSafe for RwLock<T>
Blanket Implementations
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> From<T> for T
[src]
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
fn to_owned(&self) -> T
[src]
fn clone_into(&self, target: &mut T)
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,