Revision: 4839 http://tigervnc.svn.sourceforge.net/tigervnc/?rev=4839&view=rev Author: ossman_ Date: 2012-01-23 15:54:11 +0000 (Mon, 23 Jan 2012) Log Message: ----------- 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.
Modified Paths: -------------- trunk/common/rfb/VNCServer.h trunk/common/rfb/VNCServerST.cxx trunk/common/rfb/VNCServerST.h trunk/unix/xserver/hw/vnc/XserverDesktop.cc trunk/unix/xserver/hw/vnc/XserverDesktop.h trunk/unix/xserver/hw/vnc/vncHooks.cc Modified: trunk/common/rfb/VNCServer.h =================================================================== --- trunk/common/rfb/VNCServer.h 2012-01-23 15:43:42 UTC (rev 4838) +++ trunk/common/rfb/VNCServer.h 2012-01-23 15:54:11 UTC (rev 4839) @@ -30,6 +30,13 @@ class VNCServer : public UpdateTracker { public: + // blockUpdates()/unblockUpdates() tells the server that the pixel buffer + // is currently in flux and may not be accessed. The attributes of the + // pixel buffer may still be accessed, but not the frame buffer itself. + // Note that access must be unblocked the exact same number of times it + // was blocked. + virtual void blockUpdates() = 0; + virtual void unblockUpdates() = 0; // setPixelBuffer() tells the server to use the given pixel buffer (and // optionally a modified screen layout). If this differs in size from Modified: trunk/common/rfb/VNCServerST.cxx =================================================================== --- trunk/common/rfb/VNCServerST.cxx 2012-01-23 15:43:42 UTC (rev 4838) +++ trunk/common/rfb/VNCServerST.cxx 2012-01-23 15:54:11 UTC (rev 4839) @@ -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; Modified: trunk/common/rfb/VNCServerST.h =================================================================== --- trunk/common/rfb/VNCServerST.h 2012-01-23 15:43:42 UTC (rev 4838) +++ trunk/common/rfb/VNCServerST.h 2012-01-23 15:54:11 UTC (rev 4839) @@ -82,6 +82,8 @@ // Methods overridden from VNCServer + virtual void blockUpdates(); + virtual void unblockUpdates(); virtual void setPixelBuffer(PixelBuffer* pb, const ScreenSet& layout); virtual void setPixelBuffer(PixelBuffer* pb); virtual void setScreenLayout(const ScreenSet& layout); @@ -209,6 +211,7 @@ SDesktop* desktop; bool desktopStarted; + int blockCounter; PixelBuffer* pb; ScreenSet screenLayout; Modified: trunk/unix/xserver/hw/vnc/XserverDesktop.cc =================================================================== --- trunk/unix/xserver/hw/vnc/XserverDesktop.cc 2012-01-23 15:43:42 UTC (rev 4838) +++ trunk/unix/xserver/hw/vnc/XserverDesktop.cc 2012-01-23 15:54:11 UTC (rev 4839) @@ -188,6 +188,16 @@ cmap = (ColormapPtr) retval; } +void XserverDesktop::blockUpdates() +{ + server->blockUpdates(); +} + +void XserverDesktop::unblockUpdates() +{ + server->unblockUpdates(); +} + void XserverDesktop::setFramebuffer(int w, int h, void* fbptr, int stride) { width_ = w; Modified: trunk/unix/xserver/hw/vnc/XserverDesktop.h =================================================================== --- trunk/unix/xserver/hw/vnc/XserverDesktop.h 2012-01-23 15:43:42 UTC (rev 4838) +++ trunk/unix/xserver/hw/vnc/XserverDesktop.h 2012-01-23 15:54:11 UTC (rev 4839) @@ -61,6 +61,8 @@ // methods called from X server code void serverReset(ScreenPtr pScreen); + void blockUpdates(); + void unblockUpdates(); void setFramebuffer(int w, int h, void* fbptr, int stride); void setColormap(ColormapPtr cmap); void setColourMapEntries(ColormapPtr pColormap, int ndef, xColorItem* pdef); Modified: trunk/unix/xserver/hw/vnc/vncHooks.cc =================================================================== --- trunk/unix/xserver/hw/vnc/vncHooks.cc 2012-01-23 15:43:42 UTC (rev 4838) +++ trunk/unix/xserver/hw/vnc/vncHooks.cc 2012-01-23 15:54:11 UTC (rev 4839) @@ -605,6 +605,11 @@ RegionRec reg; BoxRec box; + // We need to prevent the RFB core from accessing the framebuffer + // for a while as there might be updates thrown our way inside + // rrSetConfig (i.e. before we have a pointer to the new framebuffer). + vncHooksScreen->desktop->blockUpdates(); + rp->rrSetConfig = vncHooksScreen->RandRSetConfig; ret = (*rp->rrSetConfig)(pScreen, rotation, rate, pSize); rp->rrSetConfig = vncHooksRandRSetConfig; @@ -617,6 +622,8 @@ vncFbptr[pScreen->myNum], vncFbstride[pScreen->myNum]); + vncHooksScreen->desktop->unblockUpdates(); + // Mark entire screen as changed box.x1 = 0; box.y1 = 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Try before you buy = See our experts in action! The most comprehensive online learning library for Microsoft developers is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3, Metro Style Apps, more. Free future releases when you subscribe now! http://p.sf.net/sfu/learndevnow-dev2 _______________________________________________ Tigervnc-commits mailing list Tigervnc-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tigervnc-commits