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:
Michael Ratanapintha 2019-05-28 09:56:36 -07:00 committed by msftbot[bot]
parent 5f938a0465
commit 9ad2544033
2 changed files with 20 additions and 16 deletions

View file

@ -297,13 +297,19 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_terminal = std::make_unique<::Microsoft::Terminal::Core::Terminal>(); _terminal = std::make_unique<::Microsoft::Terminal::Core::Terminal>();
// First create the render thread. // 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>(); 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(); 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)); _renderer = std::make_unique<::Microsoft::Console::Render::Renderer>(_terminal.get(), nullptr, 0, std::move(renderThread));
::Microsoft::Console::Render::IRenderTarget& renderTarget = *_renderer; ::Microsoft::Console::Render::IRenderTarget& renderTarget = *_renderer;
THROW_IF_FAILED(localPointerToThread->Initialize(_renderer.get()));
// Set up the DX Engine // Set up the DX Engine
auto dxEngine = std::make_unique<::Microsoft::Console::Render::DxEngine>(); auto dxEngine = std::make_unique<::Microsoft::Console::Render::DxEngine>();
_renderer->AddRenderEngine(dxEngine.get()); _renderer->AddRenderEngine(dxEngine.get());
@ -350,8 +356,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
auto inputFn = std::bind(&TermControl::_SendInputToConnection, this, std::placeholders::_1); auto inputFn = std::bind(&TermControl::_SendInputToConnection, this, std::placeholders::_1);
_terminal->SetWriteInputCallback(inputFn); _terminal->SetWriteInputCallback(inputFn);
THROW_IF_FAILED(localPointerToThread->Initialize(_renderer.get()));
auto chain = _renderEngine->GetSwapChain(); auto chain = _renderEngine->GetSwapChain();
_swapChainPanel.Dispatcher().RunAsync(CoreDispatcherPriority::High, [this, chain]() _swapChainPanel.Dispatcher().RunAsync(CoreDispatcherPriority::High, [this, chain]()
{ {

View file

@ -12,42 +12,42 @@ using namespace Microsoft::Console::Render;
RenderThread::RenderThread() : RenderThread::RenderThread() :
_pRenderer(nullptr), _pRenderer(nullptr),
_hThread(INVALID_HANDLE_VALUE), _hThread(nullptr),
_hEvent(INVALID_HANDLE_VALUE), _hEvent(nullptr),
_hPaintCompletedEvent(INVALID_HANDLE_VALUE), _hPaintCompletedEvent(nullptr),
_fKeepRunning(true), _fKeepRunning(true),
_hPaintEnabledEvent(INVALID_HANDLE_VALUE) _hPaintEnabledEvent(nullptr)
{ {
} }
RenderThread::~RenderThread() RenderThread::~RenderThread()
{ {
if (_hThread != INVALID_HANDLE_VALUE) if (_hThread)
{ {
_fKeepRunning = false; // stop loop after final run _fKeepRunning = false; // stop loop after final run
SignalObjectAndWait(_hEvent, _hThread, INFINITE, FALSE); // signal final paint and wait for thread to finish. SignalObjectAndWait(_hEvent, _hThread, INFINITE, FALSE); // signal final paint and wait for thread to finish.
CloseHandle(_hThread); CloseHandle(_hThread);
_hThread = INVALID_HANDLE_VALUE; _hThread = nullptr;
} }
if (_hEvent != INVALID_HANDLE_VALUE) if (_hEvent)
{ {
CloseHandle(_hEvent); CloseHandle(_hEvent);
_hEvent = INVALID_HANDLE_VALUE; _hEvent = nullptr;
} }
if (_hPaintEnabledEvent != INVALID_HANDLE_VALUE) if (_hPaintEnabledEvent)
{ {
CloseHandle(_hPaintEnabledEvent); CloseHandle(_hPaintEnabledEvent);
_hPaintEnabledEvent = INVALID_HANDLE_VALUE; _hPaintEnabledEvent = nullptr;
} }
if (_hPaintCompletedEvent != INVALID_HANDLE_VALUE) if (_hPaintCompletedEvent)
{ {
CloseHandle(_hPaintCompletedEvent); CloseHandle(_hPaintCompletedEvent);
_hPaintCompletedEvent = INVALID_HANDLE_VALUE; _hPaintCompletedEvent = nullptr;
} }
} }