1 //! Example of interrupting a WebAssembly function's runtime via epoch
2 //! changes ("epoch interruption") in a synchronous context. To see
3 //! an example of setup for asynchronous usage, see
4 //! `tests/all/epoch_interruption.rs`
5
6 use std::sync::Arc;
7 use wasmtime::Error;
8 use wasmtime::{Config, Engine, Instance, Module, Store};
9
main() -> Result<(), Error>10 fn main() -> Result<(), Error> {
11 // Set up an engine configured with epoch interruption enabled.
12 let mut config = Config::new();
13 config.epoch_interruption(true);
14 let engine = Arc::new(Engine::new(&config)?);
15
16 let mut store = Store::new(&engine, ());
17 // Configure the store to trap on reaching the epoch deadline.
18 // This is the default, but we do it explicitly here to
19 // demonstrate.
20 store.epoch_deadline_trap();
21 // Configure the store to have an initial epoch deadline one tick
22 // in the future.
23 store.set_epoch_deadline(1);
24
25 // Reuse the fibonacci function from the Fuel example. This is a
26 // long-running function that we will want to interrupt.
27 let module = Module::from_file(store.engine(), "examples/fuel.wat")?;
28 let instance = Instance::new(&mut store, &module, &[])?;
29
30 // Start a thread that will bump the epoch after 1 second.
31 let engine_clone = engine.clone();
32 std::thread::spawn(move || {
33 std::thread::sleep(std::time::Duration::from_secs(1));
34 engine_clone.increment_epoch();
35 });
36
37 // Invoke `fibonacci` with a large argument such that a normal
38 // invocation would take many seconds to complete.
39 let fibonacci = instance.get_typed_func::<i32, i32>(&mut store, "fibonacci")?;
40 match fibonacci.call(&mut store, 100) {
41 Ok(_) => panic!("Somehow we computed recursive fib(100) in less than a second!"),
42 Err(_) => {
43 println!("Trapped out of fib(100) after epoch increment");
44 }
45 };
46
47 Ok(())
48 }
49