1 use crate::task::JoinHandle;
2 
3 cfg_rt_threaded! {
4     /// Runs the provided blocking function without blocking the executor.
5     ///
6     /// In general, issuing a blocking call or performing a lot of compute in a
7     /// future without yielding is not okay, as it may prevent the executor from
8     /// driving other futures forward. If you run a closure through this method,
9     /// the current executor thread will relegate all its executor duties to another
10     /// (possibly new) thread, and only then poll the task. Note that this requires
11     /// additional synchronization.
12     ///
13     /// # Note
14     ///
15     /// This function can only be called from a spawned task when working with
16     /// the [threaded scheduler](https://docs.rs/tokio/0.2.10/tokio/runtime/index.html#threaded-scheduler).
17     /// Consider using [tokio::task::spawn_blocking](https://docs.rs/tokio/0.2.10/tokio/task/fn.spawn_blocking.html).
18     ///
19     /// # Examples
20     ///
21     /// ```
22     /// use tokio::task;
23     ///
24     /// # async fn docs() {
25     /// task::block_in_place(move || {
26     ///     // do some compute-heavy work or call synchronous code
27     /// });
28     /// # }
29     /// ```
30     #[cfg_attr(docsrs, doc(cfg(feature = "blocking")))]
31     pub fn block_in_place<F, R>(f: F) -> R
32     where
33         F: FnOnce() -> R,
34     {
35         use crate::runtime::{enter, thread_pool};
36 
37         enter::exit(|| thread_pool::block_in_place(f))
38     }
39 }
40 
41 cfg_blocking! {
42     /// Runs the provided closure on a thread where blocking is acceptable.
43     ///
44     /// In general, issuing a blocking call or performing a lot of compute in a future without
45     /// yielding is not okay, as it may prevent the executor from driving other futures forward.
46     /// A closure that is run through this method will instead be run on a dedicated thread pool for
47     /// such blocking tasks without holding up the main futures executor.
48     ///
49     /// # Examples
50     ///
51     /// ```
52     /// use tokio::task;
53     ///
54     /// # async fn docs() -> Result<(), Box<dyn std::error::Error>>{
55     /// let res = task::spawn_blocking(move || {
56     ///     // do some compute-heavy work or call synchronous code
57     ///     "done computing"
58     /// }).await?;
59     ///
60     /// assert_eq!(res, "done computing");
61     /// # Ok(())
62     /// # }
63     /// ```
64     pub fn spawn_blocking<F, R>(f: F) -> JoinHandle<R>
65     where
66         F: FnOnce() -> R + Send + 'static,
67         R: Send + 'static,
68     {
69         crate::runtime::spawn_blocking(f)
70     }
71 }
72