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.