summaryrefslogtreecommitdiffstats
path: root/tokio/src/executor/tests/track_drop.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tokio/src/executor/tests/track_drop.rs')
-rw-r--r--tokio/src/executor/tests/track_drop.rs57
1 files changed, 57 insertions, 0 deletions
diff --git a/tokio/src/executor/tests/track_drop.rs b/tokio/src/executor/tests/track_drop.rs
new file mode 100644
index 00000000..c3ded845
--- /dev/null
+++ b/tokio/src/executor/tests/track_drop.rs
@@ -0,0 +1,57 @@
+use std::future::Future;
+use std::pin::Pin;
+use std::sync::atomic::AtomicBool;
+use std::sync::atomic::Ordering::SeqCst;
+use std::sync::Arc;
+use std::task::{Context, Poll};
+
+#[derive(Debug)]
+pub(crate) struct TrackDrop<T>(T, Arc<AtomicBool>);
+
+#[derive(Debug)]
+pub(crate) struct DidDrop(Arc<AtomicBool>, Arc<AtomicBool>);
+
+pub(crate) fn track_drop<T: Future>(
+ future: T,
+) -> (impl Future<Output = TrackDrop<T::Output>>, DidDrop) {
+ let did_drop_future = Arc::new(AtomicBool::new(false));
+ let did_drop_output = Arc::new(AtomicBool::new(false));
+ let did_drop = DidDrop(did_drop_future.clone(), did_drop_output.clone());
+
+ let future = async move { TrackDrop(future.await, did_drop_output) };
+
+ let future = TrackDrop(future, did_drop_future);
+
+ (future, did_drop)
+}
+
+impl<T> TrackDrop<T> {
+ pub(crate) fn get_ref(&self) -> &T {
+ &self.0
+ }
+}
+
+impl<T: Future> Future for TrackDrop<T> {
+ type Output = T::Output;
+
+ fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ let me = unsafe { Pin::map_unchecked_mut(self, |x| &mut x.0) };
+ me.poll(cx)
+ }
+}
+
+impl<T> Drop for TrackDrop<T> {
+ fn drop(&mut self) {
+ self.1.store(true, SeqCst);
+ }
+}
+
+impl DidDrop {
+ pub(crate) fn did_drop_future(&self) -> bool {
+ self.0.load(SeqCst)
+ }
+
+ pub(crate) fn did_drop_output(&self) -> bool {
+ self.1.load(SeqCst)
+ }
+}