|  | //! A function that runs a future to completion on a dedicated thread. | 
|  |  | 
|  | use std::future::Future; | 
|  | use std::sync::Arc; | 
|  | use std::thread; | 
|  |  | 
|  | use async_task::Task; | 
|  | use smol::future; | 
|  |  | 
|  | /// Spawns a future on a new dedicated thread. | 
|  | /// | 
|  | /// The returned task can be used to await the output of the future. | 
|  | fn spawn_on_thread<F, T>(future: F) -> Task<T> | 
|  | where | 
|  | F: Future<Output = T> + Send + 'static, | 
|  | T: Send + 'static, | 
|  | { | 
|  | // Create a channel that holds the task when it is scheduled for running. | 
|  | let (sender, receiver) = flume::unbounded(); | 
|  | let sender = Arc::new(sender); | 
|  | let s = Arc::downgrade(&sender); | 
|  |  | 
|  | // Wrap the future into one that disconnects the channel on completion. | 
|  | let future = async move { | 
|  | // When the inner future completes, the sender gets dropped and disconnects the channel. | 
|  | let _sender = sender; | 
|  | future.await | 
|  | }; | 
|  |  | 
|  | // Create a task that is scheduled by sending it into the channel. | 
|  | let schedule = move |runnable| s.upgrade().unwrap().send(runnable).unwrap(); | 
|  | let (runnable, task) = async_task::spawn(future, schedule); | 
|  |  | 
|  | // Schedule the task by sending it into the channel. | 
|  | runnable.schedule(); | 
|  |  | 
|  | // Spawn a thread running the task to completion. | 
|  | thread::spawn(move || { | 
|  | // Keep taking the task from the channel and running it until completion. | 
|  | for runnable in receiver { | 
|  | runnable.run(); | 
|  | } | 
|  | }); | 
|  |  | 
|  | task | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | // Spawn a future on a dedicated thread. | 
|  | future::block_on(spawn_on_thread(async { | 
|  | println!("Hello, world!"); | 
|  | })); | 
|  | } |