[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 whe

Javier Agustìn Fernàndez Arroyo elhoir at gmail.com
Mon May 17 12:10:48 CEST 2010


at last!
All hail mjmartin! :-)

On Mon, May 17, 2010 at 9:41 AM, Ged Murphy <gedmurphy at gmail.com> wrote:

> 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_);
>
>
>
> _______________________________________________
> Ros-dev mailing list
> Ros-dev at reactos.org
> http://www.reactos.org/mailman/listinfo/ros-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.reactos.org/pipermail/ros-dev/attachments/20100517/564e5127/attachment.htm>


More information about the Ros-dev mailing list