Move socket write event handling in to the RFB core

What to do when a socket is writeable should be handled in the
RFB core code as there may be other events we want to fire off
when this happens.
diff --git a/common/rfb/HTTPServer.cxx b/common/rfb/HTTPServer.cxx
index f50722a..54becbb 100644
--- a/common/rfb/HTTPServer.cxx
+++ b/common/rfb/HTTPServer.cxx
@@ -337,7 +337,7 @@
 }
 
 void
-HTTPServer::processSocketEvent(network::Socket* sock) {
+HTTPServer::processSocketReadEvent(network::Socket* sock) {
   std::list<Session*>::iterator i;
   for (i=sessions.begin(); i!=sessions.end(); i++) {
     if ((*i)->getSock() == sock) {
@@ -356,6 +356,23 @@
   throw rdr::Exception("invalid Socket in HTTPServer");
 }
 
+void
+HTTPServer::processSocketWriteEvent(network::Socket* sock) {
+  std::list<Session*>::iterator i;
+  for (i=sessions.begin(); i!=sessions.end(); i++) {
+    if ((*i)->getSock() == sock) {
+      try {
+        sock->outStream().flush();
+      } catch (rdr::Exception& e) {
+        vlog.error("untrapped: %s", e.str());
+        sock->shutdown();
+      }
+      return;
+    }
+  }
+  throw rdr::Exception("invalid Socket in HTTPServer");
+}
+
 void HTTPServer::getSockets(std::list<network::Socket*>* sockets)
 {
   sockets->clear();
diff --git a/common/rfb/HTTPServer.h b/common/rfb/HTTPServer.h
index 6412946..d7ca69a 100644
--- a/common/rfb/HTTPServer.h
+++ b/common/rfb/HTTPServer.h
@@ -58,11 +58,16 @@
     //   Could clean up socket-specific resources here.
     virtual void removeSocket(network::Socket* sock);
 
-    // processSocketEvent()
+    // processSocketReadEvent()
     //   The platform-specific side of the server implementation calls
     //   this method whenever data arrives on one of the active
     //   network sockets.
-    virtual void processSocketEvent(network::Socket* sock);
+    virtual void processSocketReadEvent(network::Socket* sock);
+
+    // processSocketWriteEvent()
+    //   Similar to processSocketReadEvent(), but called when it is
+    //   possible to write more data to a socket.
+    virtual void processSocketWriteEvent(network::Socket* sock);
 
     // Check for socket timeouts
     virtual int checkTimeouts();
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index 932f579..0f4ca94 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -190,6 +190,17 @@
   }
 }
 
+void VNCSConnectionST::flushSocket()
+{
+  if (state() == RFBSTATE_CLOSING) return;
+  try {
+    setSocketTimeouts();
+    sock->outStream().flush();
+  } catch (rdr::Exception &e) {
+    close(e.str());
+  }
+}
+
 void VNCSConnectionST::pixelBufferChange()
 {
   try {
diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h
index 72ffc1d..55b7ca3 100644
--- a/common/rfb/VNCSConnectionST.h
+++ b/common/rfb/VNCSConnectionST.h
@@ -65,6 +65,9 @@
     // Socket if an error occurs, via the close() call.
     void processMessages();
 
+    // flushSocket() pushes any unwritten data on to the network.
+    void flushSocket();
+
     // Called when the underlying pixelbuffer is resized or replaced.
     void pixelBufferChange();
 
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
index 199524e..d501085 100644
--- a/common/rfb/VNCServerST.cxx
+++ b/common/rfb/VNCServerST.cxx
@@ -163,7 +163,7 @@
   closingSockets.remove(sock);
 }
 
-void VNCServerST::processSocketEvent(network::Socket* sock)
+void VNCServerST::processSocketReadEvent(network::Socket* sock)
 {
   // - Find the appropriate VNCSConnectionST and process the event
   std::list<VNCSConnectionST*>::iterator ci;
@@ -176,6 +176,19 @@
   throw rdr::Exception("invalid Socket in VNCServerST");
 }
 
+void VNCServerST::processSocketWriteEvent(network::Socket* sock)
+{
+  // - Find the appropriate VNCSConnectionST and process the event
+  std::list<VNCSConnectionST*>::iterator ci;
+  for (ci = clients.begin(); ci != clients.end(); ci++) {
+    if ((*ci)->getSock() == sock) {
+      (*ci)->flushSocket();
+      return;
+    }
+  }
+  throw rdr::Exception("invalid Socket in VNCServerST");
+}
+
 int VNCServerST::checkTimeouts()
 {
   int timeout = 0;
diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h
index 1e055dd..bd84c45 100644
--- a/common/rfb/VNCServerST.h
+++ b/common/rfb/VNCServerST.h
@@ -67,11 +67,15 @@
     //   Clean up any resources associated with the Socket
     virtual void removeSocket(network::Socket* sock);
 
-    // processSocketEvent
+    // processSocketReadEvent
     //   Read more RFB data from the Socket.  If an error occurs during
     //   processing then shutdown() is called on the Socket, causing
     //   removeSocket() to be called by the caller at a later time.
-    virtual void processSocketEvent(network::Socket* sock);
+    virtual void processSocketReadEvent(network::Socket* sock);
+
+    // processSocketWriteEvent
+    //   Flush pending data from the Socket on to the network.
+    virtual void processSocketWriteEvent(network::Socket* sock);
 
     // checkTimeouts
     //   Returns the number of milliseconds left until the next idle timeout