`Rc` is `!Send` but not thread-dependant?

Exactly:

It turns out there are two notions of thread-safety/single-threaded; one, OS-agnostic, concurrency-related, and one, OS-specific, about thread-based shenanigans.

  • Consider a thread_local!-based guard type; such a thing would be !Send, as in, it is to be "thread-pinned", no matter what.

  • But then something such as Rc is only !Send insofar a single owned Rc instance, crossing the thread boundary, :warning: in isolation :warning:, is prone to data races and thus unsoundness.

    But since the concern is merely race-condition related w.r.t. the "in isolation" thing, there is indeed a notion of an "Rc flock" of all the owners related to a piece of data. And when considered together, that whole "flock" is perfectly safe to cross thread-boundaries, much like a Cell<usize> : Send, for instance.

What all this shows is that we might be able to come up with some abstraction to allow for "newborn and properly-jailed Rcs" (e.g., in a Future task), to be usable by a work-stealing executor (i.e., wherein two successive .poll()s may be performed from distinct threads), but generalizing this pattern to all !Send types won't be possible, we'd need some other special marker trait to distinguish "flock-thread-safe"[1] from "thread-pinned" types[2].


  1. CSend in that post ↩︎

  2. TSend in that post ↩︎

5 Likes