Open Bug 1888109 Opened 11 months ago Updated 10 months ago

SharedArrayBuffer users that block the main thread (reasonably) assuming Worker creation can happen without the main thread being available can cause deadlock

Categories

(Core :: DOM: Workers, enhancement)

enhancement

Tracking

()

People

(Reporter: jujjyl, Unassigned)

References

Details

Would it be possible to make the following code not deadlock the browser?

a.html

<html><body><script>
fetch('a.js').then(response => response.blob()).then(blob => {
  let worker = new Worker(URL.createObjectURL(blob));
  let sab = new Uint8Array(new SharedArrayBuffer(16));
  worker.postMessage(sab);
  console.log('Waiting for Worker to finish');
  while(sab[0] != 1) /*wait to join with the result*/; 
  console.log(`Worker finished. SAB: ${sab[0]}`);
});
</script></body></html>

a.js

onmessage = (e) => {
  console.log('Received SAB');
  e.data[0] = 1;
}

Observed: browser hangs on the while() loop.

Expected: new Worker() would be great to make progress asynchronously, and the code would print out

Worker finished. SAB: 1

Some background: This deadlock is causing headaches to users of SharedArrayBuffer/WebAssembly, and leads to poor startup time and over-subscription of web resources on shipped web sites. If it was possible to make the above code work and not deadlock, it would greatly improve startup time and performance of SharedArrayBuffer-utilizing web sites.

Note that we are not asking new Worker(arbitraryUrl) to necessarily have this forward-progress guarantee, but that at least that new Worker(blobUrlInMemory) would do so (like illustrated in above code). Would that be feasible?

Note that when testing the above code, COOP+COEP HTTP headers are required, or otherwise the SharedArrayBuffer object will not be available. A quick way to get those headers is to download an ad hoc emrun.py web server, and run

emrun.py --no_browser --port 8000 .

in the directory of a.html and a.js. That will launch a web server that includes the relevant COOP+COEP headers.

See Also: → 1896829

Bug 1797639 tracks the script loader improvements necessary to address this.

I believe the reporter also filed https://github.com/whatwg/html/issues/10228 culminating in new WPT tests at https://github.com/web-platform-tests/wpt/pull/45502 that I signed off on.

Noting that while it's of course not a best practice to block the main thread in a busy-wait loop, this probably is better noted as a defect that our worker implementation depends on the main thread, so I've changed this from an enhancement for this bug. (Although the implementation bug 1797639 gets to stay an enhancement.)

Depends on: 1797639
Summary: Can new Worker() be made to properly operate on the background (maybe when the URL is an in-memory Blob)? → SharedArrayBuffer users that block the main thread (reasonably) assuming Worker creation can happen without the main thread being available can cause deadlock
You need to log in before you can comment on or make changes to this bug.