[src]

Trait std::kinds::Share

pub trait Share { }

Types that can be safely shared between tasks when aliased.

The precise definition is: a type T is Share if &T is thread-safe. In other words, there is no possibility of data races when passing &T references between tasks.

As one would expect, primitive types like u8 and f64 are all Share, and so are simple aggregate types containing them (like tuples, structs and enums). More instances of basic Share types include "immutable" types like &T and those with simple inherited mutability, such as ~T, Vec<T> and most other collection types. (Generic parameters need to be Share for their container to be Share.)

A somewhat surprising consequence of the definition is &mut T is Share (if T is Share) even though it seems that it might provide unsynchronised mutation. The trick is a mutable reference stored in an aliasable reference (that is, & &mut T) becomes read-only, as if it were a & &T, hence there is no risk of a data race.

Types that are not Share are those that have "interior mutability" in a non-thread-safe way, such as Cell and RefCell in std::cell. These types allow for mutation of their contents even when in an immutable, aliasable slot, e.g. the contents of &Cell<T> can be .set, and do not ensure data races are impossible, hence they cannot be Share. A higher level example of a non-Share type is the reference counted pointer std::rc::Rc, because any reference &Rc<T> can clone a new reference, which modifies the reference counts in a non-atomic way.

For cases when one does need thread-safe interior mutability, types like the atomics in std::sync and Mutex & RWLock in the sync crate do ensure that any mutation cannot cause data races. Hence these types are Share.

Users writing their own types with interior mutability (or anything else that is not thread-safe) should use the NoShare marker type (from std::kinds::marker) to ensure that the compiler doesn't consider the user-defined type to be Share. Any types with interior mutability must also use the std::ty::Unsafe wrapper around the value(s) which can be mutated when behind a & reference; not doing this is undefined behaviour (for example, transmute-ing from &T to &mut T is illegal).