1use crate::raw::RawTask;
2
3use super::{COMPLETE, error::JoinError, id::Id};
4use std::{
5 fmt,
6 future::Future,
7 marker::PhantomData,
8 pin::Pin,
9 task::{Context, Poll},
10};
11
12pub struct JoinHandle<T> {
13 raw: RawTask,
14 _p: PhantomData<T>,
15}
16unsafe impl<T: Send> Send for JoinHandle<T> {}
17unsafe impl<T: Send> Sync for JoinHandle<T> {}
18
19impl<T> std::panic::UnwindSafe for JoinHandle<T> {}
20impl<T> std::panic::RefUnwindSafe for JoinHandle<T> {}
21
22impl<T> JoinHandle<T> {
23 pub(super) fn new(raw: RawTask) -> JoinHandle<T> {
24 JoinHandle {
25 raw,
26 _p: PhantomData,
27 }
28 }
29
30 pub fn abort(&self) {
31 unsafe { self.raw.clone().abort_task() };
32 }
33
34 pub fn is_finished(&self) -> bool {
35 self.raw.header().state.load().has(COMPLETE)
36 }
37
38 pub fn id(&self) -> Id {
39 Id::new(&self.raw)
40 }
41}
42
43impl<T> Unpin for JoinHandle<T> {}
44
45impl<T> Future for JoinHandle<T> {
46 type Output = Result<T, JoinError>;
47
48 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
49 let mut ret = Poll::Pending;
50 unsafe {
51 self.raw
52 .read_output(&mut ret as *mut _ as *mut (), cx.waker());
53 }
54
55 ret
56 }
57}
58
59impl<T> Drop for JoinHandle<T> {
60 fn drop(&mut self) {
61 unsafe { self.raw.drop_join_handler() };
62 }
63}
64
65impl<T> fmt::Debug for JoinHandle<T>
66where
67 T: fmt::Debug,
68{
69 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
70 fmt.debug_struct("JoinHandle")
71 .field("id", &self.id())
72 .finish()
73 }
74}