forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			53 lines
		
	
	
	
		
			1.5 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			53 lines
		
	
	
	
		
			1.5 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| //! 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!");
 | |
|     }));
 | |
| }
 | 
