Using a boxed non-Send type between threads

I am using a library that provides the Sample trait with impls for i8, i16, i32 and f32 (hound, a WAV codec). I would like to send a boxed vector of samples down a std::sync::mpsc::channel<Box<Vec<Sample>>> but because Sample is not marked Send, it 'cannot be sent between threads safely'.

I'm a bit confused because it's the boxed vector I want to send, but I assume the compiler is worried that a reference to a Sample might be taken in another thread? I'm not sure. Wrapping the vector in a boxed mutex is not enough for the compiler either.

To move forward I've made the code non-generic, forcing everything to be i16, but I can't quite figure out the correct way to keep it generic. Do I define my own type that is Send and implement the Into trait for converting Sample? Is there a way I can limit the generic type to be one of i8, i16 etc in the where clause, maybe with the num crate? Or is there a more idiomatic way that I haven't been able to discover?

Edit: code sample for context

fn test_thread<T>()
where T: hound::Sample
{
    let (tx, rx) = mpsc::channel::<Box<Vec<T>>>();
    let thread = thread::spawn(move|| {
        loop {
            let samples = rx.recv().unwrap();
            for _sample in samples.iter() {
                // Do something
            }
        }
    });
}

Could you possibly make your channel type std::sync::mpsc::channel<Box<Vec<Sample+Send>>>?

1 Like

I've edited my question to give more context. Adding Send to type T now produces the error that T might not live long enough, even though I want the vector to own T, the box to own the vector, and the channel to own the box.

Then it will contain Sample + Send + 'static, so that the inner items themselves own everything they need.