Compare commits

...

1 Commits

Author SHA1 Message Date
Dustin L. Howett
6446611bca render: check the thread exit condition after every long operation
We have received an internal report that teardown on OneCore is still
hanging. It looks like there's a chance that `TriggerTeardown` is called
during `PaintFrame`, which may result in `_threadShouldKeepRunning`
getting set to `false` (TriggerTeardown) and `_redraw` being set to
`false` as well (PaintFrame). The thread will wait forever on `_redraw`
to be signalled, which it never will, because `TriggerTeardown` is
waiting for the thread to exit.

That is:

```
Render Thread      | ConIoSrv Thread
------------------------------------
Check _enabled     |
Wait on _redraw    |
Check _keepRunning | TriggerTeardown
Paint              |   _keepRunning = false
                   |   _redraw = true
    _redraw = false|   Signal _enabled
Paint Completes    |   Wait on thread
Check _enabled     |
Wait on _redraw    |
**DEADLOCK**       | **DEADLOCK**
                   v
```

This may not be an ideal fix, but at least it checks
`_threadShouldKeepRunning` after every "long" operation (waiting and
painting) now.
2026-04-08 18:33:47 -05:00

View File

@@ -119,12 +119,15 @@ DWORD WINAPI Renderer::s_renderThread(void* param) noexcept
DWORD Renderer::_renderThread() noexcept
{
while (true)
while (_threadKeepRunning.load(std::memory_order_relaxed))
{
_enable.wait();
_waitUntilCanRender();
_waitUntilTimerOrRedraw();
// We just completed what could have been a long wait;
// eagerly check again to prevent rendering if we don't
// need to.
if (!_threadKeepRunning.load(std::memory_order_relaxed))
{
break;