Arc

Struct Arc 

Source
pub struct Arc<T, S: Strategy> { /* private fields */ }
Expand description

Transferable reference counted type.

This type works like a per-affinity (per-thread) sync::Arc. Each affinity gets a unique value that is shared by clones of the Arc, but the ThreadAware implementation ensures that when moving to another affinity, the resulting Arc will point to the value in the destination affinity. See new for information on constructing instances.

ThreadAware of different clones of the Arc result in “deduplication” in the destination affinity. The following example demonstrates this using the counter implemented in the documentation for the ThreadAware trait.


let arc_affinity1 = Arc::<_, PerCore>::new(Counter::new);
let arc_affinity1_clone = arc_affinity1.clone();

arc_affinity1.increment_by(42);
assert_eq!(arc_affinity1.value(), 42);

let arc_affinity2 = arc_affinity1.relocated(affinity1, affinity2);
assert_eq!(arc_affinity2.value(), 0);
assert_eq!(arc_affinity1_clone.value(), 42);

arc_affinity2.increment_by(11);
let arc_affinity2_clone = arc_affinity1_clone.relocated(affinity1, affinity2);
assert_eq!(arc_affinity2_clone.value(), 11);

Implementations§

Source§

impl<T, S> Arc<T, S>
where T: Send + 'static, S: Strategy,

Source

pub fn new(ctor: fn() -> T) -> Self

Creates a new Arc with the given value and strategy.

This variant takes a zero-argument constructor function (fn() -> T). The constructor is invoked lazily and independently for each processor the first time a PerCore is materialized on that processor (i.e. on the first transfer into that processor). This guarantees that every processor obtains its own freshly created T without requiring T: Clone or T: ThreadAware.

Requirements:

  • T must be Send + 'static so it can live in the processor storage.
  • The provided function must be pure with respect to per-processor isolation (it should not leak references into other processors). Any captured state should therefore be provided via globally shareable mechanisms or prefer new_with if you need to capture data that itself implements ThreadAware.

When transferring to another affinity which doesn’t yet contain a value, the constructor is called in the destination affinity to create a brand new instance.

For example, the counter type we implemented in the documentation for ThreadAware trait can be used with new by passing the constructor function (note the absence of ()):


let container = Arc::<_, PerCore>::new(Counter::new);
let container_clone = container.clone();
container.increment_by(42);
assert_eq!(container.value(), 42);
assert_eq!(container_clone.value(), 42);
Source§

impl<T, S> Arc<T, S>
where T: 'static, S: Strategy,

Source

pub fn new_with<D>(data: D, f: fn(D) -> T) -> Self
where D: ThreadAware + Send + Sync + Clone + 'static,

Creates a new Arc with a closure that will be called once per-processor to create the inner value.

The closure only gets called once for each processor, and it’s called only when a Arc is actually transferred to another processor. The closure behaves like a RelocateFnOnce to ensure it captures only values that are safe to transfer themselves.

This function can be used to create a Arc of a type that itself doesn’t implement ThreadAware because we can ensure that each affinity will get its own, independenty-initialized value:

struct MyStruct {
    inner: sync::Arc<Mutex<i32>>,
}

impl MyStruct {
    fn new() -> Self {
        Self {
            inner: sync::Arc::new(Mutex::new(0)),
        }
    }
}

let container = Arc::<_, PerCore>::new_with((), |_| MyStruct::new());

The constructor can depend on other values that implement ThreadAware (this example uses the Counter defined in ThreadAware documentation):


struct MyStruct;

impl MyStruct {
    fn new(value: i32) -> Self {
        Self
    }
}

let counter = Counter::new();
let container = Arc::<_, PerCore>::new_with(counter, |counter| MyStruct::new(counter.value()));
Source§

impl<T, S: Strategy> Arc<T, S>
where T: Clone + 'static + Send,

Source

pub fn from_unaware(value: T) -> Self

Creates a new Arc with the given value.

The value must implement Clone. When transferring to another affinity which doesn’t yet contain a value, a new value is created by cloning the value in current affinity and transferring it to the new affinity.

This is useful for types that do not implement ThreadAware. In such cases, the same value is cloned for each affinity without any relocation logic.

For example, the counter type we implemented in the documentation for ThreadAware trait can be used with new:


let arc = Arc::<_, PerCore>::new(Counter::new);
let arc_clone = arc.clone();
arc.increment_by(42);
assert_eq!(arc.value(), 42);
assert_eq!(arc_clone.value(), 42);
Source§

impl<T, S: Strategy> Arc<T, S>
where T: 'static,

Source

pub fn from_storage( storage: Arc<RwLock<Storage<Arc<T>, S>>>, current_affinity: PinnedAffinity, ) -> Self

Creates a new Arc from the given storage and the current affinity.

If the resulting Arc is transferred to an affinity which does not have data in the storage, it will behave like a sync::Arc.

§Panics

This may panic if the storage does not contain data for the current affinity.

Source§

impl<T, S: Strategy> Arc<T, S>

Source

pub fn into_arc(self) -> Arc<T>

Converts the Arc<T, S> into an sync::Arc<T>.

Trait Implementations§

Source§

impl<T, S: Strategy> Clone for Arc<T, S>

Source§

fn clone(&self) -> Self

Returns a duplicate 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: Debug, S: Debug + Strategy> Debug for Arc<T, S>

Source§

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

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

impl<T, S: Strategy> Deref for Arc<T, S>

Source§

type Target = T

The resulting type after dereferencing.
Source§

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

Dereferences the value.
Source§

impl<T: Hash, S: Strategy> Hash for Arc<T, S>

Source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<T: Ord, S: Strategy> Ord for Arc<T, S>

Source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

impl<T: PartialEq, S: Strategy> PartialEq for Arc<T, S>

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<T: PartialOrd, S: Strategy> PartialOrd for Arc<T, S>

Source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

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

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

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

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

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

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

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

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl<T, S: Strategy> ThreadAware for Arc<T, S>

Source§

fn relocated(self, source: MemoryAffinity, destination: PinnedAffinity) -> Self

Consume a value and return a value in the destination affinity. Read more
Source§

impl<T: Eq, S: Strategy> Eq for Arc<T, S>

Auto Trait Implementations§

§

impl<T, S> Freeze for Arc<T, S>

§

impl<T, S> !RefUnwindSafe for Arc<T, S>

§

impl<T, S> Send for Arc<T, S>
where T: Sync + Send, S: Send + Sync,

§

impl<T, S> Sync for Arc<T, S>
where T: Sync + Send, S: Send + Sync,

§

impl<T, S> Unpin for Arc<T, S>

§

impl<T, S> !UnwindSafe for Arc<T, S>

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.