forked from qt-creator/qt-creator
Terminal: Use QWinEventNotifier for shell process termination
Change-Id: I59ddcaa76714a0b15987b9e0912f4701a2951648 Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
committed by
Marcus Tillmanns
parent
3287e14dd1
commit
007c47a2d4
35
src/libs/3rdparty/libptyqt/conptyprocess.cpp
vendored
35
src/libs/3rdparty/libptyqt/conptyprocess.cpp
vendored
@@ -6,6 +6,7 @@
|
||||
#include <QTimer>
|
||||
#include <QMutexLocker>
|
||||
#include <QCoreApplication>
|
||||
#include <QWinEventNotifier>
|
||||
|
||||
#include <qt_windows.h>
|
||||
|
||||
@@ -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<ConPtyProcess *>(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) {
|
||||
|
4
src/libs/3rdparty/libptyqt/conptyprocess.h
vendored
4
src/libs/3rdparty/libptyqt/conptyprocess.h
vendored
@@ -23,6 +23,8 @@ typedef VOID* HPCON;
|
||||
#define TOO_OLD_WINSDK
|
||||
#endif
|
||||
|
||||
class QWinEventNotifier;
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> vectorFromString(const std::basic_string<T> &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{};
|
||||
};
|
||||
|
||||
|
36
src/libs/3rdparty/libptyqt/winptyprocess.cpp
vendored
36
src/libs/3rdparty/libptyqt/winptyprocess.cpp
vendored
@@ -3,6 +3,8 @@
|
||||
#include <QFileInfo>
|
||||
#include <sstream>
|
||||
#include <QCoreApplication>
|
||||
#include <QLocalSocket>
|
||||
#include <QWinEventNotifier>
|
||||
|
||||
#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<WinPtyProcess *>(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;
|
||||
|
5
src/libs/3rdparty/libptyqt/winptyprocess.h
vendored
5
src/libs/3rdparty/libptyqt/winptyprocess.h
vendored
@@ -4,7 +4,8 @@
|
||||
#include "iptyprocess.h"
|
||||
#include "winpty.h"
|
||||
|
||||
#include <QLocalSocket>
|
||||
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
|
||||
|
Reference in New Issue
Block a user