Date: Thu, 2 Oct 2008 02:44:12 GMT From: Benjamin Close <benjsc@FreeBSD.org> To: freebsd-gnats-submit@FreeBSD.org Subject: ports/127791: Fix intermittent delays caused in synergy Message-ID: <200810020244.m922iCVP032299@www.freebsd.org> Resent-Message-ID: <200810020250.m922o14m036089@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 127791 >Category: ports >Synopsis: Fix intermittent delays caused in synergy >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Oct 02 02:50:00 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Benjamin Close >Release: 8-Current >Organization: >Environment: FreeBSD wolf.clearchain.com 8.0-CURRENT FreeBSD 8.0-CURRENT #0 r183368: Mon Sep 29 08:37:02 CST 2008 root@wolf.clearchain.com:/usr/obj/devel/FreeBSD/svn/head/sys/GENERIC amd64 >Description: There is a bug in synergy that causes delays under the current X windows version when using synergyc. Below is a description of the report submitted to sourceforge. However since the synergy project hasn't been updated in close to 2 years I figured a local fix was also in order. --- Bug description: There is poor assumption in the synergy XWindowsEventQueue class. The assumption is that all events will cause a change on the Xwindows file descriptor. This is not true. Some events are queued in the Xlib buffers. This is extremely noticable with the new xcb version of Xorg. It causes synergy to hang or delay for a period of time (timeout value in waitForEvent) as there is no event on the fd to wake up the thread. This delay is VERY annoying. The fix is to check for events not only from the server itself but also in the xlib event queue. We don't need to lock this test as it's a non blocking io call. We change the XPending call in isEmpty to QueueLength to avoid the XFlush call that XPending may cause. This fix eliminates the delay at the cost of a little more cpu time - still < 1% on my box. >How-To-Repeat: Use synergyc on FBSD to connect to a synergy server. >Fix: The attached patch is a bump to port revision and also contains the required patch to fix the problem. Should just be able to apply. Please note I don't have a ports commit bit so can't commit this. Patch attached with submission follows: diff -urN synergy/Makefile synergy2/Makefile --- synergy/Makefile 2008-04-24 12:38:43.260017882 +0930 +++ synergy2/Makefile 2008-10-02 12:05:33.732674843 +0930 @@ -7,7 +7,7 @@ PORTNAME= synergy PORTVERSION= 1.3.1 -PORTREVISION= 3 +PORTREVISION= 4 CATEGORIES= sysutils MASTER_SITES= ${MASTER_SITE_SOURCEFORGE} MASTER_SITE_SUBDIR= ${PORTNAME}2 diff -urN synergy/files/patch-lib__platform__CXWindowsEventQueueBuffer.cpp synergy2/files/patch-lib__platform__CXWindowsEventQueueBuffer.cpp --- synergy/files/patch-lib__platform__CXWindowsEventQueueBuffer.cpp 1970-01-01 09:30:00.000000000 +0930 +++ synergy2/files/patch-lib__platform__CXWindowsEventQueueBuffer.cpp 2008-10-02 12:07:49.922114563 +0930 @@ -0,0 +1,58 @@ +--- ./lib/platform/CXWindowsEventQueueBuffer.cpp 2005-04-24 12:32:16.000000000 +0930 ++++ ./lib/platform/CXWindowsEventQueueBuffer.cpp 2008-10-02 11:14:18.112098206 +0930 +@@ -84,6 +73,8 @@ + pfds[0].events = POLLIN; + int timeout = (dtimeout < 0.0) ? -1 : + static_cast<int>(1000.0 * dtimeout); ++ int remaining = timeout; ++ int retval = 0; + #else + struct timeval timeout; + struct timeval* timeoutPtr; +@@ -102,19 +93,31 @@ + FD_ZERO(&rfds); + FD_SET(ConnectionNumber(m_display), &rfds); + #endif ++ // It's possible that the X server has queued events locally ++ // in xlib's event buffer and not pushed on to the fd. Hence we ++ // can't simply monitor the fd as we may never be woken up. ++ // ie addEvent calls flush, XFlush may not send via the fd hence ++ // there is an event waiting to be sent but we must exit the poll ++ // before it can. ++ // Instead we poll for a brief period of time (so if events ++ // queued locally in the xlib buffer can be processed) ++ // and continue doing this until timeout is reached. ++ // The human eye can notice 60hz (ansi) which is 16ms, however ++ // we want to give the cpu a chance s owe up this to 25ms ++#define TIMEOUT_DELAY 25 + +- // 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. ++ while( remaining > 0 && QLength(m_display)==0 && retval==0){ + #if HAVE_POLL +- poll(pfds, 1, timeout); ++ retval = poll(pfds, 1, TIMEOUT_DELAY); //16ms = 60hz, but we make it > to play nicely with the cpu + #else +- select(ConnectionNumber(m_display) + 1, ++ retval = select(ConnectionNumber(m_display) + 1, + SELECT_TYPE_ARG234 &rfds, + SELECT_TYPE_ARG234 NULL, + SELECT_TYPE_ARG234 NULL, +- SELECT_TYPE_ARG5 timeoutPtr); ++ SELECT_TYPE_ARG5 TIMEOUT_DELAY); + #endif ++ remaining-=TIMEOUT_DELAY; ++ } + + { + // we're no longer waiting for events +@@ -179,7 +184,7 @@ + CXWindowsEventQueueBuffer::isEmpty() const + { + CLock lock(&m_mutex); +- return (XPending(m_display) == 0); ++ return (QLength(m_display) == 0 ); + } + + CEventQueueTimer* >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810020244.m922iCVP032299>