diff options
author | Luboš Luňák <l.lunak@suse.cz> | 2011-04-05 18:25:22 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@suse.cz> | 2011-04-06 15:54:19 +0200 |
commit | 4640b3864d9c761a3482cc802fa6a09925f8a138 (patch) | |
tree | 044dfe5eab5d2f2b173f9a3956e38e7c86f58e17 /vcl | |
parent | c87019c1a938d7bb4ba1575f79df20f94a619ca9 (diff) |
rework confused and racy clipboard event polling (bnc#683941)
It does not work reliably to just poll on the X connection fd,
as there may be already incoming events in the Xlib queue (removed
from the fd connection). So XPending() call is necessary; which
additionally ensures the output queue is flushed before polling.
The second poll() seems to have been just introduced as a result
of failing to understand this, and the strange XPending() nesting
later is no longer needed either.
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/unx/source/dtrans/X11_selection.cxx | 54 |
1 files changed, 21 insertions, 33 deletions
diff --git a/vcl/unx/source/dtrans/X11_selection.cxx b/vcl/unx/source/dtrans/X11_selection.cxx index 23584694cad2..cd6f21327770 100644 --- a/vcl/unx/source/dtrans/X11_selection.cxx +++ b/vcl/unx/source/dtrans/X11_selection.cxx @@ -3729,41 +3729,29 @@ bool SelectionManager::handleXEvent( XEvent& rEvent ) void SelectionManager::dispatchEvent( int millisec ) { - pollfd aPollFD; - XEvent event; - - // query socket handle to poll on - aPollFD.fd = ConnectionNumber( m_pDisplay ); - aPollFD.events = POLLIN; - aPollFD.revents = 0; + // acquire the mutex to prevent other threads + // from using the same X connection + osl::ResettableMutexGuard aGuard(m_aMutex); - // wait for activity (outside the xlib) - if( poll( &aPollFD, 1, millisec ) > 0 ) + if( !XPending( m_pDisplay )) + { // wait for any events if none are already queued + pollfd aPollFD; + aPollFD.fd = XConnectionNumber( m_pDisplay ); + aPollFD.events = POLLIN; + aPollFD.revents = 0; + // release mutex for the time of waiting for possible data + aGuard.clear(); + if( poll( &aPollFD, 1, millisec ) <= 0 ) + return; + aGuard.reset(); + } + while( XPending( m_pDisplay )) { - // now acquire the mutex to prevent other threads - // from using the same X connection - osl::ResettableMutexGuard aGuard(m_aMutex); - - // prevent that another thread already ate the input - // this can happen if e.g. another thread does - // an X request getting a response. the response - // would be removed from the queue and we would end up - // with an empty socket here - if( poll( &aPollFD, 1, 0 ) > 0 ) - { - int nPending = 1; - while( nPending ) - { - nPending = XPending( m_pDisplay ); - if( nPending ) - { - XNextEvent( m_pDisplay, &event ); - aGuard.clear(); - handleXEvent( event ); - aGuard.reset(); - } - } - } + XEvent event; + XNextEvent( m_pDisplay, &event ); + aGuard.clear(); + handleXEvent( event ); + aGuard.reset(); } } |