Question on mpsc::channel implementation

Hi Rust experts,

I am trying to understand how mpsc::channels work. https://github.com/rust-lang/rust/blob/master/src/libstd/sync/mpsc/mod.rs

I found that Sender and Receiver is implemented similarly:

pub struct Sender<T> {
    inner: UnsafeCell<Flavor<T>>,
}

And Flavor is:

enum Flavor<T> {
    Oneshot(Arc<UnsafeCell<oneshot::Packet<T>>>),
    Stream(Arc<UnsafeCell<stream::Packet<T>>>),
    Shared(Arc<UnsafeCell<shared::Packet<T>>>),
    Sync(Arc<UnsafeCell<sync::Packet<T>>>),
}

With my limited understanding I see the role of Arc and UnsafeCell. Based on the above I assume that Sender and Receiver encapsulates a type like UnsafeCell<Arc<UnsafeCell<T>>>.

Can someone please explain what the second, outer UnsafeCell is doing here? Why can't the Sender be like?:

pub struct Sender<T> {
    inner: Flavor<T>,
}

Thank you, David

The channel type is changed dynamically, based on how it is used, so the flavour needs to change. The desire is to have this all happen while shared (i.e. inside &self methods, like clone) and so interior mutability is necessary, which is what UnsafeCell provides.

3 Likes

Thank you, makes sense to me now.