1use std::fmt;
19
20pub use crate::intent::ThreadIntent;
21pub use crate::pool::Pool;
22pub use crate::taskpool::TaskPool;
23
24mod intent;
25mod pool;
26mod taskpool;
27
28pub fn spawn<F, T>(intent: ThreadIntent, name: String, f: F) -> JoinHandle<T>
32where
33 F: (FnOnce() -> T) + Send + 'static,
34 T: Send + 'static,
35{
36 Builder::new(intent, name)
37 .spawn(f)
38 .expect("failed to spawn thread")
39}
40
41pub struct Builder {
42 intent: ThreadIntent,
43 inner: jod_thread::Builder,
44 allow_leak: bool,
45}
46
47impl Builder {
48 #[must_use]
49 pub fn new(intent: ThreadIntent, name: impl Into<String>) -> Self {
50 Self {
51 intent,
52 inner: jod_thread::Builder::new().name(name.into()),
53 allow_leak: false,
54 }
55 }
56
57 #[must_use]
58 pub fn stack_size(self, size: usize) -> Self {
59 Self {
60 inner: self.inner.stack_size(size),
61 ..self
62 }
63 }
64
65 #[must_use]
68 pub fn allow_leak(self, allow_leak: bool) -> Self {
69 Self { allow_leak, ..self }
70 }
71
72 pub fn spawn<F, T>(self, f: F) -> std::io::Result<JoinHandle<T>>
73 where
74 F: (FnOnce() -> T) + Send + 'static,
75 T: Send + 'static,
76 {
77 let inner_handle = self.inner.spawn(move || {
78 self.intent.apply_to_current_thread();
79 f()
80 })?;
81
82 Ok(JoinHandle {
83 inner: Some(inner_handle),
84 allow_leak: self.allow_leak,
85 })
86 }
87}
88
89pub struct JoinHandle<T = ()> {
90 inner: Option<jod_thread::JoinHandle<T>>,
93 allow_leak: bool,
94}
95
96impl<T> JoinHandle<T> {
97 #[must_use]
101 pub fn join(mut self) -> T {
102 self.inner.take().unwrap().join()
103 }
104}
105
106impl<T> Drop for JoinHandle<T> {
107 fn drop(&mut self) {
108 if !self.allow_leak {
109 return;
110 }
111
112 if let Some(join_handle) = self.inner.take() {
113 join_handle.detach();
114 }
115 }
116}
117
118impl<T> fmt::Debug for JoinHandle<T> {
119 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120 f.pad("JoinHandle { .. }")
121 }
122}