Skip to content

Commit 0e48a22

Browse files
committed
threads: Bump version to 0.2.2
- Updated locking mechanism in better synchronization. - Enhanced error handling for worker termination and notifications. - Exporting example polyfill - Adapted the example for Firefox
1 parent 1678544 commit 0e48a22

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1497
-1074
lines changed

threads/examples/bun.lockb

144 KB
Binary file not shown.
106 KB
Binary file not shown.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
6+
<div id="terminal"></div>
7+
8+
<script type="module" src="./index.ts"></script>
9+
</body>
10+
</html>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { Fd } from "@bjorn3/browser_wasi_shim";
2+
import { Terminal } from "@xterm/xterm";
3+
import { FitAddon } from "xterm-addon-fit";
4+
import { WASIFarm } from "../../src";
5+
import { wait_async_polyfill } from "../../src";
6+
7+
import "@xterm/xterm/css/xterm.css";
8+
9+
wait_async_polyfill();
10+
11+
const term = new Terminal({
12+
convertEol: true,
13+
});
14+
const terminalElement = document.getElementById("terminal");
15+
16+
if (!terminalElement) {
17+
throw new Error("No terminal element found");
18+
}
19+
20+
term.open(terminalElement);
21+
22+
const fitAddon = new FitAddon();
23+
term.loadAddon(fitAddon);
24+
fitAddon.fit();
25+
26+
term.writeln("Initializing...");
27+
28+
class XtermStdio extends Fd {
29+
term: Terminal;
30+
31+
constructor(term: Terminal) {
32+
super();
33+
this.term = term;
34+
}
35+
fd_write(data: Uint8Array) /*: {ret: number, nwritten: number}*/ {
36+
const str = new TextDecoder().decode(data);
37+
this.term.write(str);
38+
console.log(str);
39+
return { ret: 0, nwritten: data.byteLength };
40+
}
41+
}
42+
43+
const farm = new WASIFarm(
44+
new XtermStdio(term),
45+
new XtermStdio(term),
46+
new XtermStdio(term),
47+
[],
48+
);
49+
50+
const worker = new Worker("./worker.ts", { type: "module" });
51+
52+
worker.postMessage({
53+
wasi_ref: farm.get_ref(),
54+
});
55+
56+
worker.onmessage = (e) => {
57+
if (e.data.done) {
58+
term.writeln("All Done!!");
59+
}
60+
};
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// https://doc.rust-lang.org/book/ch16-02-message-passing.html
2+
// rustc +nightly --target wasm32-wasip1-threads main.rs -o common.wasm -Cstrip=debuginfo -Clto=fat
3+
// wasm-opt -Oz --enable-multivalue -o common_opt.wasm common.wasm
4+
5+
use std::thread;
6+
7+
fn main() {
8+
let args = std::env::args().collect::<Vec<_>>();
9+
match args[0].as_str() {
10+
"unreachable" => {
11+
unreachable!();
12+
}
13+
"unreachable_child" => {
14+
thread::spawn(|| {
15+
unreachable!();
16+
});
17+
loop {}
18+
}
19+
"exit" => {
20+
println!("exit {}", args[1]);
21+
std::process::exit(args[1].parse().unwrap());
22+
}
23+
"exit_child" => {
24+
thread::spawn(move || {
25+
println!("exit {}", args[1]);
26+
std::process::exit(args[1].parse().unwrap());
27+
});
28+
loop {}
29+
}
30+
"panic" => {
31+
panic!("panic!");
32+
}
33+
"panic_child" => {
34+
thread::spawn(|| {
35+
panic!("panic!");
36+
});
37+
loop {}
38+
}
39+
"ok" => {
40+
println!("ok");
41+
}
42+
"ok_child" => {
43+
thread::spawn(|| {
44+
println!("ok");
45+
})
46+
.join()
47+
.unwrap();
48+
}
49+
_ => unreachable!(),
50+
}
51+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { thread_spawn_on_worker } from "../../src";
2+
3+
self.onmessage = (event) => {
4+
thread_spawn_on_worker(event.data);
5+
};
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { WASIFarmAnimal } from "../../src";
2+
3+
import { wait_async_polyfill } from "../../src/index.js";
4+
5+
wait_async_polyfill();
6+
7+
self.onmessage = async (e) => {
8+
const { wasi_ref } = e.data;
9+
10+
const wasm = await WebAssembly.compileStreaming(fetch("./common.wasm"));
11+
12+
const run = async (args: string[]) => {
13+
const wasi = new WASIFarmAnimal(
14+
wasi_ref,
15+
args, // args\
16+
[], // env
17+
{
18+
can_thread_spawn: true,
19+
thread_spawn_worker_url: new URL("./thread_spawn.ts", import.meta.url)
20+
.href,
21+
// thread_spawn_worker_url: "./thread_spawn.ts",
22+
thread_spawn_wasm: wasm,
23+
worker_background_worker_url: new URL(
24+
"./worker_background.ts",
25+
import.meta.url,
26+
).href,
27+
},
28+
);
29+
30+
await wasi.wait_worker_background_worker();
31+
32+
try {
33+
const code = await wasi.async_start_on_thread();
34+
console.log(`"${args[0]}" exit code:`, code);
35+
return code;
36+
} catch (e) {
37+
console.error(`"${args[0]}" error:`, e);
38+
return "error";
39+
}
40+
};
41+
42+
const code = await run(["unreachable"]);
43+
if (code !== "error") {
44+
throw new Error("unreachable test failed");
45+
}
46+
const code2 = await run(["unreachable_child"]);
47+
if (code2 !== "error") {
48+
throw new Error("exit test failed");
49+
}
50+
const code3 = await run(["exit", "42"]);
51+
if (code3 !== 42) {
52+
throw new Error("exit test failed");
53+
}
54+
const code4 = await run(["exit_child", "43"]);
55+
if (code4 !== 43) {
56+
throw new Error("exit test failed");
57+
}
58+
const code5 = await run(["panic"]);
59+
if (code5 !== "error") {
60+
throw new Error("panic test failed");
61+
}
62+
const code6 = await run(["panic_child"]);
63+
if (code6 !== "error") {
64+
throw new Error("panic test failed");
65+
}
66+
const code7 = await run(["ok"]);
67+
if (code7 !== 0) {
68+
throw new Error("ok test failed");
69+
}
70+
const code8 = await run(["ok_child"]);
71+
if (code8 !== 0) {
72+
throw new Error("ok test failed");
73+
}
74+
75+
console.log("All tests passed");
76+
77+
self.postMessage({ done: true });
78+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// @ts-ignore
2+
import worker_background_worker from "../node_modules/@oligami/browser_wasi_shim-threads/dist/worker_background_worker.min.js";
3+
4+
import { wait_async_polyfill } from "../../src/index.js";
5+
6+
wait_async_polyfill();
7+
8+
worker_background_worker();

threads/examples/package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

threads/examples/wasi_multi_threads/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
import { WASIFarm, WASIFarmAnimal } from "../../src";
21
import {
2+
ConsoleStdout,
33
File,
44
OpenFile,
5-
ConsoleStdout,
65
PreopenDirectory,
76
} from "@bjorn3/browser_wasi_shim";
7+
import { WASIFarm } from "../../src";
8+
import { wait_async_polyfill } from "../../src";
9+
10+
wait_async_polyfill();
811

912
const farm = new WASIFarm(
1013
new OpenFile(new File([])), // stdin

0 commit comments

Comments
 (0)