Struct Lock

Source
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

Source

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 a Guard 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());
Source

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 a Guard 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());
Source

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());
Source

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));
Source

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();
});
Source

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();
Source

pub unsafe fn make_guard_unchecked(&self) -> Guard<'_>

Creates a new Guard without checking if the lock is held.

§Safety
  • The invariant that each Guard owns a ticket must be upheld whenever a Guard is used or dropped.
§Example
use std::mem;
use shared_lock::Lock;

let lock = Lock::default();
mem::forget(lock.lock());
// SAFETY: This recovers the guard we just forgot.
let _guard = unsafe {
    lock.make_guard_unchecked()
};
Source

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();
});
Source

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();
});
Source

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

Source

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);

Trait Implementations§

Source§

impl Clone for Lock

Source§

fn clone(&self) -> Lock

Returns a duplicate of the value. Read more
1.0.0 · Source§

const fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Lock

Source§

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

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

impl Default for Lock

Source§

fn default() -> Lock

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

impl PartialEq for Lock

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Eq for Lock

Source§

impl Send for Lock

Source§

impl Sync for Lock

Auto Trait Implementations§

§

impl Freeze for Lock

§

impl !RefUnwindSafe for Lock

§

impl Unpin for Lock

§

impl !UnwindSafe for Lock

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.