aboutsummaryrefslogtreecommitdiffstats
path: root/common/rdr
diff options
context:
space:
mode:
Diffstat (limited to 'common/rdr')
-rw-r--r--common/rdr/FdOutStream.cxx10
-rw-r--r--common/rdr/FdOutStream.h2
-rw-r--r--common/rdr/HexOutStream.cxx8
-rw-r--r--common/rdr/HexOutStream.h1
-rw-r--r--common/rdr/OutStream.h8
-rw-r--r--common/rdr/TLSOutStream.cxx18
-rw-r--r--common/rdr/TLSOutStream.h1
-rw-r--r--common/rdr/ZlibOutStream.cxx44
-rw-r--r--common/rdr/ZlibOutStream.h1
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: