[ros-dev] [ros-diffs] [mjmartin] 47226: [win32k] - Change the first parameter type from HWND to PWINDOW_OBJECT for IntKillTimer as it makes more sense. Activate IntSetTimer, already done by James. - Add flag TMRF_DELETEPENDING. Destroy timers when this flag is

Ged Murphy gedmurphy at gmail.com
Mon May 17 09:41:03 CEST 2010


Congrats, good stuff Michael :)

-----Original Message-----
From: ros-diffs-bounces at reactos.org [mailto:ros-diffs-bounces at reactos.org] On Behalf Of mjmartin at svn.reactos.org
Sent: 15 May 2010 20:41
To: ros-diffs at reactos.org
Subject: [ros-diffs] [mjmartin] 47226: [win32k] - Change the first parameter type from HWND to PWINDOW_OBJECT for IntKillTimer as it makes more sense. Activate IntSetTimer, already done by James. - Add flag TMRF_DELETEPENDING. Destroy timers when this flag is set 

Author: mjmartin
Date: Sat May 15 21:40:33 2010
New Revision: 47226

URL: http://svn.reactos.org/svn/reactos?rev=47226&view=rev
Log:
[win32k]
- Change the first parameter type from HWND to PWINDOW_OBJECT for IntKillTimer as it makes more sense.
Activate IntSetTimer, already done by James.
- Add flag TMRF_DELETEPENDING. Destroy timers when this flag is set in ProcessTimers to allow any timers that have expired to have the WM_SYSTIMER/WM_TIMER messages posted to message queue before being destroyed.
- Fix error in FindTimer, it was always returning a Timer and it needed to return NULL if the specified timer did not exist.
- Fix error in PostTimerMessages, need to handle cases where the Window object is NULL which occurs when requesting messages for any window belonging to the thread. 
- In co_IntPeekMessage, simply call PostTimerMessages to have WM_SYSTIMER/WM_TIMER messages posted for expired timers. Remove call to old timer message handling.
- TODO: Code using the old timer implementation needs removed.
- Fixes bugs #2393, #3634, #2835. Commit dedicated to JT and Mr. Roboto.

Modified:
    trunk/reactos/subsystems/win32/win32k/include/timer.h
    trunk/reactos/subsystems/win32/win32k/main/dllmain.c
    trunk/reactos/subsystems/win32/win32k/ntuser/caret.c
    trunk/reactos/subsystems/win32/win32k/ntuser/message.c
    trunk/reactos/subsystems/win32/win32k/ntuser/timer.c

Modified: trunk/reactos/subsystems/win32/win32k/include/timer.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/timer.h?rev=47226&r1=47225&r2=47226&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/timer.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/timer.h [iso-8859-1] Sat May 15 21:40:33 2010
@@ -23,12 +23,14 @@
 #define TMRF_ONESHOT 0x0010
 #define TMRF_WAITING 0x0020
 #define TMRF_TIFROMWND 0x0040
+#define TMRF_DELETEPENDING 0x8000
 
 extern PKTIMER MasterTimer;
 
 NTSTATUS FASTCALL InitTimerImpl(VOID);
-BOOL FASTCALL IntKillTimer(HWND Wnd, UINT_PTR IDEvent, BOOL SystemTimer);
-UINT_PTR FASTCALL IntSetTimer(HWND Wnd, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, BOOL SystemTimer);
+BOOL FASTCALL DestroyTimersForThread(PTHREADINFO pti);
+BOOL FASTCALL IntKillTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, BOOL SystemTimer);
+UINT_PTR FASTCALL IntSetTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, INT Type);
 PTIMER FASTCALL FindSystemTimer(PMSG);
 BOOL FASTCALL ValidateTimerCallback(PTHREADINFO,PWINDOW_OBJECT,WPARAM,LPARAM);
 VOID CALLBACK SystemTimerProc(HWND,UINT,UINT_PTR,DWORD);

Modified: trunk/reactos/subsystems/win32/win32k/main/dllmain.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/main/dllmain.c?rev=47226&r1=47225&r2=47226&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/main/dllmain.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/main/dllmain.c [iso-8859-1] Sat May 15 21:40:33 2010
@@ -290,6 +290,8 @@
       Win32Thread->TIF_flags |= TIF_INCLEANUP;
       DceFreeThreadDCE(Win32Thread);
       HOOK_DestroyThreadHooks(Thread);
+      /* Cleanup timers */
+      DestroyTimersForThread(Win32Thread);
       UnregisterThreadHotKeys(Thread);
       /* what if this co_ func crash in umode? what will clean us up then? */
       co_DestroyThreadWindows(Thread);

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/caret.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/caret.c?rev=47226&r1=47225&r2=47226&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/caret.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/caret.c [iso-8859-1] Sat May 15 21:40:33 2010
@@ -189,7 +189,7 @@
          ThreadQueue->CaretInfo->Pos.x = X;
          ThreadQueue->CaretInfo->Pos.y = Y;
          co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
-         IntSetTimer(ThreadQueue->CaretInfo->hWnd, IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TRUE);
+         IntSetTimer(UserGetWindowObject(ThreadQueue->CaretInfo->hWnd), IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TMRF_SYSTEM);
       }
       return TRUE;
    }
@@ -302,7 +302,7 @@
       {
          co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
       }
-      IntSetTimer(ThreadQueue->CaretInfo->hWnd, IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TRUE);
+      IntSetTimer(UserGetWindowObject(ThreadQueue->CaretInfo->hWnd), IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TMRF_SYSTEM);
    }
 
    return TRUE;

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/message.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/message.c?rev=47226&r1=47225&r2=47226&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/message.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/message.c [iso-8859-1] Sat May 15 21:40:33 2010
@@ -880,23 +880,8 @@
       goto MsgExit;
    }
 
-   if (ThreadQueue->WakeMask & QS_TIMER)
-      if (PostTimerMessages(Window)) // If there are timers ready,
-         goto CheckMessages;       // go back and process them.
-
-   // LOL! Polling Timer Queue? How much time is spent doing this?
-   /* Check for WM_(SYS)TIMER messages */
-   Present = MsqGetTimerMessage( ThreadQueue,
-                                 Window,
-                                 MsgFilterMin,
-                                 MsgFilterMax,
-                                &Msg->Msg,
-                                 RemoveMessages);
-   if (Present)
-   {
-      Msg->FreeLParam = FALSE;
-      goto MessageFound;
-   }
+   if (PostTimerMessages(Window))
+      goto CheckMessages;
 
    if(Present)
    {

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/timer.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/timer.c?rev=47226&r1=47225&r2=47226&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/timer.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/timer.c [iso-8859-1] Sat May 15 21:40:33 2010
@@ -57,7 +57,7 @@
   {
       Ret = UserCreateObject(gHandleTable, NULL, &Handle, otTimer, sizeof(TIMER));
       if (Ret) InsertTailList(&FirstpTmr->ptmrList, &Ret->ptmrList);
-  } 
+  }
   return Ret;
 }
 
@@ -68,8 +68,8 @@
 {
   if (pTmr)
   {
-     RemoveEntryList(&pTmr->ptmrList);
-     UserDeleteObject( UserHMGetHandle(pTmr), otTimer);
+     /* Set the flag, it will be removed when ready */
+     pTmr->flags |= TMRF_DELETEPENDING;
      return TRUE;
   }
   return FALSE;
@@ -83,7 +83,7 @@
           BOOL Distroy)
 {
   PLIST_ENTRY pLE;
-  PTIMER pTmr = FirstpTmr;
+  PTIMER pTmr = FirstpTmr, RetTmr = NULL;
   KeEnterCriticalRegion();
   do
   {
@@ -96,8 +96,8 @@
        if (Distroy)
        {
           RemoveTimer(pTmr);
-          pTmr = (PTIMER)1; // We are here to remove the timer.
        }
+       RetTmr = pTmr;
        break;
     }
 
@@ -106,7 +106,7 @@
   } while (pTmr != FirstpTmr);
   KeLeaveCriticalRegion();
 
-  return pTmr;
+  return RetTmr;
 }
 
 PTIMER
@@ -162,15 +162,15 @@
   return TRUE;
 }
 
-// Rename it to IntSetTimer after move.
 UINT_PTR FASTCALL
-InternalSetTimer( PWINDOW_OBJECT Window,
+IntSetTimer( PWINDOW_OBJECT Window,
                   UINT_PTR IDEvent,
                   UINT Elapse,
                   TIMERPROC TimerFunc,
                   INT Type)
 {
   PTIMER pTmr;
+  UINT Ret= IDEvent;
   LARGE_INTEGER DueTime;
   DueTime.QuadPart = (LONGLONG)(-10000000);
 
@@ -195,6 +195,24 @@
   {
      DPRINT("Adjusting uElapse\n");
      Elapse = 10;
+  }
+
+  if ((Window == NULL) && (!(Type & TMRF_SYSTEM)))
+  {
+      IntLockWindowlessTimerBitmap();
+      IDEvent = RtlFindClearBitsAndSet(&WindowLessTimersBitMap, 1, HintIndex);
+
+      if (IDEvent == (UINT_PTR) -1)
+      {
+         IntUnlockWindowlessTimerBitmap();
+         DPRINT1("Unable to find a free window-less timer id\n");
+         SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+         return 0;
+      }
+
+      HintIndex = ++IDEvent;
+      IntUnlockWindowlessTimerBitmap();
+      Ret = IDEvent;
   }
 
   pTmr = FindTimer(Window, IDEvent, Type, FALSE);
@@ -215,18 +233,23 @@
      pTmr->pWnd    = Window;
      pTmr->cmsCountdown = Elapse;
      pTmr->cmsRate = Elapse;
-     pTmr->flags   = Type|TMRF_INIT; // Set timer to Init mode.
      pTmr->pfn     = TimerFunc;
      pTmr->nID     = IDEvent;
-
-     InsertTailList(&FirstpTmr->ptmrList, &pTmr->ptmrList);
+     pTmr->flags   = Type|TMRF_INIT; // Set timer to Init mode.
+  }
+
+  pTmr->cmsCountdown = Elapse;
+  pTmr->cmsRate = Elapse;
+  if (pTmr->flags & TMRF_DELETEPENDING)
+  {
+     pTmr->flags &= ~TMRF_DELETEPENDING;
   }
 
   // Start the timer thread!
-  KeSetTimer(MasterTimer, DueTime, NULL);
-
-  if (!pTmr->nID) return 1;
-  return pTmr->nID;
+  if (pTmr == FirstpTmr)
+     KeSetTimer(MasterTimer, DueTime, NULL);
+
+  return Ret;
 }
 
 //
@@ -248,7 +271,7 @@
 {
   // Need to start gdi syncro timers then start timer with Hang App proc
   // that calles Idle process so the screen savers will know to run......    
-  InternalSetTimer(NULL, 0, 1000, SystemTimerProc, TMRF_RIT);
+  IntSetTimer(NULL, 0, 1000, SystemTimerProc, TMRF_RIT);
 }
 
 UINT_PTR
@@ -256,14 +279,14 @@
 SystemTimerSet( PWINDOW_OBJECT Window,
                 UINT_PTR nIDEvent,
                 UINT uElapse,
-                TIMERPROC lpTimerFunc) 
+                TIMERPROC lpTimerFunc)
 {
   if (Window && Window->pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
   {
      SetLastWin32Error(ERROR_ACCESS_DENIED);
      return 0;
   }
-  return InternalSetTimer( Window, nIDEvent, uElapse, lpTimerFunc, TMRF_SYSTEM);
+  return IntSetTimer( Window, nIDEvent, uElapse, lpTimerFunc, TMRF_SYSTEM);
 }
 
 BOOL
@@ -279,28 +302,23 @@
 
   if (!pTmr) return FALSE;
 
-  if (Window && ((ULONG_PTR)Window != 1))
-  {
-     if (!Window->Wnd) return FALSE;
-  }
-
   pti = PsGetCurrentThreadWin32Thread();
   ThreadQueue = pti->MessageQueue;
 
   KeEnterCriticalRegion();
+
   do
   {
      if ( (pTmr->flags & TMRF_READY) &&
           (pTmr->pti == pti) &&
-          (pTmr->pWnd == Window))
+          ((pTmr->pWnd == Window) || (Window == NULL) ) )
         {
-           ASSERT((ULONG_PTR)Window != 1);
-           Msg.hwnd    = Window->hSelf;
+           Msg.hwnd    = (pTmr->pWnd) ? pTmr->pWnd->hSelf : 0;
            Msg.message = (pTmr->flags & TMRF_SYSTEM) ? WM_SYSTIMER : WM_TIMER;
            Msg.wParam  = (WPARAM) pTmr->nID;
            Msg.lParam  = (LPARAM) pTmr->pfn;
-           MsqPostMessage(ThreadQueue, &Msg, FALSE, QS_POSTMESSAGE);
-
+
+           MsqPostMessage(ThreadQueue, &Msg, FALSE, QS_TIMER);
            pTmr->flags &= ~TMRF_READY;
            ThreadQueue->WakeMask = ~QS_TIMER;
            Hit = TRUE;
@@ -309,6 +327,7 @@
      pLE = pTmr->ptmrList.Flink;
      pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
   } while (pTmr != FirstpTmr);
+
   KeLeaveCriticalRegion();
 
   return Hit;
@@ -330,7 +349,7 @@
   KeQueryTickCount(&TickCount);
   Time = MsqCalculateMessageTime(&TickCount);
 
-  DueTime.QuadPart = (LONGLONG)(-10000000);
+  DueTime.QuadPart = (LONGLONG)(-1000000);
 
   do
   {
@@ -341,8 +360,10 @@
        continue;
     }
 
-    if (pTmr->flags & TMRF_INIT)  
+    if (pTmr->flags & TMRF_INIT)
+    {
        pTmr->flags &= ~TMRF_INIT; // Skip this run.
+    }
     else
     {
        if (pTmr->cmsCountdown < 0)
@@ -363,16 +384,35 @@
                 // Set thread message queue for this timer.
                 if (pTmr->pti->MessageQueue)
                 {  // Wakeup thread
-                   pTmr->pti->MessageQueue->WakeMask |= QS_TIMER;
-                   KeSetEvent(pTmr->pti->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
+                   if (pTmr->pti->MessageQueue->WakeMask & QS_POSTMESSAGE)
+                      KeSetEvent(pTmr->pti->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
                 }
              }
           }
-          pTmr->cmsCountdown = pTmr->cmsRate;
+          if (pTmr->flags & TMRF_DELETEPENDING)
+          {
+             DPRINT("Removing Timer %x from List\n", pTmr);
+
+             /* FIXME: Fix this!!!! */
+/*
+             if (!pTmr->pWnd)
+             {
+                DPRINT1("Clearing Bits for WindowLess Timer\n");
+                IntLockWindowlessTimerBitmap();
+                RtlSetBits(&WindowLessTimersBitMap, pTmr->nID, 1);
+                IntUnlockWindowlessTimerBitmap();
+             }
+*/
+             RemoveEntryList(&pTmr->ptmrList);
+             UserDeleteObject( UserHMGetHandle(pTmr), otTimer);
+          }
+           else
+             pTmr->cmsCountdown = pTmr->cmsRate;
        }
        else
           pTmr->cmsCountdown -= Time - TimeLast;
     }
+
     pLE = pTmr->ptmrList.Flink;
     pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
   } while (pTmr != FirstpTmr);
@@ -391,7 +431,7 @@
 //
 //
 UINT_PTR FASTCALL
-IntSetTimer(HWND Wnd, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, BOOL SystemTimer)
+InternalSetTimer(HWND Wnd, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, BOOL SystemTimer)
 {
    PWINDOW_OBJECT Window;
    UINT_PTR Ret = 0;
@@ -477,17 +517,66 @@
       return 0;
    }
 
-
+if (Ret == 0) ASSERT(FALSE);
    return Ret;
 }
 
-
 BOOL FASTCALL
-IntKillTimer(HWND Wnd, UINT_PTR IDEvent, BOOL SystemTimer)
+DestroyTimersForThread(PTHREADINFO pti)
+{
+   PLIST_ENTRY pLE;
+   PTIMER pTmr = FirstpTmr;
+   BOOL TimersRemoved = FALSE;
+
+   if (FirstpTmr == NULL)
+      return FALSE;
+
+   KeEnterCriticalRegion();
+
+   do
+   {
+      if ((pTmr) && (pTmr->pti == pti))
+      {
+         pTmr->flags &= ~TMRF_READY;
+         pTmr->flags |= TMRF_DELETEPENDING;
+         TimersRemoved = TRUE;
+      }
+      pLE = pTmr->ptmrList.Flink;
+      pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
+   } while (pTmr != FirstpTmr);
+
+   KeLeaveCriticalRegion();
+
+   return TimersRemoved;
+}
+
+
+BOOL FASTCALL
+IntKillTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, BOOL SystemTimer)
+{
+   PTIMER pTmr = NULL;
+   DPRINT("IntKillTimer Window %x id %p systemtimer %s\n",
+          Window, IDEvent, SystemTimer ? "TRUE" : "FALSE");
+
+   if (IDEvent == 0)
+      return FALSE;
+
+   pTmr = FindTimer(Window, IDEvent, SystemTimer ? TMRF_SYSTEM : 0, TRUE);
+   return pTmr ? TRUE :  FALSE;
+}
+
+
+//
+//
+// Old Kill Timer
+//
+//
+BOOL FASTCALL
+InternalKillTimer(HWND Wnd, UINT_PTR IDEvent, BOOL SystemTimer)
 {
    PTHREADINFO pti;
    PWINDOW_OBJECT Window = NULL;
-   
+
    DPRINT("IntKillTimer wnd %x id %p systemtimer %s\n",
           Wnd, IDEvent, SystemTimer ? "TRUE" : "FALSE");
 
@@ -495,7 +584,7 @@
    if (Wnd)
    {
       Window = UserGetWindowObject(Wnd);
-   
+
       if (! MsqKillTimer(pti->MessageQueue, Wnd,
                                 IDEvent, SystemTimer ? WM_SYSTIMER : WM_TIMER))
       {
@@ -574,7 +663,7 @@
    DPRINT("Enter NtUserSetTimer\n");
    UserEnterExclusive();
 
-   RETURN(IntSetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc, FALSE));
+   RETURN(IntSetTimer(UserGetWindowObject(hWnd), nIDEvent, uElapse, lpTimerFunc, 0));
 
 CLEANUP:
    DPRINT("Leave NtUserSetTimer, ret=%i\n", _ret_);
@@ -591,12 +680,15 @@
    UINT_PTR uIDEvent
 )
 {
+   PWINDOW_OBJECT Window;
    DECLARE_RETURN(BOOL);
 
    DPRINT("Enter NtUserKillTimer\n");
    UserEnterExclusive();
 
-   RETURN(IntKillTimer(hWnd, uIDEvent, FALSE));
+   Window = UserGetWindowObject(hWnd);
+
+   RETURN(IntKillTimer(Window, uIDEvent, FALSE));
 
 CLEANUP:
    DPRINT("Leave NtUserKillTimer, ret=%i\n", _ret_);
@@ -620,7 +712,7 @@
    UserEnterExclusive();
 
    // This is wrong, lpTimerFunc is NULL!
-   RETURN(IntSetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc, TRUE));
+   RETURN(IntSetTimer(UserGetWindowObject(hWnd), nIDEvent, uElapse, lpTimerFunc, TMRF_SYSTEM));
 
 CLEANUP:
    DPRINT("Leave NtUserSetSystemTimer, ret=%i\n", _ret_);





More information about the Ros-dev mailing list