From 559a2e8f471edb9142eea892acc101d6fc58f0d6 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 23 Jan 2012 15:54:11 +0000 Subject: 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 --- common/rfb/VNCServerST.cxx | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'common/rfb/VNCServerST.cxx') 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 #include #include @@ -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::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; -- cgit v1.2.3