[webrtc-pc] The threading model of webrtc-pc: When are effects of in-parallel stuff surfaced? (#2502)

henbos has just created a new issue for https://github.com/w3c/webrtc-pc:

== The threading model of webrtc-pc: When are effects of in-parallel stuff surfaced? ==
JavaScript "pretending" to be single-threaded, things that happen either just happen (in the currently executing task), or they happen "in-parallel" (i.e. off the thread), and then the results are surfaced sometime in the future in a queued task.

According to my understanding of things, exposing the effects of something from an in-parallel operation before the queued task has executed would be a bug. I'm going to call this **_the state surfacing theorem_**. Feel free to challenge the validity of this theorem.

For example, `while (true) { console.log(sender.getSynchronizationSources()); }` should ALWAYS print the same result, because the thread is blocked and no queued task is able to execute to inform the JS thread that a new RTP packet has arrived.

Similarly, I would expect the following to print 0 forever and ever, because we are not letting the in-parallel SRD operation perform its queued task to create the JavaScript layer transceiver objects corresponding to the SDP m= sections:
```
pc.setRemoteDescription(offerThatCreatesATransceiver);
while (true) {
  console.log(pc.getTransceivers().length);
}
```

Why does this matter? Well JSEP has this to say about addTrack:

> If the PeerConnection is in the "have-remote-offer" state, the track will be attached to the first compatible transceiver that was created by the most recent call to setRemoteDescription() and does not have a local track.

But setRemoteDescription() executed in-parallel. And addTrack() executed immediately. So if I do `setRemoteDescription(); addTrack();`, has SRD happened when addTrack happens or not?

Based on recent discussions, I believe Chrome and Firefox has observably different implementations. I believe both of them violate _the state surfacing theorem_ but in different ways. Correct me if I'm wrong on Firefox's implementation.

- **Behavior A** (= what Chrome does): In-parallel operations previously queued happen first and synchronous operations happen second due to PostTasks ensuring a FIFO order. If you call SRD followed by addTrack, the JS thread is blocked until addTrack is performed, which only happens after the SRD operation has executed. The theorem is violated because what the result of the addTrack operation is could expose how SRD was executed.
- **Behavior B** (= probably what Firefox does?): In-parallel operations and JavaScript share the same set of transceiver objects, accessed by grabbing locks. The result of SRD + addTrack is undefined, because which operation modifies the set of transceiver objects first is racy.
- **Behavior C** (= not implemented by any browser?): No races and synchronous operations truly happening synchronously - the effect of SRD is truly not visible until the posted task. That is, if SRD is immediately followed by addTrack, the addTrack operation MUST act as if SRD has not happened yet.

What is the correct behavior? Discuss.

Please view or discuss this issue at https://github.com/w3c/webrtc-pc/issues/2502 using your GitHub account

Received on Monday, 30 March 2020 09:07:24 UTC