Fix resulting errors and introduce functional executor callback
This commit is contained in:
parent
8974b0c490
commit
8b376dd613
2 changed files with 55 additions and 38 deletions
|
@ -60,25 +60,16 @@ pub struct PluginYieldEpoch {
|
|||
epoch: std::time::Duration,
|
||||
}
|
||||
|
||||
impl Into<PluginYield> for PluginYieldEpoch {
|
||||
fn into(self) -> PluginYield {
|
||||
PluginYield::Epoch(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PluginYieldFuel {
|
||||
initial: u64,
|
||||
refill: u64,
|
||||
}
|
||||
|
||||
impl Into<PluginYield> for PluginYieldFuel {
|
||||
fn into(self) -> PluginYield {
|
||||
PluginYield::Fuel(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum PluginYield {
|
||||
Epoch(PluginYieldEpoch),
|
||||
Epoch {
|
||||
yield_epoch: PluginYieldEpoch,
|
||||
initialize_incrementer: Box<dyn FnOnce(Engine) -> () + Send>,
|
||||
},
|
||||
Fuel(PluginYieldFuel),
|
||||
}
|
||||
|
||||
|
@ -117,7 +108,7 @@ impl PluginBuilder {
|
|||
let linker = Linker::new(&engine);
|
||||
|
||||
match yield_when {
|
||||
PluginYield::Epoch(_) => {
|
||||
PluginYield::Epoch { .. } => {
|
||||
config.epoch_interruption(true);
|
||||
}
|
||||
PluginYield::Fuel(_) => {
|
||||
|
@ -136,23 +127,27 @@ impl PluginBuilder {
|
|||
callback: C,
|
||||
) -> Result<Self, Error>
|
||||
where
|
||||
C: FnOnce(std::pin::Pin<Box<dyn Future<Output = ()> + Send + 'static>>) -> (),
|
||||
C: FnOnce(std::pin::Pin<Box<dyn Future<Output = ()> + Send + 'static>>) -> ()
|
||||
+ Send
|
||||
+ 'static,
|
||||
{
|
||||
let epoch = yield_epoch.epoch;
|
||||
let yield_when = PluginYield::Epoch(yield_epoch);
|
||||
let (engine, linker) = Self::create_engine(&yield_when)?;
|
||||
|
||||
let engine_ref = &engine;
|
||||
|
||||
// we can't create the future until after initializing
|
||||
// because we need the engine to load the plugin
|
||||
// we could use an Arc, but that'd suck
|
||||
callback(Box::pin(async move {
|
||||
loop {
|
||||
smol::Timer::after(epoch).await;
|
||||
engine_ref.increment_epoch();
|
||||
}
|
||||
}));
|
||||
let epoch = yield_epoch.epoch;
|
||||
let initialize_incrementer = Box::new(move |engine: Engine| {
|
||||
callback(Box::pin(async move {
|
||||
loop {
|
||||
smol::Timer::after(epoch).await;
|
||||
engine.increment_epoch();
|
||||
}
|
||||
}))
|
||||
});
|
||||
|
||||
let yield_when = PluginYield::Epoch {
|
||||
yield_epoch,
|
||||
initialize_incrementer,
|
||||
};
|
||||
let (engine, linker) = Self::create_engine(&yield_when)?;
|
||||
|
||||
Ok(PluginBuilder {
|
||||
wasi_ctx,
|
||||
|
@ -188,7 +183,9 @@ impl PluginBuilder {
|
|||
callback: C,
|
||||
) -> Result<Self, Error>
|
||||
where
|
||||
C: FnOnce(std::pin::Pin<Box<dyn Future<Output = ()> + Send + 'static>>) -> (),
|
||||
C: FnOnce(std::pin::Pin<Box<dyn Future<Output = ()> + Send + 'static>>) -> ()
|
||||
+ Send
|
||||
+ 'static,
|
||||
{
|
||||
Self::new_epoch(Self::default_ctx(), yield_epoch, callback)
|
||||
}
|
||||
|
@ -342,7 +339,7 @@ impl PluginBuilder {
|
|||
/// Will panic if this is plugin uses `PluginYield::Epoch`,
|
||||
/// but an epoch incrementer has not yet been created.
|
||||
pub async fn init<T: AsRef<[u8]>>(self, precompiled: bool, module: T) -> Result<Plugin, Error> {
|
||||
Plugin::init(precompiled, module.as_ref().to_vec(), self).await
|
||||
Plugin::init(precompiled, module.as_ref(), self).await
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -402,11 +399,7 @@ impl Plugin {
|
|||
println!();
|
||||
}
|
||||
|
||||
async fn init(
|
||||
precompiled: bool,
|
||||
module: Vec<u8>,
|
||||
plugin: PluginBuilder,
|
||||
) -> Result<Self, Error> {
|
||||
async fn init(precompiled: bool, module: &[u8], plugin: PluginBuilder) -> Result<Self, Error> {
|
||||
// initialize the WebAssembly System Interface context
|
||||
let engine = plugin.engine;
|
||||
let mut linker = plugin.linker;
|
||||
|
@ -430,8 +423,12 @@ impl Plugin {
|
|||
|
||||
// set up automatic yielding based on configuration
|
||||
match plugin.yield_when {
|
||||
PluginYield::Epoch(PluginYieldEpoch { delta, .. }) => {
|
||||
PluginYield::Epoch {
|
||||
yield_epoch: PluginYieldEpoch { delta, .. },
|
||||
initialize_incrementer,
|
||||
} => {
|
||||
store.epoch_deadline_async_yield_and_update(delta);
|
||||
initialize_incrementer(engine);
|
||||
}
|
||||
PluginYield::Fuel(PluginYieldFuel { initial, refill }) => {
|
||||
store.add_fuel(initial).unwrap();
|
||||
|
@ -455,6 +452,25 @@ impl Plugin {
|
|||
Ok(Plugin { store, instance })
|
||||
}
|
||||
|
||||
// async fn init_fuel(
|
||||
// precompiled: bool,
|
||||
// module: &[u8],
|
||||
// plugin: PluginBuilder,
|
||||
// ) -> Result<Self, Error> {
|
||||
// let (_, plugin) = Self::init_inner(precompiled, module, plugin).await?;
|
||||
// Ok(plugin)
|
||||
// }
|
||||
|
||||
// async fn init_epoch<C>(
|
||||
// precompiled: bool,
|
||||
// module: &[u8],
|
||||
// plugin: PluginBuilder,
|
||||
// callback: C,
|
||||
// ) -> Result<Self, Error> {
|
||||
// let (_, plugin) = Self::init_inner(precompiled, module, plugin).await?;
|
||||
// Ok(plugin)
|
||||
// }
|
||||
|
||||
/// Attaches a file or directory the the given system path to the runtime.
|
||||
/// Note that the resource must be freed by calling `remove_resource` afterwards.
|
||||
pub fn attach_path<T: AsRef<Path>>(&mut self, path: T) -> Result<PluginResource, Error> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue