Symptoms
TestAppUWP is prone to a system-level race condition which puts the WebRTC threads in deadlock. This is due to the implementation of rtc::TaskQueue on UWP, which uses a combination of APC call and std::condition_variable. This results in the PeerConnection not being able to initialize, and manifests with:
- Lack of message in the Debug tab confirming the WebRTC plugin was initialized successfully.
- Disabled CreateOffer button.
This bug is limited to UWP. Desktop is not affected.
From testing experience this bug is more likely to trigger in Release config than in Debug config. Restarting the application is currently the only workaround.
Details
Several subsystems make use of the rtc::TaskQueue, which internally initializes as follow:
- Create an
rtc::Event
- Enqueue an APC call to
InitializeQueueThread()
- Wait for the event to be set
The rationale is that InitializeQueueThread() will set the event to indicate the thread is running, unblocking the initializing of its owning thread queue.
Unfortunately, the rules of APC calls say that a user-mode APC only runs when the thread is in alertable state, with the exception of calls enqueued before the thread begins running. This difference is behavior is the race condition that makes the bug appear or disappear depending on the timing of the thread startup. Combined with the fact that TaskQueue::Impl::ThreadMain() is waiting on an std::condition_variable, which is implemented as a slim read/write lock on Windows and therefore does not put the thread in an alertable state, the result is a race condition leading to a deadlock where the new thread waits on the SRW lock to be waken up and the task queue thread waits on that thread to execute its APC call.
Symptoms
TestAppUWP is prone to a system-level race condition which puts the WebRTC threads in deadlock. This is due to the implementation of
rtc::TaskQueueon UWP, which uses a combination of APC call andstd::condition_variable. This results in thePeerConnectionnot being able to initialize, and manifests with:This bug is limited to UWP. Desktop is not affected.
From testing experience this bug is more likely to trigger in Release config than in Debug config. Restarting the application is currently the only workaround.
Details
Several subsystems make use of the
rtc::TaskQueue, which internally initializes as follow:rtc::EventInitializeQueueThread()The rationale is that
InitializeQueueThread()will set the event to indicate the thread is running, unblocking the initializing of its owning thread queue.Unfortunately, the rules of APC calls say that a user-mode APC only runs when the thread is in alertable state, with the exception of calls enqueued before the thread begins running. This difference is behavior is the race condition that makes the bug appear or disappear depending on the timing of the thread startup. Combined with the fact that
TaskQueue::Impl::ThreadMain()is waiting on anstd::condition_variable, which is implemented as a slim read/write lock on Windows and therefore does not put the thread in an alertable state, the result is a race condition leading to a deadlock where the new thread waits on the SRW lock to be waken up and the task queue thread waits on that thread to execute its APC call.