I want to create a thread inside of the new
method and stop it after the struct is destroyed:
use std::thread;
struct Foo {
handle: thread:
The function signature of JoinHandle::join is:
fn join(self) -> Result
This means that the method takes self
(the receiver object) by values (taking the ownership/consuming it). But you only have a borrow to your JoinHandle
; a mutable one, but still merely a borrow, not the ownership. Thus you can't call this method, because you can't move the ownership out of your borrow into this join()
method.
An easy way to fix that, is by accepting self
by value in the stop()
method, too:
pub fn stop(self) {
self.handle.join();
}
But you will notice that this isn't possible when implementing Drop
, because drop()
has the signature fn drop(&mut self)
! Bummer! But there is a little trick you can use, described below. Please be aware that joining threads in drop()
is probably not a good idea! Read Matthieu M.'s answer for more information on that!
If you still think, for whatever reason, that you really want to join a thread in drop()
, you can store the JoinHandle
in an Option
to save whether or not it's already joined. If you have a Some(T)
you can obtain a T
(by value!) from it by using the method Option::take(). Then you can write:
fn drop(&mut self) {
// `self.handle` has the type `Option>` here!
if let Some(handle) = self.handle.take() {
handle.join().expect("failed to join thread");
}
}