• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! A function that runs a future to completion on a dedicated thread.
2 
3 use std::future::Future;
4 use std::sync::Arc;
5 use std::thread;
6 
7 use async_task::Task;
8 use smol::future;
9 
10 /// Spawns a future on a new dedicated thread.
11 ///
12 /// The returned task can be used to await the output of the future.
spawn_on_thread<F, T>(future: F) -> Task<T> where F: Future<Output = T> + Send + 'static, T: Send + 'static,13 fn spawn_on_thread<F, T>(future: F) -> Task<T>
14 where
15     F: Future<Output = T> + Send + 'static,
16     T: Send + 'static,
17 {
18     // Create a channel that holds the task when it is scheduled for running.
19     let (sender, receiver) = flume::unbounded();
20     let sender = Arc::new(sender);
21     let s = Arc::downgrade(&sender);
22 
23     // Wrap the future into one that disconnects the channel on completion.
24     let future = async move {
25         // When the inner future completes, the sender gets dropped and disconnects the channel.
26         let _sender = sender;
27         future.await
28     };
29 
30     // Create a task that is scheduled by sending it into the channel.
31     let schedule = move |runnable| s.upgrade().unwrap().send(runnable).unwrap();
32     let (runnable, task) = async_task::spawn(future, schedule);
33 
34     // Schedule the task by sending it into the channel.
35     runnable.schedule();
36 
37     // Spawn a thread running the task to completion.
38     thread::spawn(move || {
39         // Keep taking the task from the channel and running it until completion.
40         for runnable in receiver {
41             runnable.run();
42         }
43     });
44 
45     task
46 }
47 
main()48 fn main() {
49     // Spawn a future on a dedicated thread.
50     future::block_on(spawn_on_thread(async {
51         println!("Hello, world!");
52     }));
53 }
54