Infinite loops in winclipsrv startup
François Gouget
fgouget at codeweavers.com
Sun Oct 7 20:21:33 CDT 2001
When starting wineclipsrv, the app waits until wineclipsrv has
acquired the selection. This is done by calling
MsgWaitForMultipleObjects. But if at that time a message is received (a
WM_PAINT anyone?) then we give up. wineclipsrv continues happily and
then waits for a SelectionNotify in a loop. But since the Wine process
gave up, wineclipsrv never gets what it wants and stays in a nice tight
loop wasting CPU away.
With this patch the Wine process will wait for wineclipsrv to start,
with a nice timeout. And wineclipsrv will do the same and try to sleep a
little so that it does not waste so much CPU (it should never stay in
that loop long anyway).
Changelog:
François Gouget <fgouget at codeweavers.com>
* windows/x11drv/clipboard.c,
windows/x11drv/wineclipsrv.c
Fix infinite loop problem in wineclipsrv startup
LaunchServer: Don't give up on the first message
Added GetSelectionEvent: Limit CPU use and introduce timeout
--
François Gouget
fgouget at codeweavers.com
-------------- next part --------------
Index: windows/x11drv/clipboard.c
===================================================================
RCS file: /home/wine/wine/windows/x11drv/clipboard.c,v
retrieving revision 1.38
diff -u -r1.38 clipboard.c
--- windows/x11drv/clipboard.c 2001/09/19 20:34:18 1.38
+++ windows/x11drv/clipboard.c 2001/10/07 23:19:58
@@ -295,10 +295,24 @@
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");
Index: windows/x11drv/wineclipsrv.c
===================================================================
RCS file: /home/wine/wine/windows/x11drv/wineclipsrv.c,v
retrieving revision 1.5
diff -u -r1.5 wineclipsrv.c
--- windows/x11drv/wineclipsrv.c 2001/05/09 17:31:36 1.5
+++ windows/x11drv/wineclipsrv.c 2001/10/07 23:19:59
@@ -415,6 +415,36 @@
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 @@
/*
* 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 @@
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 */
More information about the wine-patches
mailing list