Hacker News new | ask | show | jobs
by gohbgl 1929 days ago
What is the bug? I don't see it.
1 comments

The bug is that the closure is mutating the same data structure (a Vec in this case) in a different thread - i.e., a data race.

In this specific case, only the spawned thread is mutating the Vec, but the Rust compiler is usually conservative, so it marked this as a bug.

The actual bug is one or both of the following:

1. One of the threads could cause the underlying Vec to reallocate/resize while other threads are accessing it.

2. One of the threads could drop (free) the Vec while other threads are using it.

In Rust, only one thread can “own” a data structure. This is enforced through the Send trait (edit: this is probably wrong, will defer to a Rust expert here).

In addition, you cannot share a mutable reference (pointer) to the same data across threads without synchronization. This is enforced through the Sync trait.

There are two common solutions here:

1. Clone the Vec and pass that to the thread. In other words, each thread gets its own copy of the data.

2. Wrap the Vec in a Mutex and a Arc - your type becomes a Arc<Mutex<Vec<String>>>. You can then clone() the data and pass it to the new thread. Under the hood, this maps to an atomic increment instead of a deep clone of the underlying data like in (1).

The Mutex implements the Sync trait, which allows multiple threads to mutate the data. The Arc (atomic ref count) allows the compiler to guarantee that the Vec is dropped (freed) exactly once.