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/unix/slang-unix-process.cpp | 72 ++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 5 deletions(-) (limited to 'source/core/unix/slang-unix-process.cpp') diff --git a/source/core/unix/slang-unix-process.cpp b/source/core/unix/slang-unix-process.cpp index 083160f02..5131e37ec 100644 --- a/source/core/unix/slang-unix-process.cpp +++ b/source/core/unix/slang-unix-process.cpp @@ -28,7 +28,9 @@ class UnixProcess : 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 returnValue) SLANG_OVERRIDE; + virtual void kill(int32_t returnValue) SLANG_OVERRIDE; UnixProcess(pid_t pid, Stream*const* streams); @@ -133,9 +135,64 @@ bool UnixProcess::isTerminated() return _updateTerminationState(WNOHANG); } -void UnixProcess::waitForTermination() +bool UnixProcess::waitForTermination(Int timeInMs) { - while (!_updateTerminationState(0)); + // If < 0 we will wait blocking until terminated + if (timeInMs < 0) + { + while (!_updateTerminationState(0)); + return true; + } + + // Note that the amount of time waiting is very approximate (we are relying on sleeps time and don't take into + // account time outside of sleeping) + + // How often to test + const Int checkRateMs = 100; /// Check every 0.1 seconds + + while (timeInMs > 0) + { + if (_updateTerminationState(WNOHANG)) + { + return true; + } + + // Work out how long to sleep for + const Int sleepMs = (timeInMs >= checkRateMs) ? checkRateMs : timeInMs; + + // Sleep + sleepCurrentThread(sleepMs); + + timeInMs -= sleepMs; + } + + return _updateTerminationState(WNOHANG); +} + +void UnixProcess::terminate(int32_t returnValue) +{ + // Using this mechanism, we can't set a returnValue so just ignore + SLANG_UNUSED(returnValue); + + if (!isTerminated()) + { + // Request the process terminates + ::kill(m_pid, SIGTERM); + } +} + +void UnixProcess::kill(int32_t returnValue) +{ + if (!isTerminated()) + { + // We waited, lets just terminate with kill + ::kill(m_pid, SIGKILL); + + // Set the return value + m_returnValue = returnValue; + // Mark as terminated + m_isTerminated = true; + } } /* !!!!!!!!!!!!!!!!!!!!!! UnixPipeStream !!!!!!!!!!!!!!!!!!!!!!!!!!!! */ @@ -386,15 +443,20 @@ SlangResult UnixPipeStream::write(const void* buffer, size_t length) return uint64_t(now.tv_sec) * 1000000000 + now.tv_nsec; } -/* static */void Process::sleepCurrentThread(Index timeInMs) +/* static */void Process::sleepCurrentThread(Int timeInMs) { struct timespec timeSpec; - if (timeInMs > 0) + if (timeInMs >= 1000) { timeSpec.tv_sec = timeInMs / 1000; timeSpec.tv_nsec = (timeInMs % 1000) * 1000 * 1000; } + else if (timeInMs > 0) + { + timeSpec.tv_sec = 0; + timeSpec.tv_nsec = timeInMs * 1000 * 1000; + } else { timeSpec.tv_sec = 0; -- cgit v1.2.3