Menu - loop of sending and receiving WM_TIMER

Jose Alonso alonso at estadao.com.br
Wed Apr 13 15:18:47 CDT 2005


If a Menu is accessed and the application used the function
SetTimer, then the application and the wineserver use 100% of
the CPU (loop of sending and receiving WM_TIMER).

function used: SetTimer(NULL, 0, 100, TimerProc)

Description of the loop:
dlls/user/menu.c
MENU_TrackMenu

    while (!fEndMenu)
    {
        ...
        for (;;)
        {
(1)         if (PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE ))
        ...
        {
(2)          DispatchMessageW( &msg );
        }
        if (!fEndMenu) fRemove = TRUE;

        /* finally remove message from the queue */

        if (fRemove && !(mt.trackFlags & TF_SKIPREMOVE) )
(3)       PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
        else mt.trackFlags &= ~TF_SKIPREMOVE;
    }

(1) The WM_TIMER is peeked and the timer is not restarted (PM_NOREMOVE)
(2) The WM_TIMER is dispatched here
(3) The WM_TIMER is only removed from the queue.
The next PeekMessageW (1) return immediately with WM_TIMER since the
timer was not restarted.

I propose to unconditionally restart the timer when the timer
message is generated. Are there any collateral effect?

--- server/queue.c.orig 2005-03-24 16:16:54.000000000 -0300
+++ server/queue.c      2005-04-13 16:10:42.000000000 -0300
@@ -972,7 +972,7 @@
         if (win && timer->win != win) continue;
         if (timer->msg >= get_first && timer->msg <= get_last)
         {
-            if (remove) restart_timer( queue, timer );
+            restart_timer( queue, timer );
             return timer;
         }
     }

-- 
     alonso




More information about the wine-devel mailing list