xref: /wasmtime-44.0.1/examples/interrupt.cc (revision 13ebd6f5)
1*13ebd6f5SMangoPeachGrape /*
2*13ebd6f5SMangoPeachGrape Example of instantiating of the WebAssembly module and invoking its exported
3*13ebd6f5SMangoPeachGrape function.
4*13ebd6f5SMangoPeachGrape 
5*13ebd6f5SMangoPeachGrape You can compile and run this example on Linux with:
6*13ebd6f5SMangoPeachGrape 
7*13ebd6f5SMangoPeachGrape    cargo build --release -p wasmtime-c-api
8*13ebd6f5SMangoPeachGrape    c++ examples/interrupt.cc -std=c++20 \
9*13ebd6f5SMangoPeachGrape        -I crates/c-api/include \
10*13ebd6f5SMangoPeachGrape        -I crates/c-api/wasm-c-api/include \
11*13ebd6f5SMangoPeachGrape        target/release/libwasmtime.a \
12*13ebd6f5SMangoPeachGrape        -lpthread -ldl -lm \
13*13ebd6f5SMangoPeachGrape        -o interrupt
14*13ebd6f5SMangoPeachGrape    ./interrupt
15*13ebd6f5SMangoPeachGrape 
16*13ebd6f5SMangoPeachGrape Note that on Windows and macOS the command will be similar, but you'll need
17*13ebd6f5SMangoPeachGrape to tweak the `-lpthread` and such annotations as well as the name of the
18*13ebd6f5SMangoPeachGrape `libwasmtime.a` file on Windows.
19*13ebd6f5SMangoPeachGrape */
20*13ebd6f5SMangoPeachGrape 
21*13ebd6f5SMangoPeachGrape #include <chrono>
22*13ebd6f5SMangoPeachGrape #include <fstream>
23*13ebd6f5SMangoPeachGrape #include <iostream>
24*13ebd6f5SMangoPeachGrape #include <sstream>
25*13ebd6f5SMangoPeachGrape #include <thread>
26*13ebd6f5SMangoPeachGrape #include <wasmtime.hh>
27*13ebd6f5SMangoPeachGrape 
28*13ebd6f5SMangoPeachGrape using namespace wasmtime;
29*13ebd6f5SMangoPeachGrape 
readFile(const char * name)30*13ebd6f5SMangoPeachGrape std::string readFile(const char *name) {
31*13ebd6f5SMangoPeachGrape   std::ifstream watFile;
32*13ebd6f5SMangoPeachGrape   watFile.open(name);
33*13ebd6f5SMangoPeachGrape   std::stringstream strStream;
34*13ebd6f5SMangoPeachGrape   strStream << watFile.rdbuf();
35*13ebd6f5SMangoPeachGrape   return strStream.str();
36*13ebd6f5SMangoPeachGrape }
37*13ebd6f5SMangoPeachGrape 
main()38*13ebd6f5SMangoPeachGrape int main() {
39*13ebd6f5SMangoPeachGrape   // Enable interruptible code via `Config` and then create an interrupt
40*13ebd6f5SMangoPeachGrape   // handle which we'll use later to interrupt running code.
41*13ebd6f5SMangoPeachGrape   Config config;
42*13ebd6f5SMangoPeachGrape   config.epoch_interruption(true);
43*13ebd6f5SMangoPeachGrape   Engine engine(std::move(config));
44*13ebd6f5SMangoPeachGrape   Store store(engine);
45*13ebd6f5SMangoPeachGrape   store.context().set_epoch_deadline(1);
46*13ebd6f5SMangoPeachGrape 
47*13ebd6f5SMangoPeachGrape   // Compile and instantiate a small example with an infinite loop.
48*13ebd6f5SMangoPeachGrape   auto wat = readFile("examples/interrupt.wat");
49*13ebd6f5SMangoPeachGrape   Module module = Module::compile(engine, wat).unwrap();
50*13ebd6f5SMangoPeachGrape   Instance instance = Instance::create(store, module, {}).unwrap();
51*13ebd6f5SMangoPeachGrape   Func run = std::get<Func>(*instance.get(store, "run"));
52*13ebd6f5SMangoPeachGrape 
53*13ebd6f5SMangoPeachGrape   // Spin up a thread to send us an interrupt in a second
54*13ebd6f5SMangoPeachGrape   std::thread t([engine{std::move(engine)}]() {
55*13ebd6f5SMangoPeachGrape     std::this_thread::sleep_for(std::chrono::seconds(1));
56*13ebd6f5SMangoPeachGrape     std::cout << "Interrupting!\n";
57*13ebd6f5SMangoPeachGrape     engine.increment_epoch();
58*13ebd6f5SMangoPeachGrape   });
59*13ebd6f5SMangoPeachGrape 
60*13ebd6f5SMangoPeachGrape   std::cout << "Entering infinite loop ...\n";
61*13ebd6f5SMangoPeachGrape   auto err = run.call(store, {}).err();
62*13ebd6f5SMangoPeachGrape   auto &trap = std::get<Trap>(err.data);
63*13ebd6f5SMangoPeachGrape 
64*13ebd6f5SMangoPeachGrape   std::cout << "trap: " << trap.message() << "\n";
65*13ebd6f5SMangoPeachGrape   t.join();
66*13ebd6f5SMangoPeachGrape }
67