1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
macro_rules! def_ref {
($i:ident, $r:tt) => ( def_ref!($i, $r, pub(super)); );
($i:ident, $r:tt, $v:vis) => {
$v struct $r(Arc<Mutex<$i>>);
impl std::ops::Deref for $r {
type Target = Mutex<$i>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Clone for $r {
fn clone(&self) -> Self {
self.lock().unwrap().ref_count += 1;
Self(self.0.clone())
}
}
impl Drop for $r {
fn drop(&mut self) {
let mut inner = self.lock().unwrap();
if let Some(x) = inner.ref_count.checked_sub(1) {
inner.ref_count = x;
}
if inner.ref_count == 0 {
if let Some(task) = inner.driver.take() {
task.wake();
}
}
}
}
};
}
macro_rules! def_driver {
($r:ident, $d:tt, $e:ty) => ( def_driver!(pub(super), $r; pub(super), $d; $e); );
($rv:vis, $r:ident; $dv:vis, $d:tt; $e:ty) => {
#[must_use = "$r must be spawned!"]
$dv struct $d($rv $r);
impl Future for $d {
type Output = Result<(), $e>;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let mut inner = self.0.lock().unwrap();
match &inner.driver {
Some(w) if w.will_wake(cx.waker()) => (),
_ => inner.driver = Some(cx.waker().clone()),
};
inner.run_driver(cx)?;
if inner.ref_count == 0 {
Poll::Ready(Ok(()))
} else {
Poll::Pending
}
}
}
};
}
macro_rules! def_cs_future {
($f:tt, $h:tt, $ok:ty, $e:ty, $d:meta) => {
def_cs_future!($f, pub(self), $h, pub(self), $ok, $e, $d);
};
($f:tt, $vh:vis, $h:tt, $vf:vis, $ok:ty, $e:ty, $d:meta) => {
$vh type $h = oneshot::Sender<Result<$ok, $e>>;
#[$d]
pub struct $f($vf oneshot::Receiver<Result<$ok, $e>>);
def_flat_future!($f, $ok, $e);
};
}
macro_rules! def_flat_future {
($f:ty, $ok:ty, $e:ty) => {
def_flat_future!($f, $ok, $e, Canceled, 0);
};
($f:ty, $ok:ty, $e:ty, $v:tt, $fld:tt) => {
impl Future for $f {
type Output = Result<$ok, $e>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
match self.$fld.poll_unpin(cx) {
Poll::Pending => Poll::Pending,
Poll::Ready(Err(e)) => Poll::Ready(Err(<$e>::$v(e))),
Poll::Ready(Ok(res)) => Poll::Ready(res),
}
}
}
};
}
macro_rules! def_into_error {
($e: ty) => {
impl From<$e> for std::io::Error {
fn from(err: $e) -> Self {
std::io::Error::new(std::io::ErrorKind::Other, err)
}
}
};
}