1use tokio::{runtime::Handle, task};
19
20pub trait HandleExt {
23 fn block_on_place<F: Future>(&self, future: F) -> F::Output;
24}
25
26impl HandleExt for Handle {
27 #[inline]
28 fn block_on_place<F: Future>(&self, future: F) -> F::Output {
29 #[cfg(feature = "tracing")]
30 if Handle::try_current().is_ok() {
31 tracing::warn!("Calling `block_on_place` from within a runtime context.");
32 }
33
34 task::block_in_place(|| self.block_on(future))
35 }
36}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41
42 #[tokio::test(flavor = "multi_thread", worker_threads = 1)]
43 async fn inside_runtime() {
44 let handle = Handle::current();
45 handle.block_on_place(async {
46 });
48 }
49
50 #[tokio::test(flavor = "multi_thread", worker_threads = 1)]
51 async fn outside_runtime() {
52 let handle = Handle::current();
53 let task = task::spawn_blocking(move || {
54 handle.block_on_place(async {
55 });
57 });
58
59 task.await.expect("should not fail")
60 }
61}