Sophie

Sophie

distrib > Mandriva > 2009.0 > i586 > by-pkgid > deddb11168afe3bc1bcc7617083bb2e6 > files > 3

synergy-1.3.1-4mdv2009.0.src.rpm

=== modified file 'lib/platform/CXWindowsEventQueueBuffer.cpp'
--- lib/platform/CXWindowsEventQueueBuffer.cpp	2008-06-07 20:32:37 +0000
+++ lib/platform/CXWindowsEventQueueBuffer.cpp	2008-06-25 02:11:38 +0000
@@ -17,6 +17,10 @@
 #include "CThread.h"
 #include "CEvent.h"
 #include "IEventQueue.h"
+#include <fcntl.h>
+#if HAVE_UNISTD_H
+#	include <unistd.h>
+#endif
 #if HAVE_POLL
 #	include <poll.h>
 #else
@@ -29,9 +33,6 @@
 #	if HAVE_SYS_TYPES_H
 #		include <sys/types.h>
 #	endif
-#	if HAVE_UNISTD_H
-#		include <unistd.h>
-#	endif
 #endif
 
 //
@@ -55,11 +56,22 @@
 	assert(m_window  != None);
 
 	m_userEvent = XInternAtom(m_display, "SYNERGY_USER_EVENT", False);
+	// set up for pipe hack
+	int result = pipe(m_pipefd);
+	assert(result == 0);
+
+	int pipeflags;
+	pipeflags = fcntl(m_pipefd[0], F_GETFL);
+	fcntl(m_pipefd[0], F_SETFL, pipeflags | O_NONBLOCK);
+	pipeflags = fcntl(m_pipefd[1], F_GETFL);
+	fcntl(m_pipefd[1], F_SETFL, pipeflags | O_NONBLOCK);
 }
 
 CXWindowsEventQueueBuffer::~CXWindowsEventQueueBuffer()
 {
-	// do nothing
+	// release pipe hack resources
+	close(m_pipefd[0]);
+	close(m_pipefd[1]);
 }
 
 void
@@ -67,6 +79,11 @@
 {
 	CThread::testCancel();
 
+	// clear out the pipe in preparation for waiting.
+
+	char buf[16];
+	read(m_pipefd[0], buf, 15);
+
 	{
 		CLock lock(&m_mutex);
 		// we're now waiting for events
@@ -75,13 +92,20 @@
 		// push out pending events
 		flush();
 	}
+	// calling flush may have queued up a new event.
+	if (!CXWindowsEventQueueBuffer::isEmpty()) {
+		CThread::testCancel();
+		return;
+	}
 
 	// use poll() to wait for a message from the X server or for timeout.
 	// this is a good deal more efficient than polling and sleeping.
 #if HAVE_POLL
-	struct pollfd pfds[1];
+	struct pollfd pfds[2];
 	pfds[0].fd     = ConnectionNumber(m_display);
 	pfds[0].events = POLLIN;
+	pfds[1].fd     = m_pipefd[0];
+	pfds[1].events = POLLIN;
 	int timeout    = (dtimeout < 0.0) ? -1 :
 						static_cast<int>(1000.0 * dtimeout);
 #else
@@ -101,19 +125,33 @@
 	fd_set rfds;
 	FD_ZERO(&rfds);
 	FD_SET(ConnectionNumber(m_display), &rfds);
+	FD_SET(m_pipefd[0], &rfds);
+	int nfds;
+	if (ConnectionNumber(m_display) > m_pipefd[0]) {
+		nfds = ConnectionNumber(m_display) + 1;
+	}
+	else {
+		nfds = m_pipefd[0] + 1;
+	}
 #endif
 
 	// wait for message from X server or for timeout.  also check
 	// if the thread has been cancelled.  poll() should return -1
 	// with EINTR when the thread is cancelled.
 #if HAVE_POLL
-	poll(pfds, 1, timeout);
+	poll(pfds, 2, timeout);
+	if (pfds[1].revents & POLLIN) {
+		read(m_pipefd[0], buf, 15);
+	}
 #else
-	select(ConnectionNumber(m_display) + 1,
+	select(nfds,
 						SELECT_TYPE_ARG234 &rfds,
 						SELECT_TYPE_ARG234 NULL,
 						SELECT_TYPE_ARG234 NULL,
 						SELECT_TYPE_ARG5   timeoutPtr);
+	if (FD_SET(m_pipefd[0], &rfds) {
+		read(m_pipefd[0], buf, 15);
+	}
 #endif
 
 	{
@@ -170,6 +208,11 @@
 	// too.
 	if (m_waiting) {
 		flush();
+		// Send a character through the round-trip pipe to wake a thread
+		// that is waiting for a ConnectionNumber() socket to be readable.
+		// The flush call can read incoming data from the socket and put
+		// it in Xlib's input buffer.  That sneaks it past the other thread.
+		write(m_pipefd[1], "!", 1);
 	}
 
 	return true;

=== modified file 'lib/platform/CXWindowsEventQueueBuffer.h'
--- lib/platform/CXWindowsEventQueueBuffer.h	2008-06-07 20:32:37 +0000
+++ lib/platform/CXWindowsEventQueueBuffer.h	2008-06-21 20:48:14 +0000
@@ -52,6 +52,7 @@
 	XEvent				m_event;
 	CEventList			m_postedEvents;
 	bool				m_waiting;
+	int				m_pipefd[2];
 };
 
 #endif