You are right, it is not obvious.
Basically, it's a question of whether the channel behaves like a Relaxed
memory ordering, or like a Release
/Acquire
ordering, where these ordering names come from the Ordering
enum used with atomic integers. With Relaxed
, you can't rely on it, but with Release
/Acquire
, you can.
I can make an analogy to another form of "message passing" where you absolutely would expect analogous behavior. Consider this:
shared_mem = new_value;
mutex.unlock();
in one thread, and
mutex.lock();
let new_value = shared_mem;
in the other. Here, I call the lock
/unlock
methods in the style you would see in C or C++, to make the analogy more clear. In the above case, you would absolutely expect that, if the second thread starts to try to acquire the lock while the first thread has the lock, the second thread will see whatever value the first thread wrote to the shared memory.
Here the "message" is that the lock is unlocked, and the blocking .lock()
call corresponds to the blocking .recv()
call in the original post.
Of course, this requires knowing that crossbeam actually corresponds to Release
/Acquire
orderings. See e.g. this comment from conversations regarding the issue I linked earlier with some other channel.