//! 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(future: F) -> Task where F: Future + 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!"); })); }