Skip to content

Commit 253bbf5

Browse files
committed
add atomic tests
1 parent 70fdb9b commit 253bbf5

File tree

5 files changed

+71
-4
lines changed

5 files changed

+71
-4
lines changed

libs/core/runtime/jsruntime.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2292,10 +2292,12 @@ impl JsRuntime {
22922292
.safety_net_active
22932293
.swap(true, std::sync::atomic::Ordering::SeqCst)
22942294
{
2295-
let waker = cx.waker().clone();
2296-
let flag = self.inner.state.safety_net_active.clone();
2297-
waker.wake();
2298-
flag.store(false, std::sync::atomic::Ordering::SeqCst);
2295+
cx.waker().wake_by_ref();
2296+
self
2297+
.inner
2298+
.state
2299+
.safety_net_active
2300+
.store(false, std::sync::atomic::Ordering::SeqCst);
22992301
}
23002302

23012303
// Re-wake logic for next iteration
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"args": "test --quiet --no-check -A main.ts",
3+
"output": "main.out",
4+
"exitCode": 0
5+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[WILDCARD]atomicsWaitAsyncNotify ... ok [WILDCARD]
2+
3+
ok | 1 passed | 0 failed [WILDCARD]
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Regression test for https://github.com/denoland/deno/issues/14786
2+
// Atomics.waitAsync in a worker requires V8 to post a delayed foreground
3+
// task when the wait is resolved. Without the custom platform waking the
4+
// event loop, the worker hangs forever.
5+
Deno.test(async function atomicsWaitAsyncNotify() {
6+
const ia = new Int32Array(
7+
new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT),
8+
);
9+
10+
const p = Promise.allSettled(
11+
Array(2).fill(0).map((_, i) => {
12+
const w = new Worker(
13+
new URL("./worker.ts", import.meta.url),
14+
{
15+
type: "module",
16+
name: `worker-${i}`,
17+
},
18+
);
19+
return new Promise<void>((res, rej) => {
20+
w.onmessage = (ev) => {
21+
if (ev.data.ok) res(ev.data);
22+
else rej(ev.data);
23+
};
24+
setTimeout(w.postMessage.bind(w), undefined, ia);
25+
}).finally(w.terminate.bind(w));
26+
}),
27+
);
28+
29+
const results = await p;
30+
for (const r of results) {
31+
if (r.status === "rejected") throw r.reason;
32+
}
33+
});
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const sleep = (duration: number) => {
2+
return new Promise<void>((res) => {
3+
setTimeout(() => res(), duration);
4+
});
5+
};
6+
7+
self.onmessage = async (ev) => {
8+
const ia = ev.data;
9+
try {
10+
const actual = Atomics.compareExchange(ia, 0, 0, 1);
11+
12+
if (actual === 0) {
13+
await sleep(0);
14+
Atomics.notify(ia, 0);
15+
self.postMessage({ ok: true });
16+
} else {
17+
let { value } = Atomics.waitAsync(ia, 0, 1);
18+
value = await value;
19+
self.postMessage({ ok: true });
20+
}
21+
} catch (err) {
22+
self.postMessage({ ok: false, err });
23+
}
24+
};

0 commit comments

Comments
 (0)