From ba7f6c541fc406179427ffc912551722d8c5e8ff Mon Sep 17 00:00:00 2001 From: Francois Gouget <fgouget@codeweavers.com> Date: Mon, 8 Oct 2001 20:28:36 +0000 Subject: [PATCH] Fix infinite loop problem in wineclipsrv startup. LaunchServer: Don't give up on the first message. Added GetSelectionEvent: Limit CPU use and introduce timeout. --- windows/x11drv/clipboard.c | 16 ++++++++++++- windows/x11drv/wineclipsrv.c | 46 ++++++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/windows/x11drv/clipboard.c b/windows/x11drv/clipboard.c index 43d4de8f791..cdc7670461a 100644 --- a/windows/x11drv/clipboard.c +++ b/windows/x11drv/clipboard.c @@ -295,10 +295,24 @@ BOOL X11DRV_CLIPBOARD_LaunchServer() else { /* Wait until we lose the selection, timing out after a minute */ + DWORD start_time, timeout, elapsed, ret; TRACE("Waiting for clipboard server to acquire selection\n"); - if ( MsgWaitForMultipleObjects( 1, &selectionClearEvent, FALSE, 60000, QS_ALLINPUT ) != WAIT_OBJECT_0 ) + timeout = 60000; + start_time = GetTickCount(); + elapsed=0; + do + { + ret = MsgWaitForMultipleObjects( 1, &selectionClearEvent, FALSE, timeout - elapsed, QS_ALLINPUT ); + if (ret != WAIT_OBJECT_0+1) + break; + elapsed = GetTickCount() - start_time; + if (elapsed > timeout) + break; + } + while (1); + if ( ret != WAIT_OBJECT_0 ) TRACE("Server could not acquire selection, or a timeout occurred!\n"); else TRACE("Server successfully acquired selection\n"); diff --git a/windows/x11drv/wineclipsrv.c b/windows/x11drv/wineclipsrv.c index 5e0b938bef8..662c85da771 100644 --- a/windows/x11drv/wineclipsrv.c +++ b/windows/x11drv/wineclipsrv.c @@ -415,6 +415,36 @@ int AcquireSelection() return g_selectionAcquired; } +BOOL GetSelectionEvent(Atom SelectionSrc, XEvent *xe) +{ + time_t end_time; + + /* Set up a 10 second time out */ + end_time=time(NULL)+10; + + do + { + struct timeval nap; + + if (XCheckTypedWindowEvent(g_display, g_win, SelectionNotify, xe)) + { + if( xe->xselection.selection == SelectionSrc ) + return TRUE; + } + + if (time(NULL)>end_time) + break; + + /* Sleep a bit to make this busy wait less brutal */ + nap.tv_sec = 0; + nap.tv_usec = 10; + select(0, NULL, NULL, NULL, &nap); + } + while (TRUE); + + return FALSE; +} + /************************************************************************** * CacheDataFormats * @@ -457,12 +487,8 @@ int CacheDataFormats( Atom SelectionSrc, PCACHEENTRY *ppCache ) /* * Wait until SelectionNotify is received */ - while( TRUE ) - { - if( XCheckTypedWindowEvent(g_display, g_win, SelectionNotify, &xe) ) - if( xe.xselection.selection == SelectionSrc ) - break; - } + if (!GetSelectionEvent(SelectionSrc, &xe)) + return 0; /* Verify that the selection returned a valid TARGETS property */ if ( (xe.xselection.target != aTargets) @@ -541,12 +567,8 @@ BOOL FillCacheEntry( Atom SelectionSrc, Atom target, PCACHEENTRY pCacheEntry ) g_win, CurrentTime); /* wait until SelectionNotify is received */ - while( TRUE ) - { - if( XCheckTypedWindowEvent(g_display, g_win, SelectionNotify, &xe) ) - if( xe.xselection.selection == SelectionSrc ) - break; - } + if (!GetSelectionEvent(SelectionSrc,&xe)) + return bRet; /* Now proceed to retrieve the actual converted property from * the SELECTION_DATA atom */ -- GitLab