16:40
<annevk>
sideshowbarker: there are some existing CSP + CSS issues, not sure if they cover this
16:42
<annevk>
Oh right, the spec even links https://github.com/w3c/webappsec-csp/issues/212
19:06
<sideshowbarker>
annevk: thanks
20:04
<bakkot>
I've just learned that postMessage is async, such that if you do worker.postMessage(); while (true) {} the message will never actually fire. Is there a reason for this? If no, could it be changed, possibly as an opt-in option? This comes up in the context of emscripten.
20:09
<Andreu Botella (he/they)>
I don't think that's true per the spec
20:09
<Andreu Botella (he/they)>
https://html.spec.whatwg.org/multipage/workers.html#dom-worker-postmessage
20:10
<Andreu Botella (he/they)>
The only task or microtask queued in that algorithm is the one that is actually queued on the worker's event loop
20:12
<Andreu Botella (he/they)>
But I guess it comes down to the notion of observability, since you can't observe the result of a task in a worker thread if the main thread is stuck in a loop
20:13
<bakkot>
you can with a SAB
20:13
<Andreu Botella (he/they)>
True. Then this is a bug
20:25
<bakkot>

MDN has it documented:

After postMessage() is called, the MessageEvent will be dispatched only after all pending execution contexts have finished. For example, if postMessage() is invoked in an event handler, that event handler will run to completion, as will any remaining handlers for that same event, before the MessageEvent is dispatched.

20:28
<bakkot>
I can't actually tell from reading the spec if the "add a task" implies adding it on the current thread or the worker's, but I'll take your word for it.
20:30
<Andreu Botella (he/they)>
That task fires the message event, and event firing is synchronous, so it must be on the worker's thread
20:47
<Domenic>
I think this is related to https://github.com/whatwg/html/issues/3691 . Basically, postMessage() infrastructure assumes the target could be cross-process. Although this is not true for dedicated workers it could be for iframes or shared/service workers. The spec as-written doesn't really acknowledge this so it acts as if you can get synchronous access to the target's message queue. But, in general, you cannot; if your process is busy-looping you're gonna have a hard time pushing messages across process boundaries, I believe.
20:48
<Domenic>
So in theory implementations could maybe special-case dedicatedWorker.postMessage() to make that work even in the presence of busy loops. In practice that'd probably be quite involved as they'd essentially have to create a parallel message-queuing infrastructure for dedicated workers only.
20:54
<bakkot>
huh, ok, it looks like I was actually wrong (I wrote a test case but it was bugged) and the MDN page is also wrong
20:54
<bakkot>

here's my test case (now that I've fixed it)

let workerSrc = `
let arr;
self.addEventListener('message', e => {
  switch (e.data.message) {
    case 'init': {
      console.log('worker: got init');
      arr = new Int32Array(e.data.buf);
      Atomics.notify(arr, 0);
      break;
    }
    case 'next': {
      console.log('worker: got next');
      arr[1] = 1;
      break;
    }
  }
});
`;
let blob = new Blob([workerSrc], {type: 'application/javascript'});
let worker = new Worker(URL.createObjectURL(blob));

(async () => {
  let buf = new SharedArrayBuffer(16);
  let arr = new Int32Array(buf);
  worker.postMessage({ message: 'init', buf });

  if (typeof Atomics.waitAsync === 'function') {
    await Atomics.waitAsync(arr, 0, 0).value;
  } else {
    // give the worker time to start
    await new Promise(res => setTimeout(res, 1000));
  }

  console.log('init');
  worker.postMessage({ message: 'next' });

  console.log('now we busy-wait, with arr[1] initially =', arr[1]);
  for (let i = 0; i < 1e8; ++i) {
    if (arr[1] === 1) {
      console.log('done! took until i =', i);
      return;
    }
  }
  console.log('never initialized');
})().catch(e => console.error('error', e));
20:54
<bakkot>
in chrome and FF this does actually finish; FF seems to take literally no iterations of the loop, where chrome takes a couple hundred
20:54
<bakkot>
apologies for the confusion
21:38
<aliray>
Hi, could someone explain main what is the purpose of this line? https://github.com/html5lib/html5lib-python/blob/master/html5lib/_inputstream.py#L141
21:59
<sideshowbarker>
huh, ok, it looks like I was actually wrong (I wrote a test case but it was bugged) and the MDN page is also wrong
please file an MDN issue for it
22:06
<bakkot>
per discussion above the MDN page might be right in other cases, despite the spec
22:06
<bakkot>
but I'll file an issue saying "this is wrong at least some of the time"
22:06
<sideshowbarker>
OK
23:50
<bakkot>
oh hey there's even WPT tests for postMessage being sync - https://github.com/web-platform-tests/wpt/pull/23270