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