File fix-bug-4735-don-t-leave-until-fillclipboard-s-all.patch of Package synergy

From 32ad85706878a92f5964847b1d88752fb5685303 Mon Sep 17 00:00:00 2001
From: Nye Liu <nyet@nyet.org>
Date: Tue, 1 Sep 2015 17:39:25 -0700
Subject: [PATCH] Fix bug #4735 - don't leave() until fillClipboard()s all
 complete

---
 src/lib/client/Client.cpp | 66 ++++++++++++++++++++++++++++++++++-------------
 src/lib/client/Client.h   |  9 +++++--
 2 files changed, 55 insertions(+), 20 deletions(-)

Index: synergy-1.7.4-stable/src/lib/client/Client.cpp
===================================================================
--- synergy-1.7.4-stable.orig/src/lib/client/Client.cpp
+++ synergy-1.7.4-stable/src/lib/client/Client.cpp
@@ -21,7 +21,6 @@
 #include "../plugin/ns/SecureSocket.h"
 #include "client/ServerProxy.h"
 #include "synergy/Screen.h"
-#include "synergy/Clipboard.h"
 #include "synergy/FileChunk.h"
 #include "synergy/DropHelper.h"
 #include "synergy/PacketStreamFilter.h"
@@ -75,7 +74,10 @@ Client::Client(
 	m_socket(NULL),
 	m_useSecureNetwork(false),
 	m_args(args),
-	m_sendClipboardThread(NULL)
+	m_sendClipboardThread(NULL),
+	m_mutex(NULL),
+	m_condData(false),
+	m_condVar(NULL)
 {
 	assert(m_socketFactory != NULL);
 	assert(m_screen        != NULL);
@@ -107,6 +109,8 @@ Client::Client(
 			LOG((CLOG_NOTE "crypto disabled because of ns plugin not available"));
 		}
 	}
+	m_mutex = new Mutex();
+	m_condVar = new CondVar<bool>(m_mutex, m_condData);
 }
 
 Client::~Client()
@@ -125,6 +129,8 @@ Client::~Client()
 	cleanupConnecting();
 	cleanupConnection();
 	delete m_socketFactory;
+	delete m_condVar;
+	delete m_mutex;
 }
 
 void
@@ -262,8 +268,6 @@ Client::enter(SInt32 xAbs, SInt32 yAbs,
 bool
 Client::leave()
 {
-	m_screen->leave();
-
 	m_active = false;
 
 	if (m_sendClipboardThread != NULL) {
@@ -272,11 +276,17 @@ Client::leave()
 		m_sendClipboardThread = NULL;
 	}
 
+	m_condData = false;
 	m_sendClipboardThread = new Thread(
 								new TMethodJob<Client>(
 									this,
 									&Client::sendClipboardThread,
 									NULL));
+	// Bug #4735 - we can't leave() until fillClipboard()s all finish
+	while (!m_condData)
+	    m_condVar->wait();
+
+	m_screen->leave();
 
 	if (!m_receivedFileData.empty()) {
 		m_receivedFileData.clear();
@@ -382,9 +392,20 @@ Client::getName() const
 }
 
 void
-Client::sendClipboard(ClipboardID id)
+Client::fillClipboard(ClipboardID id, Clipboard *clipboard)
+{
+	assert(m_screen != NULL);
+	assert(m_server != NULL);
+
+	if (clipboard->open(m_timeClipboard[id])) {
+		clipboard->close();
+	}
+	m_screen->getClipboard(id, clipboard);
+}
+
+void
+Client::sendClipboard(ClipboardID id, Clipboard *clipboard)
 {
-	// note -- m_mutex must be locked on entry
 	assert(m_screen != NULL);
 	assert(m_server != NULL);
 
@@ -392,26 +413,21 @@ Client::sendClipboard(ClipboardID id)
 	// clipboard time before getting the data from the screen
 	// as the screen may detect an unchanged clipboard and
 	// avoid copying the data.
-	Clipboard clipboard;
-	if (clipboard.open(m_timeClipboard[id])) {
-		clipboard.close();
-	}
-	m_screen->getClipboard(id, &clipboard);
 
 	// check time
 	if (m_timeClipboard[id] == 0 ||
-		clipboard.getTime() != m_timeClipboard[id]) {
+		clipboard->getTime() != m_timeClipboard[id]) {
 		// save new time
-		m_timeClipboard[id] = clipboard.getTime();
+		m_timeClipboard[id] = clipboard->getTime();
 
 		// marshall the data
-		String data = clipboard.marshall();
+		String data = clipboard->marshall();
 
 		// save and send data if different or not yet sent
 		if (!m_sentClipboard[id] || data != m_dataClipboard[id]) {
 			m_sentClipboard[id] = true;
 			m_dataClipboard[id] = data;
-			m_server->onClipboardChanged(id, &clipboard);
+			m_server->onClipboardChanged(id, clipboard);
 		}
 	}
 }
@@ -673,8 +689,10 @@ Client::handleClipboardGrabbed(const Eve
 
 	// if we're not the active screen then send the clipboard now,
 	// otherwise we'll wait until we leave.
+	Clipboard clipboard;
 	if (!m_active) {
-		sendClipboard(info->m_id);
+		fillClipboard(info->m_id, &clipboard);
+		sendClipboard(info->m_id, &clipboard);
 	}
 }
 
@@ -762,12 +780,24 @@ Client::onFileRecieveCompleted()
 }
 
 void
-Client::sendClipboardThread(void*)
+Client::sendClipboardThread(void * data)
 {
+	Clipboard clipboard[kClipboardEnd];
+	// fill clipboards that we own and that have changed
+	for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
+		if (m_ownClipboard[id]) {
+			fillClipboard(id, &clipboard[id]);
+		}
+	}
+
+	// signal that fill is done
+	m_condData = true;
+	m_condVar->signal();
+
 	// send clipboards that we own and that have changed
 	for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
 		if (m_ownClipboard[id]) {
-			sendClipboard(id);
+			sendClipboard(id, &clipboard[id]);
 		}
 	}
 
Index: synergy-1.7.4-stable/src/lib/client/Client.h
===================================================================
--- synergy-1.7.4-stable.orig/src/lib/client/Client.h
+++ synergy-1.7.4-stable/src/lib/client/Client.h
@@ -20,12 +20,13 @@
 
 #include "synergy/IClient.h"
 
-#include "synergy/IClipboard.h"
+#include "synergy/Clipboard.h"
 #include "synergy/DragInformation.h"
 #include "synergy/INode.h"
 #include "synergy/ClientArgs.h"
 #include "net/NetworkAddress.h"
 #include "base/EventTypes.h"
+#include "mt/CondVar.h"
 
 class EventQueueTimer;
 namespace synergy { class Screen; }
@@ -162,7 +163,8 @@ public:
 	virtual String		getName() const;
 
 private:
-	void				sendClipboard(ClipboardID);
+	void				fillClipboard(ClipboardID, Clipboard*);
+	void				sendClipboard(ClipboardID, Clipboard*);
 	void				sendEvent(Event::Type, void*);
 	void				sendConnectionFailedEvent(const char* msg);
 	void				sendFileChunk(const void* data);
@@ -223,4 +225,7 @@ private:
 	bool				m_useSecureNetwork;
 	ClientArgs&			m_args;
 	Thread*				m_sendClipboardThread;
+	Mutex*				m_mutex;
+	bool				m_condData;
+	CondVar<bool>*			m_condVar;
 };
openSUSE Build Service is sponsored by