Without stopping the thread when BackgroundProcessor is dropped, it will
run free. In the context of language bindings, it is difficult to know
how long references held by the thread should live. Implement Drop to
stop the thread just as is done when explicitly calling stop().
stop_thread: Arc<AtomicBool>,
/// May be used to retrieve and handle the error if `BackgroundProcessor`'s thread
/// exits due to an error while persisting.
stop_thread: Arc<AtomicBool>,
/// May be used to retrieve and handle the error if `BackgroundProcessor`'s thread
/// exits due to an error while persisting.
- pub thread_handle: JoinHandle<Result<(), std::io::Error>>,
+ pub thread_handle: Option<JoinHandle<Result<(), std::io::Error>>>,
- Self { stop_thread: stop_thread_clone, thread_handle: handle }
+ Self { stop_thread: stop_thread_clone, thread_handle: Some(handle) }
}
/// Stop `BackgroundProcessor`'s thread.
}
/// Stop `BackgroundProcessor`'s thread.
- pub fn stop(self) -> Result<(), std::io::Error> {
+ pub fn stop(mut self) -> Result<(), std::io::Error> {
+ assert!(self.thread_handle.is_some());
+ self.stop_and_join_thread()
+ }
+
+ fn stop_and_join_thread(&mut self) -> Result<(), std::io::Error> {
self.stop_thread.store(true, Ordering::Release);
self.stop_thread.store(true, Ordering::Release);
- self.thread_handle.join().unwrap()
+ match self.thread_handle.take() {
+ Some(handle) => handle.join().unwrap(),
+ None => Ok(()),
+ }
+ }
+}
+
+impl Drop for BackgroundProcessor {
+ fn drop(&mut self) {
+ self.stop_and_join_thread().unwrap();