pub struct Lock { /* private fields */ }
Expand description
A re-entrant lock that can be used to protect multiple objects.
Locking this lock automatically gives access to all objects protected by it.
§Example
use shared_lock::Lock;
let lock = Lock::default();
let locked1 = lock.wrap(1);
let locked2 = lock.wrap(2);
let guard = &lock.lock();
assert_eq!(*locked1.get(guard), 1);
assert_eq!(*locked2.get(guard), 2);
Implementations§
Source§impl Lock
impl Lock
Sourcepub unsafe fn force_unlock(&self)
pub unsafe fn force_unlock(&self)
Forcibly consumes a ticket.
This can be used to consume the ticket of a Guard
that was passed to
mem::forget
.
§Safety
- The current thread must own a ticket.
- The invariant that each
Guard
owns a ticket must be upheld whenever aGuard
is used or dropped.
§Example
use std::mem;
use shared_lock::Lock;
let lock = Lock::default();
let guard = lock.lock();
assert!(lock.is_locked());
mem::forget(guard);
// SAFETY: This consumes the ticket from the guard.
unsafe {
lock.force_unlock();
}
assert!(!lock.is_locked());
Sourcepub unsafe fn force_unlock_fair(&self)
pub unsafe fn force_unlock_fair(&self)
Forcibly consumes a ticket.
If this causes the number tickets to go to 0, the underlying mutex will be unlocked fairly.
This can be used to consume the ticket of a Guard
that was passed to
mem::forget
.
§Safety
- The current thread must own a ticket.
- The invariant that each
Guard
owns a ticket must be upheld whenever aGuard
is used or dropped.
§Example
use std::mem;
use shared_lock::Lock;
let lock = Lock::default();
let guard = lock.lock();
assert!(lock.is_locked());
mem::forget(guard);
// SAFETY: This consumes the ticket from the guard.
unsafe {
lock.force_unlock_fair();
}
assert!(!lock.is_locked());
Sourcepub fn is_locked(&self) -> bool
pub fn is_locked(&self) -> bool
Returns whether this lock is locked.
§Example
use shared_lock::Lock;
let lock = Lock::default();
assert!(!lock.is_locked());
let _guard = lock.lock();
assert!(lock.is_locked());
Sourcepub fn is_locked_by(&self, guard: &Guard<'_>) -> bool
pub fn is_locked_by(&self, guard: &Guard<'_>) -> bool
Returns whether this lock is locked by the guard.
§Example
use shared_lock::Lock;
let lock1 = Lock::default();
let lock2 = Lock::default();
let guard1 = &lock1.lock();
let guard2 = &lock2.lock();
assert!(lock1.is_locked_by(&guard1));
assert!(!lock1.is_locked_by(&guard2));
Sourcepub fn is_locked_by_current_thread(&self) -> bool
pub fn is_locked_by_current_thread(&self) -> bool
Returns whether the current thread is holding the lock.
§Example
use std::thread;
use shared_lock::Lock;
let lock = Lock::default();
let _guard = lock.lock();
assert!(lock.is_locked_by_current_thread());
thread::scope(|scope| {
let handle = scope.spawn(|| {
assert!(!lock.is_locked_by_current_thread());
});
handle.join().unwrap();
});
Sourcepub fn lock(&self) -> Guard<'_>
pub fn lock(&self) -> Guard<'_>
Acquires this lock.
If the lock is held by another thread, then this function will block until it is able to acquire the lock. If the current thread has already acquired the lock, the function returns immediately.
§Example
use shared_lock::Lock;
let lock = Lock::default();
let _guard = lock.lock();
Sourcepub unsafe fn make_guard_unchecked(&self) -> Guard<'_>
pub unsafe fn make_guard_unchecked(&self) -> Guard<'_>
Sourcepub fn try_lock(&self) -> Option<Guard<'_>>
pub fn try_lock(&self) -> Option<Guard<'_>>
Attempts to acquire this lock.
If the lock cannot be acquired at this time, None
is returned. Otherwise a guard
is returned and the lock will be unlocked when the guard is dropped.
This function does not block.
§Example
use std::thread;
use std::time::{Duration, Instant};
use shared_lock::Lock;
let timeout = Duration::from_millis(200);
let lock = Lock::default();
let _guard = lock.lock();
// The same thread can lock the lock again.
assert!(lock.try_lock().is_some());
thread::scope(|scope| {
let join_handle = scope.spawn(|| {
// Another thread cannot lock the lock.
assert!(lock.try_lock().is_none());
});
join_handle.join().unwrap();
});
Sourcepub fn try_lock_for(&self, duration: Duration) -> Option<Guard<'_>>
pub fn try_lock_for(&self, duration: Duration) -> Option<Guard<'_>>
Attempts to acquire this lock until a timeout has expired.
If the lock cannot be acquired before the timeout expires, None
is returned.
Otherwise a guard is returned and the lock will be unlocked when the guard is
dropped.
§Example
use std::thread;
use std::time::{Duration, Instant};
use shared_lock::Lock;
let timeout = Duration::from_millis(200);
let lock = Lock::default();
let _guard = lock.lock();
thread::scope(|scope| {
let join_handle = scope.spawn(|| {
let guard = lock.try_lock_for(timeout);
assert!(guard.is_none());
});
join_handle.join().unwrap();
});
Sourcepub fn try_lock_until(&self, instant: Instant) -> Option<Guard<'_>>
pub fn try_lock_until(&self, instant: Instant) -> Option<Guard<'_>>
Attempts to acquire this lock until a timeout is reached.
If the lock cannot be acquired before the timeout expires, None
is returned.
Otherwise a guard is returned and the lock will be unlocked when the guard is
dropped.
§Example
use std::thread;
use std::time::{Duration, Instant};
use shared_lock::Lock;
let timeout = Instant::now() + Duration::from_millis(200);
let lock = Lock::default();
let _guard = lock.lock();
thread::scope(|scope| {
let join_handle = scope.spawn(|| {
let guard = lock.try_lock_until(timeout);
assert!(guard.is_none());
});
join_handle.join().unwrap();
});
Source§impl Lock
impl Lock
Sourcepub fn wrap<T>(&self, value: T) -> Locked<T>
pub fn wrap<T>(&self, value: T) -> Locked<T>
Wraps a value in a Locked
protected by this lock.
This function clones the Lock
which makes it about as expensive as cloning an
Arc
. Note that this is much more expensive than creating an ordinary mutex.
§Example
use shared_lock::Lock;
let lock = Lock::default();
let locked = lock.wrap(5);
let guard = &lock.lock();
assert_eq!(*locked.get(guard), 5);