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 anyhow::Error; 7 use std::sync::Arc; 8 use wasmtime::{Config, Engine, Instance, Module, Store}; 9 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