+// **Exercise 13.1**: Change rgrep such that it prints not only the matching lines, but also the
+// name of the file and the number of the line in the file. You will have to change the type of the
+// channels from `String` to something that records this extra information.
+
+//@ ## Ownership, Borrowing, and Concurrency
+//@ The little demo above showed that concurrency in Rust has a fairly simple API. Considering Rust
+//@ has closures, that should not be entirely surprising. However, as it turns out, Rust goes well
+//@ beyond this and actually ensures the absence of data races. <br/>
+//@ A data race is typically defined as having two concurrent, unsynchronized accesses to the same
+//@ memory location, at least one of which is a write. In other words, a data race is mutation in
+//@ the presence of aliasing, which Rust reliably rules out! It turns out that the same mechanism
+//@ that makes our single-threaded programs memory safe, and that prevents us from invalidating
+//@ iterators, also helps secure our multi-threaded code against data races. For example, notice
+//@ how `read_files` sends a `String` to `filter_lines`.
+//@ At run-time, only the pointer to the character data will actually be moved around (just like
+//@ when a `String` is passed to a function with full ownership). However, `read_files` has to
+//@ *give up* ownership of the string to perform `send`, to it is impossible for the string to
+//@ still be borrowed. After it sent the string to the other side, `read_files` has no pointer into
+//@ the string content anymore, and hence no way to race on the data with someone else.
+//@
+//@ There is a little more to this. Remember the `'static` bound we had to add to `register` in the
+//@ previous parts, to make sure that the callbacks do not reference any pointers that might become
+//@ invalid? This is just as crucial for spawning a thread: In general, that thread could last for
+//@ much longer than the current stack frame. Thus, it must not use any pointers to data in that
+//@ stack frame. This is achieved by requiring the `FnOnce` closure passed to `thread::spawn` to be
+//@ valid for lifetime `'static`, as you can see in
+//@ [its documentation](https://doc.rust-lang.org/stable/std/thread/fn.spawn.html). This avoids
+//@ another kind of data race, where the thread's access races with the callee deallocating its
+//@ stack frame. It is only thanks to the concept of lifetimes that this can be expressed as part
+//@ of the type of `spawn`.
+
+//@ ## Send
+//@ However, the story goes even further. I said above that `Arc` is a thread-safe version of `Rc`,
+//@ which uses atomic operations to manipulate the reference count. It is thus crucial that we
+//@ don't use `Rc` across multiple threads, or the reference count may become invalid. And indeed,
+//@ if you replace `Arc` by `Rc` (and add the appropriate imports), Rust will tell you that
+//@ something is wrong. That's great, of course, but how did it do that?
+//@
+//@ The answer is already hinted at in the error: It will say something about `Send`. You may have
+//@ noticed that the closure in `thread::spawn` does not just have a `'static` bound, but also has
+//@ to satisfy `Send`. `Send` is a trait, and just like `Copy`, it's just a marker - there are no
+//@ functions provided by `Send`. What the trait says is that types which are `Send` can be safely
+//@ sent to another thread without causing trouble.
+//@ Of course, all the primitive data-types are `Send`. So is `Arc`, which is why Rust accepted our
+//@ code. But `Rc` is not `Send`, and for a good reason! If had two `Rc` to the same data, and sent
+//@ one of them to another thread, things could go havoc due to the lack of synchronization.
+//@
+//@ Now, `Send` as a trait is fairly special. It has a so-called *default implementation*. This
+//@ means that *every type* implements `Send`, unless it opts out. Opting out is viral: If your
+//@ type contains a type that opted out, then you don't have `Send`, either. So if the environment
+//@ of your closure contains an `Rc`, it won't be `Send`, preventing it from causing trouble. If
+//@ however every captured variable *is* `Send`, then so is the entire environment, and you are
+//@ good.
+
+//@ [index](main.html) | [previous](part12.html) | [raw source](workspace/src/part13.rs) |
+//@ [next](part14.html)