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
Rcis only!Sendinsofar a single ownedRcinstance, crossing the thread boundary,
in isolation
, 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 "
Rcflock" 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 aCell<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].