@@ -40,7 +40,51 @@ pub trait Pod {
40
40
// Empty.
41
41
}
42
42
43
- /// Types that can be safely shared between threads, hence thread-safe.
43
+ /// Types that can be safely shared between tasks when aliased.
44
+ ///
45
+ /// The precise definition is: a type `T` is `Share` if `&T` is
46
+ /// thread-safe. In other words, there is no possibility of data races
47
+ /// when passing `&T` references between tasks.
48
+ ///
49
+ /// As one would expect, primitive types like `u8` and `f64` are all
50
+ /// `Share`, and so are simple aggregate types containing them (like
51
+ /// tuples, structs and enums). More instances of basic `Share` types
52
+ /// include "immutable" types like `&T` and those with simple
53
+ /// inherited mutability, such as `~T`, `Vec<T>` and most other
54
+ /// collection types. (Generic parameters need to be `Share` for their
55
+ /// container to be `Share`.)
56
+ ///
57
+ /// A somewhat surprising consequence of the definition is `&mut T` is
58
+ /// `Share` (if `T` is `Share`) even though it seems that it might
59
+ /// provide unsynchronised mutation. The trick is a mutable reference
60
+ /// stored in an aliasable reference (that is, `& &mut T`) becomes
61
+ /// read-only, as if it were a `& &T`, hence there is no risk of a data
62
+ /// race.
63
+ ///
64
+ /// Types that are not `Share` are those that have "interior
65
+ /// mutability" in a non-thread-safe way, such as `Cell` and `RefCell`
66
+ /// in `std::cell`. These types allow for mutation of their contents
67
+ /// even when in an immutable, aliasable slot, e.g. the contents of
68
+ /// `&Cell<T>` can be `.set`, and do not ensure data races are
69
+ /// impossible, hence they cannot be `Share`. A higher level example
70
+ /// of a non-`Share` type is the reference counted pointer
71
+ /// `std::rc::Rc`, because any reference `&Rc<T>` can clone a new
72
+ /// reference, which modifies the reference counts in a non-atomic
73
+ /// way.
74
+ ///
75
+ /// For cases when one does need thread-safe interior mutability,
76
+ /// types like the atomics in `std::sync` and `Mutex` & `RWLock` in
77
+ /// the `sync` crate do ensure that any mutation cannot cause data
78
+ /// races. Hence these types are `Share`.
79
+ ///
80
+ /// Users writing their own types with interior mutability (or anything
81
+ /// else that is not thread-safe) should use the `NoShare` marker type
82
+ /// (from `std::kinds::marker`) to ensure that the compiler doesn't
83
+ /// consider the user-defined type to be `Share`. Any types with
84
+ /// interior mutability must also use the `std::ty::Unsafe` wrapper
85
+ /// around the value(s) which can be mutated when behind a `&`
86
+ /// reference; not doing this is undefined behaviour (for example,
87
+ /// `transmute`-ing from `&T` to `&mut T` is illegal).
44
88
#[ lang="share" ]
45
89
pub trait Share {
46
90
// Empty
0 commit comments