nio_task/
join.rs

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}