mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-12 17:21:03 +00:00
Fix unbalanced unlock in PtySignalInputThread::_Shutdown (#12181)
The only way to notice that LeaveCriticalSection() was called more often than EnterCriticalSection() is by calling EnterCriticalSection() again in the future, which will then deadlock. Since this bug occurs on exit it wasn't noticeable with the old console lock. With the new, stricter ticket lock this bug causes a fail-fast exit. ## PR Checklist * [x] Closes #12168 * [x] I work here * [x] Tests added/passed ## Validation Steps Performed * Launch and then exit Windows Terminal * OpenConsole cleanly exits ✅
This commit is contained in:
@@ -170,7 +170,6 @@ bool PtySignalInputThread::_GetData(_Out_writes_bytes_(cbBuffer) void* const pBu
|
||||
if (lastError == ERROR_BROKEN_PIPE)
|
||||
{
|
||||
_Shutdown();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -180,7 +179,6 @@ bool PtySignalInputThread::_GetData(_Out_writes_bytes_(cbBuffer) void* const pBu
|
||||
else if (dwRead != cbBuffer)
|
||||
{
|
||||
_Shutdown();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -233,6 +231,7 @@ void PtySignalInputThread::_Shutdown()
|
||||
// happens if this method is called outside of lock, but if we're
|
||||
// currently locked, we want to make sure ctrl events are handled
|
||||
// _before_ we RundownAndExit.
|
||||
LockConsole();
|
||||
ProcessCtrlEvents();
|
||||
|
||||
// Make sure we terminate.
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "../renderer/base/renderer.hpp"
|
||||
#include "../types/inc/utils.hpp"
|
||||
#include "handle.h" // LockConsole
|
||||
#include "input.h" // ProcessCtrlEvents
|
||||
#include "output.h" // CloseConsoleProcessState
|
||||
|
||||
@@ -383,6 +384,7 @@ void VtIo::_ShutdownIfNeeded()
|
||||
// happens if this method is called outside of lock, but if we're
|
||||
// currently locked, we want to make sure ctrl events are handled
|
||||
// _before_ we RundownAndExit.
|
||||
LockConsole();
|
||||
ProcessCtrlEvents();
|
||||
|
||||
// Make sure we terminate.
|
||||
|
||||
@@ -520,5 +520,5 @@ void CloseConsoleProcessState()
|
||||
// ctrl event will never actually get dispatched.
|
||||
// So, lock and unlock here, to make sure the ctrl event gets handled.
|
||||
LockConsole();
|
||||
auto Unlock = wil::scope_exit([&] { UnlockConsole(); });
|
||||
UnlockConsole();
|
||||
}
|
||||
|
||||
@@ -163,7 +163,6 @@ bool HostSignalInputThread::_GetData(gsl::span<gsl::byte> buffer)
|
||||
if (lastError == ERROR_BROKEN_PIPE)
|
||||
{
|
||||
_Shutdown();
|
||||
return false;
|
||||
}
|
||||
|
||||
THROW_WIN32(lastError);
|
||||
@@ -172,7 +171,6 @@ bool HostSignalInputThread::_GetData(gsl::span<gsl::byte> buffer)
|
||||
if (bytesRead != buffer.size())
|
||||
{
|
||||
_Shutdown();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -34,7 +34,7 @@ wil::unique_hwnd ServiceLocator::s_pseudoWindow = nullptr;
|
||||
|
||||
#pragma region Public Methods
|
||||
|
||||
void ServiceLocator::RundownAndExit(const HRESULT hr)
|
||||
[[noreturn]] void ServiceLocator::RundownAndExit(const HRESULT hr)
|
||||
{
|
||||
// MSFT:15506250
|
||||
// In VT I/O Mode, a client application might die before we've rendered
|
||||
@@ -67,7 +67,7 @@ void ServiceLocator::RundownAndExit(const HRESULT hr)
|
||||
s_inputServices.reset(nullptr);
|
||||
}
|
||||
|
||||
TerminateProcess(GetCurrentProcess(), hr);
|
||||
ExitProcess(hr);
|
||||
}
|
||||
|
||||
#pragma region Creation Methods
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Microsoft::Console::Interactivity
|
||||
class ServiceLocator final
|
||||
{
|
||||
public:
|
||||
static void RundownAndExit(const HRESULT hr);
|
||||
[[noreturn]] static void RundownAndExit(const HRESULT hr);
|
||||
|
||||
// N.B.: Location methods without corresponding creation methods
|
||||
// automatically create the singleton object on demand.
|
||||
|
||||
Reference in New Issue
Block a user