From 2c7649422ecd811217bc85b4c493794b217014b7 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 14 Nov 2011 15:54:30 +0000 Subject: [PATCH] Implement proper support for fences in the server. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4799 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- common/rfb/VNCSConnectionST.cxx | 57 ++++++++++++++++++++++++++++++++- common/rfb/VNCSConnectionST.h | 7 ++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx index 30d9b6ad..12dcf047 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -35,7 +36,9 @@ static LogWriter vlog("VNCSConnST"); VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s, bool reverse) - : SConnection(reverse), sock(s), inProcessMessages(false), server(server_), + : SConnection(reverse), sock(s), inProcessMessages(false), + syncFence(false), fenceFlags(0), fenceDataLen(0), fenceData(NULL), + server(server_), updates(false), image_getter(server->useEconomicTranslate), drawRenderedCursor(false), removeRenderedCursor(false), updateTimer(this), pointerEventTime(0), @@ -70,6 +73,7 @@ VNCSConnectionST::~VNCSConnectionST() // Remove this client from the server server->clients.remove(this); + delete [] fenceData; } @@ -121,6 +125,10 @@ void VNCSConnectionST::processMessages() while (getInStream()->checkNoWait(1)) { processMsg(); + if (syncFence) { + writer()->writeFence(fenceFlags, fenceDataLen, fenceData); + syncFence = false; + } } // Flush out everything in case we go idle after this. @@ -566,6 +574,42 @@ void VNCSConnectionST::setInitialColourMap() setColourMapEntries(0, 0); } +void VNCSConnectionST::fence(rdr::U32 flags, unsigned len, const char data[]) +{ + if (flags & fenceFlagRequest) { + if (flags & fenceFlagSyncNext) { + if (syncFence) + vlog.error("Fence trying to synchronise another fence"); + + syncFence = true; + + fenceFlags = flags & (fenceFlagBlockBefore | fenceFlagBlockAfter | fenceFlagSyncNext); + fenceDataLen = len; + delete [] fenceData; + if (len > 0) { + fenceData = new char[len]; + memcpy(fenceData, data, len); + } + + return; + } + + // We handle everything synchronously so we trivially honor these modes + flags = flags & (fenceFlagBlockBefore | fenceFlagBlockAfter); + + writer()->writeFence(flags, len, data); + return; + } + + switch (len) { + case 0: + // Initial dummy fence; + break; + default: + vlog.error("Fence response of unexpected size received"); + } +} + // supportsLocalCursor() is called whenever the status of // cp.supportsLocalCursor has changed. If the client does now support local // cursor, we make sure that the old server-side rendered cursor is cleaned up @@ -581,6 +625,11 @@ void VNCSConnectionST::supportsLocalCursor() } } +void VNCSConnectionST::supportsFence() +{ + writer()->writeFence(fenceFlagRequest, 0, NULL); +} + void VNCSConnectionST::writeSetCursorCallback() { if (cp.supportsLocalXCursor) { @@ -642,6 +691,12 @@ void VNCSConnectionST::writeFramebufferUpdate() { updateTimer.stop(); + // We're in the middle of processing a command that's supposed to be + // synchronised. Allowing an update to slip out right now might violate + // that synchronisation. + if (syncFence) + return; + // We try to aggregate responses, so don't send out anything whilst we // still have incoming messages. processMessages() will give us another // chance to run once things are idle. diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h index 5a007ee9..e06522b9 100644 --- a/common/rfb/VNCSConnectionST.h +++ b/common/rfb/VNCSConnectionST.h @@ -133,7 +133,9 @@ namespace rfb { virtual void setDesktopSize(int fb_width, int fb_height, const ScreenSet& layout); virtual void setInitialColourMap(); + virtual void fence(rdr::U32 flags, unsigned len, const char data[]); virtual void supportsLocalCursor(); + virtual void supportsFence(); // setAccessRights() allows a security package to limit the access rights // of a VNCSConnectioST to the server. These access rights are applied @@ -168,6 +170,11 @@ namespace rfb { bool inProcessMessages; + bool syncFence; + rdr::U32 fenceFlags; + unsigned fenceDataLen; + char *fenceData; + VNCServerST* server; SimpleUpdateTracker updates; TransImageGetter image_getter; -- 2.39.5