Fix #936: misuse of uninitialized objects causes AppVerifier breaks on Windows Terminal startup (#1015)
* move the render thread init up; gets rid of verifier stops * s/INVALID_HANDLE_VALUE/NULL/g since CreateEvent() and CreateThread() return a NULL HANDLE on failure; resolves another cause of AppVerifier breaks
This commit is contained in:
parent
5f938a0465
commit
9ad2544033
|
@ -297,13 +297,19 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
_terminal = std::make_unique<::Microsoft::Terminal::Core::Terminal>();
|
||||
|
||||
// First create the render thread.
|
||||
// Then stash a local pointer to the render thread so we can initialize it and enable it
|
||||
// to paint itself *after* we hand off its ownership to the renderer.
|
||||
// We split up construction and initialization of the render thread object this way
|
||||
// because the renderer and render thread have circular references to each other.
|
||||
auto renderThread = std::make_unique<::Microsoft::Console::Render::RenderThread>();
|
||||
// Stash a local pointer to the render thread, so we can enable it after
|
||||
// we hand off ownership to the renderer.
|
||||
auto* const localPointerToThread = renderThread.get();
|
||||
|
||||
// Now create the renderer and initialize the render thread.
|
||||
_renderer = std::make_unique<::Microsoft::Console::Render::Renderer>(_terminal.get(), nullptr, 0, std::move(renderThread));
|
||||
::Microsoft::Console::Render::IRenderTarget& renderTarget = *_renderer;
|
||||
|
||||
THROW_IF_FAILED(localPointerToThread->Initialize(_renderer.get()));
|
||||
|
||||
// Set up the DX Engine
|
||||
auto dxEngine = std::make_unique<::Microsoft::Console::Render::DxEngine>();
|
||||
_renderer->AddRenderEngine(dxEngine.get());
|
||||
|
@ -350,8 +356,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
auto inputFn = std::bind(&TermControl::_SendInputToConnection, this, std::placeholders::_1);
|
||||
_terminal->SetWriteInputCallback(inputFn);
|
||||
|
||||
THROW_IF_FAILED(localPointerToThread->Initialize(_renderer.get()));
|
||||
|
||||
auto chain = _renderEngine->GetSwapChain();
|
||||
_swapChainPanel.Dispatcher().RunAsync(CoreDispatcherPriority::High, [this, chain]()
|
||||
{
|
||||
|
|
|
@ -12,42 +12,42 @@ using namespace Microsoft::Console::Render;
|
|||
|
||||
RenderThread::RenderThread() :
|
||||
_pRenderer(nullptr),
|
||||
_hThread(INVALID_HANDLE_VALUE),
|
||||
_hEvent(INVALID_HANDLE_VALUE),
|
||||
_hPaintCompletedEvent(INVALID_HANDLE_VALUE),
|
||||
_hThread(nullptr),
|
||||
_hEvent(nullptr),
|
||||
_hPaintCompletedEvent(nullptr),
|
||||
_fKeepRunning(true),
|
||||
_hPaintEnabledEvent(INVALID_HANDLE_VALUE)
|
||||
_hPaintEnabledEvent(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RenderThread::~RenderThread()
|
||||
{
|
||||
if (_hThread != INVALID_HANDLE_VALUE)
|
||||
if (_hThread)
|
||||
{
|
||||
_fKeepRunning = false; // stop loop after final run
|
||||
SignalObjectAndWait(_hEvent, _hThread, INFINITE, FALSE); // signal final paint and wait for thread to finish.
|
||||
|
||||
CloseHandle(_hThread);
|
||||
_hThread = INVALID_HANDLE_VALUE;
|
||||
_hThread = nullptr;
|
||||
}
|
||||
|
||||
if (_hEvent != INVALID_HANDLE_VALUE)
|
||||
if (_hEvent)
|
||||
{
|
||||
CloseHandle(_hEvent);
|
||||
_hEvent = INVALID_HANDLE_VALUE;
|
||||
_hEvent = nullptr;
|
||||
}
|
||||
|
||||
if (_hPaintEnabledEvent != INVALID_HANDLE_VALUE)
|
||||
if (_hPaintEnabledEvent)
|
||||
{
|
||||
CloseHandle(_hPaintEnabledEvent);
|
||||
_hPaintEnabledEvent = INVALID_HANDLE_VALUE;
|
||||
_hPaintEnabledEvent = nullptr;
|
||||
}
|
||||
|
||||
if (_hPaintCompletedEvent != INVALID_HANDLE_VALUE)
|
||||
if (_hPaintCompletedEvent)
|
||||
{
|
||||
CloseHandle(_hPaintCompletedEvent);
|
||||
_hPaintCompletedEvent = INVALID_HANDLE_VALUE;
|
||||
_hPaintCompletedEvent = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue