diff --git a/src/libs/3rdparty/libptyqt/conptyprocess.cpp b/src/libs/3rdparty/libptyqt/conptyprocess.cpp index b50f319ebf1..d112f5e1533 100644 --- a/src/libs/3rdparty/libptyqt/conptyprocess.cpp +++ b/src/libs/3rdparty/libptyqt/conptyprocess.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include @@ -179,21 +180,19 @@ bool ConPtyProcess::startProcess(const QString &executable, m_pid = m_shellProcessInformation.dwProcessId; // Notify when the shell process has been terminated - RegisterWaitForSingleObject( - &m_shellCloseWaitHandle, - m_shellProcessInformation.hProcess, - [](PVOID data, BOOLEAN) { - auto self = static_cast(data); - DWORD exitCode = 0; - GetExitCodeProcess(self->m_shellProcessInformation.hProcess, &exitCode); - self->m_exitCode = exitCode; - // Do not respawn if the object is about to be destructed - if (!self->m_aboutToDestruct) - emit self->notifier()->aboutToClose(); - }, - this, - INFINITE, - WT_EXECUTEONLYONCE); + m_shellCloseWaitNotifier = new QWinEventNotifier(m_shellProcessInformation.hProcess, notifier()); + QObject::connect(m_shellCloseWaitNotifier, + &QWinEventNotifier::activated, + notifier(), + [this](HANDLE hEvent) { + DWORD exitCode = 0; + GetExitCodeProcess(hEvent, &exitCode); + m_exitCode = exitCode; + // Do not respawn if the object is about to be destructed + if (!m_aboutToDestruct) + emit notifier()->aboutToClose(); + m_shellCloseWaitNotifier->setEnabled(false); + }); //this code runned in separate thread m_readThread = QThread::create([this]() @@ -220,6 +219,8 @@ bool ConPtyProcess::startProcess(const QString &executable, if (QThread::currentThread()->isInterruptionRequested() || brokenPipe) break; } + + CancelIoEx(m_hPipeIn, nullptr); }); //start read thread @@ -269,6 +270,9 @@ bool ConPtyProcess::kill() m_readThread->deleteLater(); m_readThread = nullptr; + delete m_shellCloseWaitNotifier; + m_shellCloseWaitNotifier = nullptr; + m_pid = 0; m_ptyHandler = INVALID_HANDLE_VALUE; m_hPipeIn = INVALID_HANDLE_VALUE; @@ -276,7 +280,6 @@ bool ConPtyProcess::kill() CloseHandle(m_shellProcessInformation.hThread); CloseHandle(m_shellProcessInformation.hProcess); - UnregisterWait(m_shellCloseWaitHandle); // Cleanup attribute list if (m_shellStartupInfo.lpAttributeList) { diff --git a/src/libs/3rdparty/libptyqt/conptyprocess.h b/src/libs/3rdparty/libptyqt/conptyprocess.h index b3f77664c26..a22b6290c77 100644 --- a/src/libs/3rdparty/libptyqt/conptyprocess.h +++ b/src/libs/3rdparty/libptyqt/conptyprocess.h @@ -23,6 +23,8 @@ typedef VOID* HPCON; #define TOO_OLD_WINSDK #endif +class QWinEventNotifier; + template std::vector vectorFromString(const std::basic_string &str) { @@ -160,7 +162,7 @@ private: PtyBuffer m_buffer; bool m_aboutToDestruct{false}; PROCESS_INFORMATION m_shellProcessInformation{}; - HANDLE m_shellCloseWaitHandle{INVALID_HANDLE_VALUE}; + QWinEventNotifier* m_shellCloseWaitNotifier; STARTUPINFOEX m_shellStartupInfo{}; }; diff --git a/src/libs/3rdparty/libptyqt/winptyprocess.cpp b/src/libs/3rdparty/libptyqt/winptyprocess.cpp index 90ac139b9c3..be3a0de609e 100644 --- a/src/libs/3rdparty/libptyqt/winptyprocess.cpp +++ b/src/libs/3rdparty/libptyqt/winptyprocess.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include #define DEBUG_VAR_LEGACY "WINPTYDBG" #define DEBUG_VAR_ACTUAL "WINPTY_DEBUG" @@ -132,22 +134,22 @@ bool WinPtyProcess::startProcess(const QString &executable, m_pid = (int)GetProcessId(m_innerHandle); + m_outSocket = new QLocalSocket(); + // Notify when the shell process has been terminated - RegisterWaitForSingleObject( - &m_shellCloseWaitHandle, - m_innerHandle, - [](PVOID data, BOOLEAN) { - auto self = static_cast(data); - // Do not respawn if the object is about to be destructed - DWORD exitCode = 0; - GetExitCodeProcess(self->m_innerHandle, &exitCode); - self->m_exitCode = exitCode; - if (!self->m_aboutToDestruct) - emit self->notifier()->aboutToClose(); - }, - this, - INFINITE, - WT_EXECUTEONLYONCE); + m_shellCloseWaitNotifier = new QWinEventNotifier(m_innerHandle, notifier()); + QObject::connect(m_shellCloseWaitNotifier, + &QWinEventNotifier::activated, + notifier(), + [this](HANDLE hEvent) { + DWORD exitCode = 0; + GetExitCodeProcess(hEvent, &exitCode); + m_exitCode = exitCode; + // Do not respawn if the object is about to be destructed + if (!m_aboutToDestruct) + emit notifier()->aboutToClose(); + m_shellCloseWaitNotifier->setEnabled(false); + }); //get pipe names LPCWSTR conInPipeName = winpty_conin_name(m_ptyHandler); @@ -158,7 +160,6 @@ bool WinPtyProcess::startProcess(const QString &executable, LPCWSTR conOutPipeName = winpty_conout_name(m_ptyHandler); m_conOutName = QString::fromStdWString(std::wstring(conOutPipeName)); - m_outSocket = new QLocalSocket(); m_outSocket->connectToServer(m_conOutName, QIODevice::ReadOnly); m_outSocket->waitForConnected(); @@ -214,7 +215,8 @@ bool WinPtyProcess::kill() winpty_free(m_ptyHandler); exitCode = CloseHandle(m_innerHandle); - UnregisterWait(m_shellCloseWaitHandle); + delete m_shellCloseWaitNotifier; + m_shellCloseWaitNotifier = nullptr; m_ptyHandler = nullptr; m_innerHandle = nullptr; diff --git a/src/libs/3rdparty/libptyqt/winptyprocess.h b/src/libs/3rdparty/libptyqt/winptyprocess.h index 547bcf7c97a..0bfb27c02c4 100644 --- a/src/libs/3rdparty/libptyqt/winptyprocess.h +++ b/src/libs/3rdparty/libptyqt/winptyprocess.h @@ -4,7 +4,8 @@ #include "iptyprocess.h" #include "winpty.h" -#include +class QLocalSocket; +class QWinEventNotifier; class WinPtyProcess : public IPtyProcess { @@ -36,7 +37,7 @@ private: QLocalSocket *m_inSocket; QLocalSocket *m_outSocket; bool m_aboutToDestruct{false}; - HANDLE m_shellCloseWaitHandle{INVALID_HANDLE_VALUE}; + QWinEventNotifier* m_shellCloseWaitNotifier; }; #endif // WINPTYPROCESS_H