Struct MutexSync

Source
pub struct MutexSync<K>
where K: 'static + Sync + Send + Clone + Hash + Ord,
{ /* private fields */ }
Expand description

Task executor that can synchronise tasks by value of a key provided when submitting a task.

For example, if i32 is used as key type, then tasks submitted with keys 3 and 5 may run concurrently but several tasks submitted with key 7 are synchronised by a mutex mapped to the key.

Manages a concurrent hash map that maps ReferenceCountedMutex elements to the used keys. The ReferenceCountedMutex struct holds a mutex used for synchronisation and removes itself from the map automatically if not used by any thread anymore by managing an atomic reference counter. If the counter is decremented from 1 to 0 the element is removed from the map and the counter cannot be incremented back up again. If the counter reached 0 future increments fail and a new ReferenceCountedMutex is created instead. When creating a new ReferenceCountedMutex and inserting it to the map fails because another thread has already created an element for the same key, the current thread tries to use the found existing element instead as long as its reference counter is valid (greater than 0), else it retries creating the element.

The type of the key used for synchronisation must be able to be used as a key for the map and thus must implement Sync + Send + Clone + Hash + Ord and have a static lifetime.

Implementations§

Source§

impl<K> MutexSync<K>
where K: 'static + Sync + Send + Clone + Hash + Ord,

Source

pub fn new() -> Self

Source

pub fn evaluate<R, F: FnOnce() -> R>(&self, key: K, task: F) -> R

Submits a task for execution using the provided key for synchronisation. Uses the mutex of the ReferenceCountedMutex mapped to the key to synchronise execution of the task. The ReferenceCountedMutex removes itself from the map automatically as soon as no thread is using it anymore by managing an atomic reference counter.

If the mutex map does not already contain an entry for the provided key, meaning no task is currently running with a mutex mapped to the same key, the current thread attempts to insert a new ReferenceCountedMutex, with an initial reference count of 1, and if it succeeds acquires the mutex and runs the task, else it tries to use the found existing ReferenceCountedMutex if its reference counter is valid (greater than 0) or else retries creating the ReferenceCountedMutex.

If the mutex map already contains a ReferenceCountedMutex mapped to the same key, meaning there are threads running using the same key, the current thread attempts to increment the reference counter on the found ReferenceCountedMutex and if it succeeds it waits to acquire the mutex and then executes the task, if it fails, because the counter has been decremented to 0 because another thread is in the process of removing the mutex from the map, it tries to create a new ReferenceCountedMutex, same as above.

Trait Implementations§

Source§

impl<K> Default for MutexSync<K>
where K: 'static + Sync + Send + Clone + Hash + Ord,

Source§

fn default() -> Self

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

Auto Trait Implementations§

§

impl<K> !Freeze for MutexSync<K>

§

impl<K> !RefUnwindSafe for MutexSync<K>

§

impl<K> Send for MutexSync<K>

§

impl<K> Sync for MutexSync<K>

§

impl<K> Unpin for MutexSync<K>

§

impl<K> !UnwindSafe for MutexSync<K>

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> 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, 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.