diff options
Diffstat (limited to 'common/rdr')
-rw-r--r-- | common/rdr/FdOutStream.cxx | 10 | ||||
-rw-r--r-- | common/rdr/FdOutStream.h | 2 | ||||
-rw-r--r-- | common/rdr/HexOutStream.cxx | 8 | ||||
-rw-r--r-- | common/rdr/HexOutStream.h | 1 | ||||
-rw-r--r-- | common/rdr/OutStream.h | 8 | ||||
-rw-r--r-- | common/rdr/TLSOutStream.cxx | 18 | ||||
-rw-r--r-- | common/rdr/TLSOutStream.h | 1 | ||||
-rw-r--r-- | common/rdr/ZlibOutStream.cxx | 44 | ||||
-rw-r--r-- | common/rdr/ZlibOutStream.h | 1 |
9 files changed, 69 insertions, 24 deletions
diff --git a/common/rdr/FdOutStream.cxx b/common/rdr/FdOutStream.cxx index d7da7103..3405838d 100644 --- a/common/rdr/FdOutStream.cxx +++ b/common/rdr/FdOutStream.cxx @@ -77,6 +77,16 @@ unsigned FdOutStream::getIdleTime() return rfb::msSince(&lastWrite); } +void FdOutStream::cork(bool enable) +{ + BufferedOutStream::cork(enable); + +#ifdef TCP_CORK + int one = enable ? 1 : 0; + setsockopt(fd, IPPROTO_TCP, TCP_CORK, (char *)&one, sizeof(one)); +#endif +} + bool FdOutStream::flushBuffer(bool wait) { size_t n = writeWithTimeout((const void*) sentUpTo, diff --git a/common/rdr/FdOutStream.h b/common/rdr/FdOutStream.h index 24327972..b1fb74c0 100644 --- a/common/rdr/FdOutStream.h +++ b/common/rdr/FdOutStream.h @@ -43,6 +43,8 @@ namespace rdr { unsigned getIdleTime(); + virtual void cork(bool enable); + private: virtual bool flushBuffer(bool wait); size_t writeWithTimeout(const void* data, size_t length, int timeoutms); diff --git a/common/rdr/HexOutStream.cxx b/common/rdr/HexOutStream.cxx index 19c66851..88153c54 100644 --- a/common/rdr/HexOutStream.cxx +++ b/common/rdr/HexOutStream.cxx @@ -38,7 +38,6 @@ HexOutStream::~HexOutStream() { delete [] start; } - char HexOutStream::intToHex(int i) { if ((i>=0) && (i<=9)) return '0'+i; @@ -95,6 +94,13 @@ HexOutStream::flush() { out_stream.flush(); } +void HexOutStream::cork(bool enable) +{ + OutStream::cork(enable); + + out_stream.cork(enable); +} + void HexOutStream::overrun(size_t needed) { if (needed > bufSize) throw Exception("HexOutStream overrun: buffer size exceeded"); diff --git a/common/rdr/HexOutStream.h b/common/rdr/HexOutStream.h index 02366478..e591dd88 100644 --- a/common/rdr/HexOutStream.h +++ b/common/rdr/HexOutStream.h @@ -31,6 +31,7 @@ namespace rdr { void flush(); size_t length(); + virtual void cork(bool enable); static char intToHex(int i); static char* binToHexStr(const char* data, size_t length); diff --git a/common/rdr/OutStream.h b/common/rdr/OutStream.h index bb88f325..63c43169 100644 --- a/common/rdr/OutStream.h +++ b/common/rdr/OutStream.h @@ -34,7 +34,7 @@ namespace rdr { protected: - OutStream() {} + OutStream() : ptr(NULL), end(NULL), corked(false) {} public: @@ -128,6 +128,10 @@ namespace rdr { virtual void flush() {} + // cork() requests that the stream coalesces flushes in an efficient way + + virtual void cork(bool enable) { corked = enable; flush(); } + // getptr(), getend() and setptr() are "dirty" methods which allow you to // manipulate the buffer directly. This is useful for a stream which is a // wrapper around an underlying stream. @@ -147,6 +151,8 @@ namespace rdr { U8* ptr; U8* end; + + bool corked; }; } diff --git a/common/rdr/TLSOutStream.cxx b/common/rdr/TLSOutStream.cxx index 76f5dffe..7d59a9c7 100644 --- a/common/rdr/TLSOutStream.cxx +++ b/common/rdr/TLSOutStream.cxx @@ -82,7 +82,13 @@ size_t TLSOutStream::length() void TLSOutStream::flush() { - U8* sentUpTo = start; + U8* sentUpTo; + + // Only give GnuTLS larger chunks if corked to minimize overhead + if (corked && ((ptr - start) < 1024)) + return; + + sentUpTo = start; while (sentUpTo < ptr) { size_t n = writeTLS(sentUpTo, ptr - sentUpTo); sentUpTo += n; @@ -93,12 +99,22 @@ void TLSOutStream::flush() out->flush(); } +void TLSOutStream::cork(bool enable) +{ + OutStream::cork(enable); + + out->cork(enable); +} + void TLSOutStream::overrun(size_t needed) { if (needed > bufSize) throw Exception("TLSOutStream overrun: buffer size exceeded"); + // A cork might prevent the flush, so disable it temporarily + corked = false; flush(); + corked = true; } size_t TLSOutStream::writeTLS(const U8* data, size_t length) diff --git a/common/rdr/TLSOutStream.h b/common/rdr/TLSOutStream.h index 9ce6eb6d..c9750463 100644 --- a/common/rdr/TLSOutStream.h +++ b/common/rdr/TLSOutStream.h @@ -37,6 +37,7 @@ namespace rdr { void flush(); size_t length(); + virtual void cork(bool enable); protected: virtual void overrun(size_t needed); diff --git a/common/rdr/ZlibOutStream.cxx b/common/rdr/ZlibOutStream.cxx index 8f7170da..0eb89222 100644 --- a/common/rdr/ZlibOutStream.cxx +++ b/common/rdr/ZlibOutStream.cxx @@ -92,10 +92,25 @@ void ZlibOutStream::flush() #endif // Force out everything from the zlib encoder - deflate(Z_SYNC_FLUSH); + deflate(corked ? Z_NO_FLUSH : Z_SYNC_FLUSH); + + if (zs->avail_in == 0) { + offset += ptr - start; + ptr = start; + } else { + // didn't consume all the data? try shifting what's left to the + // start of the buffer. + memmove(start, zs->next_in, ptr - zs->next_in); + offset += zs->next_in - start; + ptr -= zs->next_in - start; + } +} + +void ZlibOutStream::cork(bool enable) +{ + OutStream::cork(enable); - offset += ptr - start; - ptr = start; + underlying->cork(enable); } void ZlibOutStream::overrun(size_t needed) @@ -110,24 +125,11 @@ void ZlibOutStream::overrun(size_t needed) checkCompressionLevel(); while (avail() < needed) { - zs->next_in = start; - zs->avail_in = ptr - start; - - deflate(Z_NO_FLUSH); - - // output buffer not full - - if (zs->avail_in == 0) { - offset += ptr - start; - ptr = start; - } else { - // but didn't consume all the data? try shifting what's left to the - // start of the buffer. - vlog.info("z out buf not full, but in data not consumed"); - memmove(start, zs->next_in, ptr - zs->next_in); - offset += zs->next_in - start; - ptr -= zs->next_in - start; - } + // use corked to make zlib a bit more efficient since we're not trying + // to end the stream here, just make some room + corked = true; + flush(); + corked = false; } } diff --git a/common/rdr/ZlibOutStream.h b/common/rdr/ZlibOutStream.h index 2b08f8d5..af917d89 100644 --- a/common/rdr/ZlibOutStream.h +++ b/common/rdr/ZlibOutStream.h @@ -42,6 +42,7 @@ namespace rdr { void setCompressionLevel(int level=-1); void flush(); size_t length(); + virtual void cork(bool enable); private: |