// You can execute this example with `cargo run --example threads` use anyhow::{format_err, Result}; use std::thread; use std::time; use wasmtime::*; const N_THREADS: i32 = 10; const N_REPS: i32 = 3; fn run(engine: &Engine, module: Module, id: i32) -> Result<()> { let store = Store::new(&engine); // Create external print functions. println!("Creating callback..."); let callback_func = Func::wrap(&store, |arg: i32| { println!("> Thread {} is running", arg); }); let id_type = GlobalType::new(ValType::I32, Mutability::Const); let id_global = Global::new(&store, id_type, Val::I32(id))?; // Instantiate. println!("Instantiating module..."); let instance = Instance::new(&store, &module, &[callback_func.into(), id_global.into()])?; // Extract exports. println!("Extracting export..."); let g = instance .get_func("run") .ok_or(format_err!("failed to find export `eun`"))?; for _ in 0..N_REPS { thread::sleep(time::Duration::from_millis(100)); // Call `$run`. drop(g.call(&[])?); } Ok(()) } fn main() -> Result<()> { println!("Initializing..."); let engine = Engine::default(); // Compile. println!("Compiling module..."); let module = Module::from_file(&engine, "examples/threads.wat")?; let mut children = Vec::new(); for id in 0..N_THREADS { let engine = engine.clone(); let module = module.clone(); children.push(thread::spawn(move || { run(&engine, module, id).expect("Success"); })); } for (i, child) in children.into_iter().enumerate() { if let Err(_) = child.join() { println!("Thread #{} errors", i); } } Ok(()) }