future_utils/
drop_notify.rs1use std::thread;
2use futures::task::{self, Task};
3use futures::sync::BiLock;
4use futures::{Async, Future};
5use void::Void;
6
7struct Inner {
8 dropped: bool,
9 task_rx: Option<Task>,
10}
11
12pub struct DropNotify {
15 inner: BiLock<Inner>,
16}
17
18pub struct DropNotice {
21 inner: BiLock<Inner>,
22}
23
24pub fn drop_notify() -> (DropNotify, DropNotice) {
27 let inner = Inner {
28 dropped: false,
29 task_rx: None,
30 };
31 let (lock_notify, lock_notice) = BiLock::new(inner);
32 let drop_notify = DropNotify {
33 inner: lock_notify,
34 };
35 let drop_notice = DropNotice {
36 inner: lock_notice,
37 };
38 (drop_notify, drop_notice)
39}
40
41impl Future for DropNotice {
42 type Item = ();
43 type Error = Void;
44
45 fn poll(&mut self) -> Result<Async<()>, Void> {
46 if let Async::Ready(ref mut inner) = self.inner.poll_lock() {
47 if inner.dropped {
48 return Ok(Async::Ready(()));
49 }
50 inner.task_rx = Some(task::current());
51 Ok(Async::NotReady)
52 } else {
53 Ok(Async::Ready(()))
55 }
56 }
57}
58
59impl Drop for DropNotify {
60 fn drop(&mut self) {
61 loop {
62 if let Async::Ready(ref mut inner) = self.inner.poll_lock() {
63 inner.dropped = true;
64 if let Some(task) = inner.task_rx.take() {
65 task.notify();
66 }
67 return;
68 }
69 thread::yield_now();
71 }
72 }
73}
74