sync_wrapper

Struct SyncWrapper

Source
pub struct SyncWrapper<T>(/* private fields */);
Expand description

A mutual exclusion primitive that relies on static type information only

In some cases synchronization can be proven statically: whenever you hold an exclusive &mut reference, the Rust type system ensures that no other part of the program can hold another reference to the data. Therefore it is safe to access it even if the current thread obtained this reference via a channel. Whenever this is the case, the overhead of allocating and locking a Mutex can be avoided by using this static version.

One example where this is often applicable is Future, which requires an exclusive reference for its poll method: While a given Future implementation may not be safe to access by multiple threads concurrently, the executor can only run the Future on one thread at any given time, making it Sync in practice as long as the implementation is Send. You can therefore use the static mutex to prove that your data structure is Sync even though it contains such a Future.

§Example

use sync_wrapper::SyncWrapper;
use std::future::Future;

struct MyThing {
    future: SyncWrapper<Box<dyn Future<Output = String> + Send>>,
}

impl MyThing {
    // all accesses to `self.future` now require an exclusive reference or ownership
}

fn assert_sync<T: Sync>() {}

assert_sync::<MyThing>();

Implementations§

Source§

impl<T> SyncWrapper<T>

Source

pub const fn new(value: T) -> Self

Creates a new static mutex containing the given value.

§Examples
use sync_wrapper::SyncWrapper;

let mutex = SyncWrapper::new(42);
Source

pub fn get_mut(&mut self) -> &mut T

Acquires a reference to the protected value.

This is safe because it requires an exclusive reference to the mutex. Therefore this method neither panics nor does it return an error. This is in contrast to Mutex::get_mut which returns an error if another thread panicked while holding the lock. It is not recommended to send an exclusive reference to a potentially damaged value to another thread for further processing.

§Examples
use sync_wrapper::SyncWrapper;

let mut mutex = SyncWrapper::new(42);
let value = mutex.get_mut();
*value = 0;
assert_eq!(*mutex.get_mut(), 0);
Source

pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T>

Acquires a pinned reference to the protected value.

See Self::get_mut for why this method is safe.

§Examples
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};

use pin_project_lite::pin_project;
use sync_wrapper::SyncWrapper;

pin_project! {
    struct FutureWrapper<F> {
        #[pin]
        inner: SyncWrapper<F>,
    }
}

impl<F: Future> Future for FutureWrapper<F> {
    type Output = F::Output;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        self.project().inner.get_pin_mut().poll(cx)
    }
}
Source

pub fn into_inner(self) -> T

Consumes this mutex, returning the underlying data.

This is safe because it requires ownership of the mutex, therefore this method will neither panic nor does it return an error. This is in contrast to Mutex::into_inner which returns an error if another thread panicked while holding the lock. It is not recommended to send an exclusive reference to a potentially damaged value to another thread for further processing.

§Examples
use sync_wrapper::SyncWrapper;

let mut mutex = SyncWrapper::new(42);
assert_eq!(mutex.into_inner(), 42);

Trait Implementations§

Source§

impl<T> Debug for SyncWrapper<T>

Source§

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

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

impl<T: Default> Default for SyncWrapper<T>

Source§

fn default() -> Self

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

impl<T> From<T> for SyncWrapper<T>

Source§

fn from(value: T) -> Self

Converts to this type from the input type.
Source§

impl<T> Sync for SyncWrapper<T>

Auto Trait Implementations§

§

impl<T> Freeze for SyncWrapper<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for SyncWrapper<T>
where T: RefUnwindSafe,

§

impl<T> Send for SyncWrapper<T>
where T: Send,

§

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

§

impl<T> UnwindSafe for SyncWrapper<T>
where T: UnwindSafe,

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<!> for T

Source§

fn from(t: !) -> T

Converts to this type from the input type.
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.