|
42 | 42 | use std::fmt;
|
43 | 43 | use std::marker::PhantomData;
|
44 | 44 | use std::panic::{RefUnwindSafe, UnwindSafe};
|
| 45 | +use std::pin::Pin; |
45 | 46 | use std::rc::Rc;
|
46 | 47 | use std::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
|
47 | 48 | use std::sync::{Arc, Mutex, MutexGuard, RwLock, TryLockError};
|
48 |
| -use std::task::{Poll, Waker}; |
| 49 | +use std::task::{Context, Poll, Waker}; |
49 | 50 |
|
50 | 51 | use async_task::{Builder, Runnable};
|
51 | 52 | use concurrent_queue::ConcurrentQueue;
|
52 | 53 | use futures_lite::{future, prelude::*};
|
| 54 | +use pin_project_lite::pin_project; |
53 | 55 | use slab::Slab;
|
54 | 56 |
|
55 | 57 | #[cfg(feature = "static")]
|
@@ -245,10 +247,7 @@ impl<'a> Executor<'a> {
|
245 | 247 | let entry = active.vacant_entry();
|
246 | 248 | let index = entry.key();
|
247 | 249 | let state = self.state_as_arc();
|
248 |
| - let future = async move { |
249 |
| - let _guard = CallOnDrop(move || drop(state.active().try_remove(index))); |
250 |
| - future.await |
251 |
| - }; |
| 250 | + let future = AsyncCallOnDrop::new(future, move || drop(state.active().try_remove(index))); |
252 | 251 |
|
253 | 252 | // Create the task and register it in the set of active tasks.
|
254 | 253 | //
|
@@ -1155,6 +1154,32 @@ impl<F: FnMut()> Drop for CallOnDrop<F> {
|
1155 | 1154 | }
|
1156 | 1155 | }
|
1157 | 1156 |
|
| 1157 | +pin_project! { |
| 1158 | + /// A wrapper around a future, running a closure when dropped. |
| 1159 | + struct AsyncCallOnDrop<Fut, Cleanup: FnMut()> { |
| 1160 | + #[pin] |
| 1161 | + future: Fut, |
| 1162 | + cleanup: CallOnDrop<Cleanup>, |
| 1163 | + } |
| 1164 | +} |
| 1165 | + |
| 1166 | +impl<Fut, Cleanup: FnMut()> AsyncCallOnDrop<Fut, Cleanup> { |
| 1167 | + fn new(future: Fut, cleanup: Cleanup) -> Self { |
| 1168 | + Self { |
| 1169 | + future, |
| 1170 | + cleanup: CallOnDrop(cleanup), |
| 1171 | + } |
| 1172 | + } |
| 1173 | +} |
| 1174 | + |
| 1175 | +impl<Fut: Future, Cleanup: FnMut()> Future for AsyncCallOnDrop<Fut, Cleanup> { |
| 1176 | + type Output = Fut::Output; |
| 1177 | + |
| 1178 | + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 1179 | + self.project().future.poll(cx) |
| 1180 | + } |
| 1181 | +} |
| 1182 | + |
1158 | 1183 | fn _ensure_send_and_sync() {
|
1159 | 1184 | use futures_lite::future::pending;
|
1160 | 1185 |
|
|
0 commit comments