File: interrupt.cc

package info (click to toggle)
rust-wasmtime 36.0.5%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 60,576 kB
  • sloc: cpp: 5,670; ansic: 4,079; sh: 636; javascript: 608; asm: 110; ml: 96; makefile: 61; python: 12
file content (66 lines) | stat: -rw-r--r-- 1,951 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
Example of instantiating of the WebAssembly module and invoking its exported
function.

You can compile and run this example on Linux with:

   cargo build --release -p wasmtime-c-api
   c++ examples/interrupt.cc -std=c++20 \
       -I crates/c-api/include \
       -I crates/c-api/wasm-c-api/include \
       target/release/libwasmtime.a \
       -lpthread -ldl -lm \
       -o interrupt
   ./interrupt

Note that on Windows and macOS the command will be similar, but you'll need
to tweak the `-lpthread` and such annotations as well as the name of the
`libwasmtime.a` file on Windows.
*/

#include <chrono>
#include <fstream>
#include <iostream>
#include <sstream>
#include <thread>
#include <wasmtime.hh>

using namespace wasmtime;

std::string readFile(const char *name) {
  std::ifstream watFile;
  watFile.open(name);
  std::stringstream strStream;
  strStream << watFile.rdbuf();
  return strStream.str();
}

int main() {
  // Enable interruptible code via `Config` and then create an interrupt
  // handle which we'll use later to interrupt running code.
  Config config;
  config.epoch_interruption(true);
  Engine engine(std::move(config));
  Store store(engine);
  store.context().set_epoch_deadline(1);

  // Compile and instantiate a small example with an infinite loop.
  auto wat = readFile("examples/interrupt.wat");
  Module module = Module::compile(engine, wat).unwrap();
  Instance instance = Instance::create(store, module, {}).unwrap();
  Func run = std::get<Func>(*instance.get(store, "run"));

  // Spin up a thread to send us an interrupt in a second
  std::thread t([engine{std::move(engine)}]() {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "Interrupting!\n";
    engine.increment_epoch();
  });

  std::cout << "Entering infinite loop ...\n";
  auto err = run.call(store, {}).err();
  auto &trap = std::get<Trap>(err.data);

  std::cout << "trap: " << trap.message() << "\n";
  t.join();
}