Why can I not hand a mpsc::Receiver to a spawned thread?

Viewed 65

Here is the code that wont compile.

use std::{
    sync::{
        mpsc::{self, Receiver, Sender},
        Arc,
    },
    thread,
};

struct S1 {
    rx: Receiver<i32>,
}

pub struct S2 {
    inner: Arc<S1>,
    tx: Sender<i32>,
}

impl S2 {
    pub fn new() -> S2 {
        let (tx, rx): (Sender<i32>, Receiver<i32>) = mpsc::channel();
        let st1 = S1 { rx };
        let st2 = S2 {
            tx,
            inner: Arc::new(st1),
        };
        st2
    }

    pub fn start(&mut self) {
        let inner = &self.inner.clone();
        let _jh = thread::spawn(move || loop {
            inner.rx.recv().unwrap();
        });
    }
}

fn main() {}

S2 is the client-visible code and S1 is the internal state maintained by the backend thread. This seems to be a common Rust idiom.

Here is the error:

error[E0277]: `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely
   --> src/main.rs:31:19
    |
31  |         let _jh = thread::spawn(move || loop {
    |                   ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely
    |
    = help: within `S1`, the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Receiver<i32>`
    = note: required because it appears within the type `S1`
    = note: required because of the requirements on the impl of `std::marker::Sync` for `std::sync::Arc<S1>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::Arc<S1>`
    = note: required because it appears within the type `[closure@src/main.rs:31:33: 33:10 inner:&std::sync::Arc<S1>]`

This is not a duplicate of Why do I get an error that "Sync is not satisfied" when moving self, which contains an Arc, into a new thread?. I don't care if I have the Arc or not. I just want my constructor of the client visible thing (S2) to create a channel and have the send on the client side and the receiver in the background thread. I can find no way of doing that.

0 Answers
Related