From c51f1e27f0e307a80a57a840b2337e3226b3c2be Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Tue, 16 Nov 2021 08:54:55 -0500 Subject: Support around JSON-RPC (#2014) * #include an absolute path didn't work - because paths were taken to always be relative. * Use 'Process' to communicate with an command line tool. * Remove slang-win-stream * Tidy up windows ProcessUtil. * First version of BufferedReadStream. * Windows working IPC for steams. * Test proxy count option. * Split Process/ProcessUtil. Process is platform dependant. ProcessUtil are functions that are platform independent. * First implementation of Unix Process interface. * Unix process compiles on cygwin. * Fix typo in unix process. * Separate unix pipe stream error of invalid access, from pipe availability. * Fix in standard line extraction. * Make fd non blocking. * Fix issues with Windows Process streams. * Added UnixPipe. * Some fixes around UnixPipeStream. * Make a unix stream closed explicit. * Hack to debug linux process/stream. * Revert to old linux pipe handling. * Pass executable path for unit tests. Split out CommandLine into own source. * Small improvements in process/command line. * Check process behavior with crash. * Make stderr and stdout unbuffered for crash testing. * Only turn disable buffering in crash test. * Disable crash test on CI. * Fix crash on clang/linux. * Enable crash test. Remove _appendBuffer as can use StreamUtil functionality. * Added inital processing for http headers. * Small improvements to HttpHeader. * First pass HTTPPacketConnection working on windows. * Enable other Process communication tests. * Update comments. * WIP JSON RPC. * Add terminate to Process. Made JSONRPC a Util. * Small tidy up around HTTPPacketConnection. * Improve process termination options. Co-authored-by: Yong He --- source/core/windows/slang-win-process.cpp | 50 ++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 14 deletions(-) (limited to 'source/core/windows/slang-win-process.cpp') diff --git a/source/core/windows/slang-win-process.cpp b/source/core/windows/slang-win-process.cpp index c37936a30..ed06f5692 100644 --- a/source/core/windows/slang-win-process.cpp +++ b/source/core/windows/slang-win-process.cpp @@ -111,8 +111,11 @@ class WinProcess : public Process { public: + // Process virtual bool isTerminated() SLANG_OVERRIDE; - virtual void waitForTermination() SLANG_OVERRIDE; + virtual bool waitForTermination(Int timeInMs) SLANG_OVERRIDE; + virtual void terminate(int32_t returnCode) SLANG_OVERRIDE; + virtual void kill(int32_t returnCode) SLANG_OVERRIDE; WinProcess(HANDLE handle, Stream* const* streams) : m_processHandle(handle) @@ -300,7 +303,7 @@ void WinProcess::_hasTerminated() // https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-getexitcodeprocess DWORD childExitCode = 0; - if (GetExitCodeProcess(m_processHandle, &childExitCode)) + if (::GetExitCodeProcess(m_processHandle, &childExitCode)) { m_returnValue = int32_t(childExitCode); } @@ -308,35 +311,54 @@ void WinProcess::_hasTerminated() } } -void WinProcess::waitForTermination() +bool WinProcess::waitForTermination(Int timeInMs) { if (m_processHandle.isNull()) { - return; + return true; } + const DWORD timeOutTime = (timeInMs < 0) ? INFINITE : DWORD(timeInMs); + // wait for the process to exit // TODO: set a timeout as a safety measure... - WaitForSingleObject(m_processHandle, INFINITE); + auto res = ::WaitForSingleObject(m_processHandle, timeOutTime); + + if (res == WAIT_TIMEOUT) + { + return false; + } _hasTerminated(); + return true; } bool WinProcess::isTerminated() { - if (m_processHandle.isNull()) + return waitForTermination(0); +} + +void WinProcess::terminate(int32_t returnCode) +{ + if (!isTerminated()) { - return true; + // If it's not terminated, try terminating. + // Might take time, so use isTerminated to check + ::TerminateProcess(m_processHandle, UINT32(returnCode)); } +} - auto res = WaitForSingleObject(m_processHandle, 0); - - if (res == WAIT_TIMEOUT) +void WinProcess::kill(int32_t returnCode) +{ + if (!isTerminated()) { - return false; + // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminateprocess + ::TerminateProcess(m_processHandle, UINT32(returnCode)); + + // Just assume it's done and set the return code + m_returnValue = returnCode; + m_processHandle.setNull(); } - _hasTerminated(); - return true; } /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ @@ -505,7 +527,7 @@ bool WinProcess::isTerminated() return SLANG_OK; } -/* static */void Process::sleepCurrentThread(Index timeInMs) +/* static */void Process::sleepCurrentThread(Int timeInMs) { ::Sleep(DWORD(timeInMs)); } -- cgit v1.2.3