Fix resulting errors and introduce functional executor callback

This commit is contained in:
Isaac Clayton 2022-07-13 13:15:12 +02:00
parent 8974b0c490
commit 8b376dd613
2 changed files with 55 additions and 38 deletions

View file

@ -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> {