summaryrefslogtreecommitdiffstats
path: root/common/rfb/VNCServerST.cxx
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2012-01-23 15:54:11 +0000
committerPierre Ossman <ossman@cendio.se>2012-01-23 15:54:11 +0000
commit559a2e8f471edb9142eea892acc101d6fc58f0d6 (patch)
tree21efcef13a2cb0524019ab4cc0400dc1d9e2f079 /common/rfb/VNCServerST.cxx
parent2f4fd6b9203f0ade624ff8500c3a8a8c8711db61 (diff)
downloadtigervnc-559a2e8f471edb9142eea892acc101d6fc58f0d6.tar.gz
tigervnc-559a2e8f471edb9142eea892acc101d6fc58f0d6.zip
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
Diffstat (limited to 'common/rfb/VNCServerST.cxx')
-rw-r--r--common/rfb/VNCServerST.cxx27
1 files changed, 26 insertions, 1 deletions
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
index 697695d4..b07f5c35 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 @@ rfb::BoolParameter alwaysSetDeferUpdateTimer("AlwaysSetDeferUpdateTimer",
// -=- 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 @@ int VNCServerST::checkTimeouts()
// 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 @@ void VNCServerST::tryUpdate()
{
std::list<VNCSConnectionST*>::iterator ci, ci_next;
+ if (blockCounter > 0)
+ return;
+
if (!checkDefer())
return;
@@ -571,6 +592,10 @@ bool VNCServerST::checkUpdate()
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;