Don't try to push out another update if the socket is already full. This
avoids stalling the entire server because of one slow client.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4737 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index 4ca58ac..34be0ef 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -37,8 +37,8 @@
: SConnection(reverse), sock(s), server(server_),
updates(false), image_getter(server->useEconomicTranslate),
drawRenderedCursor(false), removeRenderedCursor(false),
- pointerEventTime(0), accessRights(AccessDefault),
- startTime(time(0))
+ updateTimer(this), pointerEventTime(0),
+ accessRights(AccessDefault), startTime(time(0))
{
setStreams(&sock->inStream(), &sock->outStream());
peerEndpoint.buf = sock->getPeerEndpoint();
@@ -625,11 +625,40 @@
}
+bool VNCSConnectionST::handleTimeout(Timer* t)
+{
+ if (t == &updateTimer)
+ writeFramebufferUpdateOrClose();
+
+ return false;
+}
+
+
+bool VNCSConnectionST::isCongested()
+{
+ int offset, space;
+
+ if (sock->outStream().bufferUsage() > 0)
+ return true;
+
+ return false;
+}
+
+
void VNCSConnectionST::writeFramebufferUpdate()
{
+ updateTimer.stop();
+
if (state() != RFBSTATE_NORMAL || requested.is_empty())
return;
+ // Check that we actually have some space on the link and retry in a
+ // bit if things are congested.
+ if (isCongested()) {
+ updateTimer.start(50);
+ return;
+ }
+
// First take care of any updates that cannot contain framebuffer data
// changes.
if (writer()->needNoDataUpdate()) {
diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h
index c9e4ac8..abf4383 100644
--- a/common/rfb/VNCSConnectionST.h
+++ b/common/rfb/VNCSConnectionST.h
@@ -32,10 +32,12 @@
#include <rfb/SMsgWriter.h>
#include <rfb/TransImageGetter.h>
#include <rfb/VNCServerST.h>
+#include <rfb/Timer.h>
namespace rfb {
class VNCSConnectionST : public SConnection,
- public WriteSetCursorCallback {
+ public WriteSetCursorCallback,
+ public Timer::Callback {
public:
VNCSConnectionST(VNCServerST* server_, network::Socket* s, bool reverse);
virtual ~VNCSConnectionST();
@@ -140,8 +142,13 @@
// WriteSetCursorCallback
virtual void writeSetCursorCallback();
+ // Timer callbacks
+ virtual bool handleTimeout(Timer* t);
+
// Internal methods
+ bool isCongested();
+
// writeFramebufferUpdate() attempts to write a framebuffer update to the
// client.
@@ -161,6 +168,8 @@
bool drawRenderedCursor, removeRenderedCursor;
Rect renderedCursorRect;
+ Timer updateTimer;
+
std::set<rdr::U32> pressedKeys;
time_t lastEventTime;