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>();
// 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]()
{

View file

@ -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;
}
}