From 8a9e518371df03b3f382e0fe869da83751fdda0b Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Wed, 10 Nov 2021 17:33:22 -0500 Subject: Interprocess communication via pipes (#2009) * #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. --- source/core/slang-stream.h | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'source/core/slang-stream.h') diff --git a/source/core/slang-stream.h b/source/core/slang-stream.h index e33e1c601..f6c9f54a3 100644 --- a/source/core/slang-stream.h +++ b/source/core/slang-stream.h @@ -43,6 +43,9 @@ public: /// Implies any pending data is flushed. virtual void close() = 0; + /// Only applicable for write streams, flushes any buffers to underlying representation (such as pipe, or file) + virtual SlangResult flush() = 0; + /// Helper function that will also *fail* if the specified amount of bytes aren't read. SlangResult readExactly(void* buffer, size_t length); }; @@ -76,6 +79,7 @@ public: virtual bool canRead() SLANG_OVERRIDE { return (int(m_access) & int(FileAccess::Read)) != 0; } virtual bool canWrite() SLANG_OVERRIDE { return (int(m_access) & int(FileAccess::Write)) != 0; } virtual void close() SLANG_OVERRIDE { m_access = FileAccess::None; } + virtual SlangResult flush() SLANG_OVERRIDE { return canWrite() ? SLANG_OK : SLANG_E_NOT_AVAILABLE; } /// Get the contents ConstArrayView getContents() const { return ConstArrayView(m_contents, m_contentsSize); } @@ -159,6 +163,7 @@ public: virtual bool canWrite() SLANG_OVERRIDE; virtual void close() SLANG_OVERRIDE; virtual bool isEnd() SLANG_OVERRIDE; + virtual SlangResult flush() SLANG_OVERRIDE; FileStream(); @@ -175,6 +180,62 @@ private: bool m_endReached = false; }; +/* A simple BufferedReader. The valid data is between m_startIndex and getCount(). +Can be used as a buffer to build up a result from a stream in memory using 'update' to read to the appropriate buffer size. +*/ +class BufferedReadStream : public Stream +{ +public: + typedef Stream Super; + + virtual Int64 getPosition() SLANG_OVERRIDE; + virtual SlangResult seek(SeekOrigin origin, Int64 offset) SLANG_OVERRIDE; + virtual SlangResult read(void* buffer, size_t length, size_t& outReadBytes) SLANG_OVERRIDE; + virtual SlangResult write(const void* buffer, size_t length) SLANG_OVERRIDE; + virtual bool canRead() SLANG_OVERRIDE; + virtual bool canWrite() SLANG_OVERRIDE; + virtual void close() SLANG_OVERRIDE; + virtual bool isEnd() SLANG_OVERRIDE; + virtual SlangResult flush() SLANG_OVERRIDE; + + /// Will read assuming backing stream is + SlangResult update(); + + Byte* getBuffer() { return m_buffer.getBuffer() + m_startIndex; } + const Byte* getBuffer() const { return m_buffer.getBuffer() + m_startIndex; } + + size_t getCount() const { return m_buffer.getCount() - m_startIndex; } + + ConstArrayView getView() const { return ConstArrayView(getBuffer(), Index(getCount())); } + ArrayView getView() { return ArrayView(getBuffer(), Index(getCount())); } + +protected: + void _advanceStartIndex(Index byteCount); + + size_t m_defaultReadSize = 1024; ///< When initiating a read the default read size + List m_buffer; ///< Holds the characters + Index m_startIndex; ///< The start index + RefPtr m_stream; ///< Stream that is being read from +}; + +struct StreamUtil +{ + /// Appends all bytes that can be read from stream into bytes + static SlangResult readAll(Stream* stream, size_t readSize, List& ioBytes); + + /// Read as much as can be read until a 0 sized read, or an error and append onto ioBytes + /// Read size controls the size of each buffer read. Passing 0, will use the default read size. + static SlangResult read(Stream* stream, size_t readSize, List& ioBytes); + + static SlangResult discard(Stream* stream); + + static SlangResult discardAll(Stream* stream); + + static SlangResult readOrDiscard(Stream* stream, size_t readSize, List* ioBytes); + static SlangResult readOrDiscardAll(Stream* stream, size_t readSize, List* ioBytes); +}; + + } // namespace Slang #endif -- cgit v1.2.3