diff options
author | Pierre Ossman <ossman@cendio.se> | 2012-01-23 15:54:11 +0000 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2012-01-23 15:54:11 +0000 |
commit | 559a2e8f471edb9142eea892acc101d6fc58f0d6 (patch) | |
tree | 21efcef13a2cb0524019ab4cc0400dc1d9e2f079 /common/rfb/VNCServerST.cxx | |
parent | 2f4fd6b9203f0ade624ff8500c3a8a8c8711db61 (diff) | |
download | tigervnc-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.cxx | 27 |
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; |