Fix a race condition where we might get updates thrown at us right after a
framebuffer switch, but before we've been given the pointer to the new
framebuffer.


git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4839 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
index 697695d..b07f5c3 100644
--- a/common/rfb/VNCServerST.cxx
+++ b/common/rfb/VNCServerST.cxx
@@ -47,6 +47,7 @@
 // otherwise blacklisted connections might be "forgotten".
 
 
+#include <assert.h>
 #include <stdlib.h>
 
 #include <rfb/ServerCore.h>
@@ -77,7 +78,8 @@
 // -=- Constructors/Destructor
 
 VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
-  : blHosts(&blacklist), desktop(desktop_), desktopStarted(false), pb(0),
+  : blHosts(&blacklist), desktop(desktop_), desktopStarted(false),
+    blockCounter(0), pb(0),
     name(strDup(name_)), pointerClient(0), comparer(0),
     renderedCursorInvalid(false),
     queryConnectionHandler(0), keyRemapper(&KeyRemapper::defInstance),
@@ -259,6 +261,22 @@
 
 // VNCServer methods
 
+void VNCServerST::blockUpdates()
+{
+  blockCounter++;
+}
+
+void VNCServerST::unblockUpdates()
+{
+  assert(blockCounter > 0);
+
+  blockCounter--;
+
+  // Flush out any updates we might have blocked
+  if (blockCounter == 0)
+    tryUpdate();
+}
+
 void VNCServerST::setPixelBuffer(PixelBuffer* pb_, const ScreenSet& layout)
 {
   pb = pb_;
@@ -545,6 +563,9 @@
 {
   std::list<VNCSConnectionST*>::iterator ci, ci_next;
 
+  if (blockCounter > 0)
+    return;
+
   if (!checkDefer())
     return;
 
@@ -571,6 +592,10 @@
   if (ui.is_empty() && !(renderCursor && renderedCursorInvalid))
     return true;
 
+  // Block clients as the frame buffer cannot be safely accessed
+  if (blockCounter > 0)
+    return false;
+
   // Block client from updating if we are currently deferring updates
   if (!checkDefer())
     return false;