]> git.proxmox.com Git - rustc.git/blob - src/doc/nomicon/src/send-and-sync.md
New upstream version 1.17.0+dfsg1
[rustc.git] / src / doc / nomicon / src / send-and-sync.md
1 # Send and Sync
2
3 Not everything obeys inherited mutability, though. Some types allow you to
4 multiply alias a location in memory while mutating it. Unless these types use
5 synchronization to manage this access, they are absolutely not thread safe. Rust
6 captures this through the `Send` and `Sync` traits.
7
8 * A type is Send if it is safe to send it to another thread.
9 * A type is Sync if it is safe to share between threads (`&T` is Send).
10
11 Send and Sync are fundamental to Rust's concurrency story. As such, a
12 substantial amount of special tooling exists to make them work right. First and
13 foremost, they're [unsafe traits]. This means that they are unsafe to
14 implement, and other unsafe code can assume that they are correctly
15 implemented. Since they're *marker traits* (they have no associated items like
16 methods), correctly implemented simply means that they have the intrinsic
17 properties an implementor should have. Incorrectly implementing Send or Sync can
18 cause Undefined Behavior.
19
20 Send and Sync are also automatically derived traits. This means that, unlike
21 every other trait, if a type is composed entirely of Send or Sync types, then it
22 is Send or Sync. Almost all primitives are Send and Sync, and as a consequence
23 pretty much all types you'll ever interact with are Send and Sync.
24
25 Major exceptions include:
26
27 * raw pointers are neither Send nor Sync (because they have no safety guards).
28 * `UnsafeCell` isn't Sync (and therefore `Cell` and `RefCell` aren't).
29 * `Rc` isn't Send or Sync (because the refcount is shared and unsynchronized).
30
31 `Rc` and `UnsafeCell` are very fundamentally not thread-safe: they enable
32 unsynchronized shared mutable state. However raw pointers are, strictly
33 speaking, marked as thread-unsafe as more of a *lint*. Doing anything useful
34 with a raw pointer requires dereferencing it, which is already unsafe. In that
35 sense, one could argue that it would be "fine" for them to be marked as thread
36 safe.
37
38 However it's important that they aren't thread safe to prevent types that
39 contain them from being automatically marked as thread safe. These types have
40 non-trivial untracked ownership, and it's unlikely that their author was
41 necessarily thinking hard about thread safety. In the case of Rc, we have a nice
42 example of a type that contains a `*mut` that is definitely not thread safe.
43
44 Types that aren't automatically derived can simply implement them if desired:
45
46 ```rust
47 struct MyBox(*mut u8);
48
49 unsafe impl Send for MyBox {}
50 unsafe impl Sync for MyBox {}
51 ```
52
53 In the *incredibly rare* case that a type is inappropriately automatically
54 derived to be Send or Sync, then one can also unimplement Send and Sync:
55
56 ```rust
57 #![feature(optin_builtin_traits)]
58
59 // I have some magic semantics for some synchronization primitive!
60 struct SpecialThreadToken(u8);
61
62 impl !Send for SpecialThreadToken {}
63 impl !Sync for SpecialThreadToken {}
64 ```
65
66 Note that *in and of itself* it is impossible to incorrectly derive Send and
67 Sync. Only types that are ascribed special meaning by other unsafe code can
68 possible cause trouble by being incorrectly Send or Sync.
69
70 Most uses of raw pointers should be encapsulated behind a sufficient abstraction
71 that Send and Sync can be derived. For instance all of Rust's standard
72 collections are Send and Sync (when they contain Send and Sync types) in spite
73 of their pervasive use of raw pointers to manage allocations and complex ownership.
74 Similarly, most iterators into these collections are Send and Sync because they
75 largely behave like an `&` or `&mut` into the collection.
76
77 TODO: better explain what can or can't be Send or Sync. Sufficient to appeal
78 only to data races?
79
80 [unsafe traits]: safe-unsafe-meaning.html