Struct DataReference

Source
pub struct DataReference<T> { /* private fields */ }
Expand description

Atomic, reference counted pointer to data stored within an [MbarcMap].

A valid copy of DataReference should imply valid data being pointed to, regardless of the status of the owning [MbarcMap].

§Examples

//In this snippet, Arc isn't really necessary, however it's generally recommended to wrap MbarcMap in an Arc as threading is its main use case
//Very important to note that you do not need to wrap MbarcMap in a Mutex, and doing so is redundant
use std::sync::{Arc, MutexGuard};
use mbarc_map::{DataReference, MbarcMap};

let concurrent_map = Arc::new(MbarcMap::new());

let key: i64 = 2;
let value: &str = "Hi";
concurrent_map.insert(key, value);

//Retrieve the item we just put into the map, then drop the map itself
let first_value: Option<DataReference<&str>> = concurrent_map.get(&key);
drop(concurrent_map);

//Actual data reference
let first_value: DataReference<&str> = first_value.unwrap();

//Since the map no longer exists, the only reference left is the one we're still holding
assert_eq!(first_value.ref_count(), 1);
//When the map is dropped all values within are marked as deleted (also the case if the individual item had been removed instead)
assert!(first_value.is_marked_deleted());

//All values within this map are individually wrapped in a Mutex implicitly
//DataReference derefs to this Mutex, and locking is necessary to actually interact with the value
let first_value_lock: MutexGuard<&str> = first_value.lock().unwrap();
assert_eq!(*first_value_lock, "Hi");

Implementations§

Source§

impl<T> DataReference<T>

Source

pub fn is_marked_deleted(&self) -> bool

Has the individual element been marked as deleted?

If this is true, that means this element has been removed from the owning [MbarcMap]. The actual data won’t, however, be dropped until all references are gone.

Important to note that this could change at any time, even if a lock is taken on the actual data itself. You should not rely on this being 100% up-to-date in threaded code, but once this function returns true, it will not become false again.

Source

pub fn ref_count(&self) -> usize

Get a count of references to the pointed-to data.

It is possible that this number can change even in the time it takes for this function to return. You should not rely on this being 100% up-to-date in threaded code.

Methods from Deref<Target = Mutex<T>>§

Source

pub fn get_cloned(&self) -> Result<T, PoisonError<()>>
where T: Clone,

🔬This is a nightly-only experimental API. (lock_value_accessors)

Returns the contained value by cloning it.

§Errors

If another user of this mutex panicked while holding the mutex, then this call will return an error instead.

§Examples
#![feature(lock_value_accessors)]

use std::sync::Mutex;

let mut mutex = Mutex::new(7);

assert_eq!(mutex.get_cloned().unwrap(), 7);
Source

pub fn set(&self, value: T) -> Result<(), PoisonError<T>>

🔬This is a nightly-only experimental API. (lock_value_accessors)

Sets the contained value.

§Errors

If another user of this mutex panicked while holding the mutex, then this call will return an error containing the provided value instead.

§Examples
#![feature(lock_value_accessors)]

use std::sync::Mutex;

let mut mutex = Mutex::new(7);

assert_eq!(mutex.get_cloned().unwrap(), 7);
mutex.set(11).unwrap();
assert_eq!(mutex.get_cloned().unwrap(), 11);
Source

pub fn replace(&self, value: T) -> Result<T, PoisonError<T>>

🔬This is a nightly-only experimental API. (lock_value_accessors)

Replaces the contained value with value, and returns the old contained value.

§Errors

If another user of this mutex panicked while holding the mutex, then this call will return an error containing the provided value instead.

§Examples
#![feature(lock_value_accessors)]

use std::sync::Mutex;

let mut mutex = Mutex::new(7);

assert_eq!(mutex.replace(11).unwrap(), 7);
assert_eq!(mutex.get_cloned().unwrap(), 11);
1.0.0 · Source

pub fn lock(&self) -> Result<MutexGuard<'_, T>, PoisonError<MutexGuard<'_, T>>>

Acquires a mutex, blocking the current thread until it is able to do so.

This function will block the local thread until it is available to acquire the mutex. Upon returning, the thread is the only thread with the lock held. An RAII guard is returned to allow scoped unlock of the lock. When the guard goes out of scope, the mutex will be unlocked.

The exact behavior on locking a mutex in the thread which already holds the lock is left unspecified. However, this function will not return on the second call (it might panic or deadlock, for example).

§Errors

If another user of this mutex panicked while holding the mutex, then this call will return an error once the mutex is acquired. The acquired mutex guard will be contained in the returned error.

§Panics

This function might panic when called if the lock is already held by the current thread.

§Examples
use std::sync::{Arc, Mutex};
use std::thread;

let mutex = Arc::new(Mutex::new(0));
let c_mutex = Arc::clone(&mutex);

thread::spawn(move || {
    *c_mutex.lock().unwrap() = 10;
}).join().expect("thread::spawn failed");
assert_eq!(*mutex.lock().unwrap(), 10);
1.0.0 · Source

pub fn try_lock( &self, ) -> Result<MutexGuard<'_, T>, TryLockError<MutexGuard<'_, T>>>

Attempts to acquire this lock.

If the lock could not be acquired at this time, then Err is returned. Otherwise, an RAII guard is returned. The lock will be unlocked when the guard is dropped.

This function does not block.

§Errors

If another user of this mutex panicked while holding the mutex, then this call will return the Poisoned error if the mutex would otherwise be acquired. An acquired lock guard will be contained in the returned error.

If the mutex could not be acquired because it is already locked, then this call will return the WouldBlock error.

§Examples
use std::sync::{Arc, Mutex};
use std::thread;

let mutex = Arc::new(Mutex::new(0));
let c_mutex = Arc::clone(&mutex);

thread::spawn(move || {
    let mut lock = c_mutex.try_lock();
    if let Ok(ref mut mutex) = lock {
        **mutex = 10;
    } else {
        println!("try_lock failed");
    }
}).join().expect("thread::spawn failed");
assert_eq!(*mutex.lock().unwrap(), 10);
1.2.0 · Source

pub fn is_poisoned(&self) -> bool

Determines whether the mutex is poisoned.

If another thread is active, the mutex can still become poisoned at any time. You should not trust a false value for program correctness without additional synchronization.

§Examples
use std::sync::{Arc, Mutex};
use std::thread;

let mutex = Arc::new(Mutex::new(0));
let c_mutex = Arc::clone(&mutex);

let _ = thread::spawn(move || {
    let _lock = c_mutex.lock().unwrap();
    panic!(); // the mutex gets poisoned
}).join();
assert_eq!(mutex.is_poisoned(), true);
1.77.0 · Source

pub fn clear_poison(&self)

Clear the poisoned state from a mutex.

If the mutex is poisoned, it will remain poisoned until this function is called. This allows recovering from a poisoned state and marking that it has recovered. For example, if the value is overwritten by a known-good value, then the mutex can be marked as un-poisoned. Or possibly, the value could be inspected to determine if it is in a consistent state, and if so the poison is removed.

§Examples
use std::sync::{Arc, Mutex};
use std::thread;

let mutex = Arc::new(Mutex::new(0));
let c_mutex = Arc::clone(&mutex);

let _ = thread::spawn(move || {
    let _lock = c_mutex.lock().unwrap();
    panic!(); // the mutex gets poisoned
}).join();

assert_eq!(mutex.is_poisoned(), true);
let x = mutex.lock().unwrap_or_else(|mut e| {
    **e.get_mut() = 1;
    mutex.clear_poison();
    e.into_inner()
});
assert_eq!(mutex.is_poisoned(), false);
assert_eq!(*x, 1);

Trait Implementations§

Source§

impl<T> Clone for DataReference<T>

Source§

fn clone(&self) -> Self

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

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

Performs copy-assignment from source. Read more
Source§

impl<T> Deref for DataReference<T>

Source§

type Target = Mutex<T>

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl<T> Drop for DataReference<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<T: 'static> From<DataReference<T>> for DataReferenceGeneric

Source§

fn from(source: DataReference<T>) -> Self

Converts to this type from the input type.
Source§

impl<T: Sync + Send> Send for DataReference<T>

Source§

impl<T: Sync + Send> Sync for DataReference<T>

Auto Trait Implementations§

§

impl<T> Freeze for DataReference<T>

§

impl<T> RefUnwindSafe for DataReference<T>

§

impl<T> Unpin for DataReference<T>
where T: Unpin,

§

impl<T> UnwindSafe for DataReference<T>

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<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
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.