Bug 1837570 Comment 0 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

State mirroring from canonicals to mirrors is mirror-initialized. This means the mirrors connect to the canonicals [on the mirror's owning thread](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/xpcom/threads/StateMirroring.h#334).

In WebRTC we [do this in an async step](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/dom/media/webrtc/jsapi/RTCRtpTransceiver.cpp#309-324) in an otherwise sync task, which [exposes the object owning the canonicals to js synchronously](https://searchfox.org/mozilla-central/source/__GENERATED__/dom/bindings/RTCPeerConnectionBinding.cpp#10625). This can lead to (intermittent) problems if js can trigger dispatches that arrive to the target thread before the first state change task from the canonicals. The main problem is that no assumptions can be made on the state of the mirrors, and handling this would lead to unnecessary complexity.

In short there are races between async mirror setup and other types of dispatches like so:
- mirror setup:
  - [async mirror init](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/dom/media/webrtc/jsapi/RTCRtpTransceiver.cpp#309-324): main->target
  - [Canonical::AddMirror](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/xpcom/threads/StateMirroring.h#343): target->main
  - [Initial statechange](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/xpcom/threads/StateMirroring.h#145): main->target
- regular dispatch, say through a MediaEvent:
  - [async MediaEvent init](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/dom/media/webrtc/jsapi/RTCRtpTransceiver.cpp#309-324): main->target
  - [Connect](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/dom/media/webrtc/libwebrtcglue/AudioConduit.cpp#159) is [sync](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/dom/media/MediaEventSource.h#389-395): target
  - [MediaEventProducer::Notify](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/dom/media/webrtc/jsapi/RTCDTMFSender.cpp#136): main->target
- regular dispatch, through explicit Dispatch():
  - gets added in bug 1631263 so currently theoretical; main->target

Events will appear to run out of order:
- In the case of these events on the canonical side:
  - Async mirror init
  - MediaEventProducer::Notify
- The mirror side runs them in this order:
  - MediaEvent handler
  - Mirror watch handler

If there was a canonical-initialized mode (a single main->target step), or if mirrors could be added to canonicals synchronously, like how MediaEvent connects, we could make more assumptions on the state of the mirror side already when dispatching regular tasks from the canonical side, and this wouldn't be a problem.
State mirroring from canonicals to mirrors is mirror-initialized. This means the mirrors connect to the canonicals [on the mirrors' owning thread](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/xpcom/threads/StateMirroring.h#334).

In WebRTC we [do this in an async step](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/dom/media/webrtc/jsapi/RTCRtpTransceiver.cpp#309-324) in an otherwise sync task, which [exposes the object owning the canonicals to js synchronously](https://searchfox.org/mozilla-central/source/__GENERATED__/dom/bindings/RTCPeerConnectionBinding.cpp#10625). This can lead to (intermittent) problems if js can trigger dispatches that arrive to the target thread before the first state change task from the canonicals. The main problem is that no assumptions can be made on the state of the mirrors, and handling this would lead to unnecessary complexity.

In short there are races between async mirror setup and other types of dispatches like so:
- mirror setup:
  - [async mirror init](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/dom/media/webrtc/jsapi/RTCRtpTransceiver.cpp#309-324): main->target
  - [Canonical::AddMirror](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/xpcom/threads/StateMirroring.h#343): target->main
  - [Initial statechange](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/xpcom/threads/StateMirroring.h#145): main->target
- regular dispatch, say through a MediaEvent:
  - [async MediaEvent init](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/dom/media/webrtc/jsapi/RTCRtpTransceiver.cpp#309-324): main->target
  - [Connect](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/dom/media/webrtc/libwebrtcglue/AudioConduit.cpp#159) is [sync](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/dom/media/MediaEventSource.h#389-395): target
  - [MediaEventProducer::Notify](https://searchfox.org/mozilla-central/rev/2e06f92ba068e32a9a7213ee726e8171f91605c7/dom/media/webrtc/jsapi/RTCDTMFSender.cpp#136): main->target
- regular dispatch, through explicit Dispatch():
  - gets added in bug 1631263 so currently theoretical; main->target

Events will appear to run out of order:
- In the case of these events on the canonical side:
  - Async mirror init
  - MediaEventProducer::Notify
- The mirror side runs them in this order:
  - MediaEvent handler
  - Mirror watch handler

If there was a canonical-initialized mode (a single main->target step), or if mirrors could be added to canonicals synchronously, like how MediaEvent connects, we could make more assumptions on the state of the mirror side already when dispatching regular tasks from the canonical side, and this wouldn't be a problem.

Back to Bug 1837570 Comment 0