1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
use crate :: { import::*, RtConfig, RtErr, RtErrKind }; /// An executor that uses [futures 0.3 LocalPool](https://rust-lang-nursery.github.io/futures-api-docs/0.3.0-alpha.16/futures/executor/struct.LocalPool.html) or [juliex](https://docs.rs/juliex) threadpool under the hood. /// Normally you don't need to construct this yourself, just use the [`rt`](crate::rt) module methods to spawn futures. // #[ derive( Debug ) ] // pub struct Exec03 { config : RtConfig , local : Option<RefCell< LocalPool03 >> , spawner: Option<RefCell< LocalSpawner03 >> , } impl Default for Exec03 { fn default() -> Self { Exec03::new( RtConfig::default() ) } } impl Exec03 { /// Create a new Exec03 from an [RtConfig](crate::RtConfig) configuration. // pub fn new( config: RtConfig ) -> Self { match config { RtConfig::Local => { let local = LocalPool03 ::new(); let spawner = local.spawner(); Exec03 { config , local : Some( RefCell::new( local ) ) , spawner: Some( RefCell::new( spawner ) ) , } } RtConfig::Pool{..} => Exec03{ config, local: None, spawner: None }, } } /// Getter for the active executor configuration. // pub fn config( &self ) -> &RtConfig { &self.config } /// Run all spawned futures to completion. Note that this does nothing for the threadpool, /// but if you are using a local pool, you will need to run this or futures will not be polled. /// This blocks the current thread. // pub fn run( &self ) { match self.config { RtConfig::Local => self.local.as_ref().unwrap().borrow_mut().run(), RtConfig::Pool{..} => {}, // nothing to be done as juliex polls immediately } } /// Spawn a future to be run on the default executor. Note that this requires the /// future to be `Send` in order to work for both the local pool and the threadpool. /// When you need to spawn futures that are not `Send` on the local pool, please use /// [`spawn_local`](Exec03::spawn_local). /// /// ### Errors /// /// - When using `RtConfig::Pool` (currently juliex), this method is infallible. /// - When using `RtConfig::Local` (currently futures 0.3 LocalPool), this method can return a spawn /// error if the executor has been shut down. See the [docs for the futures library](https://rust-lang-nursery.github.io/futures-api-docs/0.3.0-alpha.16/futures/task/struct.SpawnError.html). I haven't really found a way to trigger this error. /// You can call [crate::rt::run] and spawn again afterwards. /// // pub fn spawn( &self, fut: impl Future< Output = () > + 'static + Send ) -> Result< (), RtErr > { match self.config { RtConfig::Local => self.spawner.as_ref().unwrap().borrow_mut().spawn_local( fut ) .map_err( |_| RtErrKind::Spawn{ context: "Futures 0.3 LocalPool spawn".into() }.into() ), RtConfig::Pool => { #[ cfg( feature = "juliex" ) ] // { juliex::spawn( fut ); Ok(()) } #[ cfg( not( feature = "juliex" ) ) ] // Err( RtErrKind::Spawn{ context: "async_runtime was compiled without the juliex feature".into() }.into() ) } } } /// Spawn a `!Send` future to be run on the LocalPool (current thread). Note that the executor must /// be created with a local pool configuration. This will err if you try to call this on an executor /// set up with a threadpool. /// /// ### Errors /// /// - When using `RtConfig::Pool` (currently juliex), this method will return a [RtErrKind::Spawn](crate::RtErrKind::Spawn). /// Since the signature doesn't require [Send] on the future, it can never be sent on a threadpool. /// - When using `RtConfig::Local` (currently futures 0.3 LocalPool), this method can return a spawn /// error if the executor has been shut down. See the [docs for the futures library](https://rust-lang-nursery.github.io/futures-api-docs/0.3.0-alpha.16/futures/task/struct.SpawnError.html). I haven't really found a way to trigger this error. /// You can call [rt::run](crate::rt::run) and spawn again afterwards. // pub fn spawn_local( &self, fut: impl Future< Output = () > + 'static ) -> Result< (), RtErr > { match self.config { RtConfig::Local => self.spawner.as_ref().unwrap().borrow_mut().spawn_local( fut ) .map_err( |_| RtErrKind::Spawn{ context: "Futures 0.3 LocalPool spawn".into() }.into() ), RtConfig::Pool{..} => Err( RtErrKind::Spawn{ context: "Exec03 spawn_local when initialized executor is the threadpool. Use `spawn` to spawn on the threadpool or initialize the default executor for the thread to be the thread local executor".into() }.into() ), } } }