Skip to content

Atomics.waitAsync bug #14786

@Eyal-Shalev

Description

@Eyal-Shalev

According to the Atomics.waitAsync documentation, it:

verifies that a given position in an Int32Array still contains a given value and if so sleeps, awaiting a wakeup or a timeout.

However, in my testing it seems like the waitAsync doesn't wake (even after calling Atomics.notify).

Moreover, I think that the event loop might be stuck (setTimeout didn't work and the test gets stuck) but I don't have any way to verify that.

Below are the POC files I used to verify that there is a problem.

poc_test.ts

Deno.test(async function poc() {
  const ia = new Int32Array(
    new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT),
  );

  const p = Promise.allSettled(
    Array(2).fill(0).map((_, i) => {
      const name = `poc_worker#${i}`;
      const w = new Worker(
        new URL("testdata/poc_worker.ts", import.meta.url),
        {
          type: "module",
          name,
        },
      );
      return new Promise<void>((res, rej) => {
        w.onmessage = (ev) => {
          if (ev.data.ok) res(ev.data);
          else rej(ev.data);
        };
        setTimeout(w.postMessage.bind(w), undefined, ia);
      }).finally(w.terminate.bind(w));
    }),
  );

  console.log(await p);
});

testdata/poc_worker.ts

export const sleep = (duration: number) => {
  return new Promise<void>((res) => {
    setTimeout(() => res(), duration);
  });
};

self.onmessage = async (ev) => {
  const ia = ev.data;
  console.log(self.name, ia);
  try {
    const actual = Atomics.compareExchange(ia, 0, 0, 1);

    if (actual === 0) {
      await sleep(0);
      const notified = Atomics.notify(ia, 0);
      console.log(self.name, { actual, notified });
      self.postMessage({ ok: true });
    } else {
      // @ts-expect-error see https://github.com/microsoft/TypeScript/issues/49198
      let { async, value } = Atomics.waitAsync(ia, 0, 1);
      console.log(self.name, { actual, async, value });
      value = await value;
      self.postMessage({ ok: true });
    }
  } catch (err) {
    self.postMessage({ ok: false, err });
  }
};

output

------- output -------
poc_worker#1 Int32Array(1) [ 0 ]
poc_worker#1 { actual: 0, notified: 0 }
poc_worker#0 Int32Array(1) [ 1 ]
poc_worker#0 { actual: 1, async: true, value: Promise { <pending> } }

My Setup
WSL2 - Ubuntu

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.4 LTS
Release:        20.04
Codename:       focal

$ deno --version
deno 1.22.1 (release, x86_64-unknown-linux-gnu)
v8 10.3.174.6
typescript 4.6.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working correctlydeno_coreChanges in "deno_core" crate are needed

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions