1pub use std::thread::yield_now;
10
11use crate::channel;
12use crate::prelude::*;
13use std::thread::{Builder, JoinHandle};
14
15pub struct Thread<T> {
17 inner: JoinHandle<()>,
18 rx: channel::Receiver<T>,
19}
20
21pub fn block_on<T>(future: impl Future<Output = T>) -> T {
23 async_io::block_on(future)
24}
25
26pub fn sleep(dur: Duration) {
28 if dur.is_infinite() {
29 std::thread::sleep(std::time::Duration::new(u64::MAX, 0));
30 } else {
31 std::thread::sleep(dur.into());
32 }
33}
34
35pub fn start<T: Send + 'static>(
37 name: impl Into<String>,
38 func: impl FnOnce() -> T + Send + 'static,
39) -> Thread<T> {
40 let (tx, rx) = channel::with_capacity(1);
41
42 let func = move || {
43 let output = func();
44 let _ = tx.try_send(output);
45 };
46
47 let inner = Builder::new().name(name.into()).spawn(func).expect("Failed to start thread");
48
49 Thread { inner, rx }
50}
51
52impl<T> Thread<T> {
53 pub async fn join(self) -> Result<T, Panic> {
55 if let Ok(output) = self.rx.recv().await {
56 return Ok(output);
57 }
58
59 if let Err(value) = self.inner.join() {
60 return Err(Panic { value });
61 }
62
63 unreachable!("Thread finished but did not send output.");
64 }
65}
66
67impl<T, E> Thread<Result<T, E>>
68where
69 E: From<Panic>,
70{
71 pub async fn try_join(self) -> Result<T, E> {
73 self.join().await?
74 }
75}