terminal/src/host/PtySignalInputThread.hpp
Michael Niksa 1b79cc87c3
Fix startup race of resizing ConPTY (#10449)
Fix startup race of resizing ConPTY

- Depending on what the timing and ordering is of the message coming in
  from the signal thread, it may be applied to the startup structure
  after the I/O thread has begun initializing the console buffer
  structures but before it has signaled that it is done and the signal
  thread is ready to make changes directly. This likely happens because
  the end of the I/O thread setup has a weird unlock/lock jog for the
  input thread and the signal thread might have been scheduled in the
  middle of it.
- My resolution here is to ensure that the signal thread just keeps
  storing the latest resize message until it is told that everything is
  initialized. Whomever comes in to tell the signal thread this
  information (under lock) will pickup and run the resize if one came in
  before everything was ready. This should resolve the race.

## Validation Steps Performed
- o-sdn-o confirms this resolves their issue

Closes #10400
2021-06-22 19:23:16 +00:00

60 lines
1.6 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- PtySignalInputThread.hpp
Abstract:
- Defines methods that wrap the thread that will wait for Pty Signals
if a Pty server (VT server) is running.
Author(s):
- Mike Griese (migrie) 15 Aug 2017
- Michael Niksa (miniksa) 19 Jan 2018
--*/
#pragma once
namespace Microsoft::Console
{
class PtySignalInputThread final
{
public:
PtySignalInputThread(_In_ wil::unique_hfile hPipe);
~PtySignalInputThread();
[[nodiscard]] HRESULT Start() noexcept;
static DWORD WINAPI StaticThreadProc(_In_ LPVOID lpParameter);
// Prevent copying and assignment.
PtySignalInputThread(const PtySignalInputThread&) = delete;
PtySignalInputThread& operator=(const PtySignalInputThread&) = delete;
void ConnectConsole() noexcept;
private:
enum class PtySignal : unsigned short
{
ResizeWindow = 8
};
struct ResizeWindowData
{
unsigned short sx;
unsigned short sy;
};
[[nodiscard]] HRESULT _InputThread();
bool _GetData(_Out_writes_bytes_(cbBuffer) void* const pBuffer, const DWORD cbBuffer);
void _DoResizeWindow(const ResizeWindowData& data);
void _Shutdown();
wil::unique_hfile _hFile;
wil::unique_handle _hThread;
DWORD _dwThreadId;
bool _consoleConnected;
std::optional<ResizeWindowData> _earlyResize;
std::unique_ptr<Microsoft::Console::VirtualTerminal::ConGetSet> _pConApi;
};
}