summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@suse.cz>2011-04-05 18:25:22 +0200
committerLuboš Luňák <l.lunak@suse.cz>2011-04-06 15:54:19 +0200
commit4640b3864d9c761a3482cc802fa6a09925f8a138 (patch)
tree044dfe5eab5d2f2b173f9a3956e38e7c86f58e17 /vcl
parentc87019c1a938d7bb4ba1575f79df20f94a619ca9 (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.cxx54
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();
}
}