mz_ore/thread.rs
1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License in the LICENSE file at the
6// root of this repository, or online at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! Thread utilities.
17
18use std::thread::JoinHandle;
19
20/// Wraps a [`JoinHandle`] so that the child thread is joined when the handle is
21/// dropped, rather than detached. If the child thread panics,
22/// `JoinOnDropHandle` will panic when dropped.
23#[derive(Debug)]
24pub struct JoinOnDropHandle<T>(Option<JoinHandle<T>>);
25
26impl<T> Drop for JoinOnDropHandle<T> {
27 fn drop(&mut self) {
28 self.0.take().unwrap().join().unwrap();
29 }
30}
31
32/// Wraps a [`JoinHandle`] so that the child thread is unparked (and then
33/// detached as usual) when the handle is dropped.
34#[derive(Debug)]
35pub struct UnparkOnDropHandle<T>(JoinHandle<T>);
36
37impl<T> Drop for UnparkOnDropHandle<T> {
38 fn drop(&mut self) {
39 self.0.thread().unpark();
40 }
41}
42
43/// Extension methods for [`JoinHandle`].
44pub trait JoinHandleExt<T> {
45 /// Converts a [`JoinHandle`] into a [`JoinOnDropHandle`].
46 fn join_on_drop(self) -> JoinOnDropHandle<T>;
47
48 /// Converts a [`JoinHandle`] into an [`UnparkOnDropHandle`].
49 fn unpark_on_drop(self) -> UnparkOnDropHandle<T>;
50}
51
52impl<T> JoinHandleExt<T> for JoinHandle<T> {
53 fn join_on_drop(self) -> JoinOnDropHandle<T> {
54 JoinOnDropHandle(Some(self))
55 }
56
57 fn unpark_on_drop(self) -> UnparkOnDropHandle<T> {
58 UnparkOnDropHandle(self)
59 }
60}