JoinHandle::join()

I return JoinHandle from this fn.

pub fn reader_start(receiver : crossbeam_channel::Receiver<messages::ReaderMsg>, p_sock : Arc<socket2::Socket>) -> thread::JoinHandle<()>{
    let join_handle = thread::spawn(  move || {
        reader_run(receiver, &p_sock);
    });
    return join_handle;
}

I put that is a struct in the calling module and when I terminate I want to call join() but can't make that work. I just added it below to show the error. I'm using is_finished() at the moment which does work but the wrong way to do it. I know I've had these same errors a lot now but still failed to find a solution.

while join_thrd.is_finished() == false {
                    thread::sleep(Duration::from_millis(100));
                }
                join_thrd.join(); 

error[E0507]: cannot move out of *join_thrd which is behind a mutable reference
--> src\udp\udp_man.rs:142:17
|
142 | join_thrd.join();
| ^^^^^^^^^^------
| | |
| | *join_thrd moved due to this method call
| move occurs because *join_thrd has type JoinHandle<()>, which does not implement the Copy trait
note: this function takes ownership of the receiver self, which moves *join_thrd

The function JoinHandle::join() takes argument by self, meaning it takes ownership of the value. While as I understand you pass the struct by a mutable reference, and so you cannot move out of it. What you can do is instead of storing JoinHandle, store Option<JoinHandle>. Initialize it to Some(join_handle). Then, do an Option::take() to take the value and leave behind a None. Then finally you can call join on the value returned by Option::take().

2 Likes

Thanks, that's another new one for me. I guess as its only used once that ploy works. Finally I think I can get on with some straight forward coding. I hope!