Author: mjmartin Date: Wed May 26 04:04:09 2010 New Revision: 47358
URL: http://svn.reactos.org/svn/reactos?rev=47358&view=rev Log: [win32k] - Implement DestroyTimersForWindow and call it instead of MsqRemoveTimersWindow when destroying a window. - Fire NewMessages event when cleaning up thread so that threads dont wait for new messages that will never be received. Fixes a problem where some application that use timers dont completly exit. - IntSetTimer: Dont try to raise a timer from the dead. Once the TMRF_DELETEPENDING flag is set, let it be destroyed. - co_MsqWaitForNewMessages: Call the wait without a timeout value as now when the timer expires the NewMessages event will be set to exit the wait. - Message Queue specific timer code and old time queuing code is now dead. It will be removed later when we are happy with new timer implementation.
Modified: trunk/reactos/subsystems/win32/win32k/include/timer.h trunk/reactos/subsystems/win32/win32k/main/dllmain.c trunk/reactos/subsystems/win32/win32k/ntuser/defwnd.c trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c trunk/reactos/subsystems/win32/win32k/ntuser/timer.c trunk/reactos/subsystems/win32/win32k/ntuser/window.c
Modified: trunk/reactos/subsystems/win32/win32k/include/timer.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/timer.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/timer.h [iso-8859-1] Wed May 26 04:04:09 2010 @@ -29,6 +29,7 @@
NTSTATUS FASTCALL InitTimerImpl(VOID); BOOL FASTCALL DestroyTimersForThread(PTHREADINFO pti); +BOOL FASTCALL DestroyTimersForWindow(PTHREADINFO pti, PWINDOW_OBJECT Window); 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);
Modified: trunk/reactos/subsystems/win32/win32k/main/dllmain.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/mai... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/main/dllmain.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/main/dllmain.c [iso-8859-1] Wed May 26 04:04:09 2010 @@ -292,6 +292,7 @@ HOOK_DestroyThreadHooks(Thread); /* Cleanup timers */ DestroyTimersForThread(Win32Thread); + KeSetEvent(Win32Thread->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); 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/defwnd.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/defwnd.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/defwnd.c [iso-8859-1] Wed May 26 04:04:09 2010 @@ -67,7 +67,7 @@ co_IntSendMessage(WndChild->hSelf, WM_ENDSESSION, KillTimers, lParams); if (KillTimers) { - MsqRemoveTimersWindow(WndChild->pti->MessageQueue, WndChild->hSelf); + DestroyTimersForWindow(WndChild->pti, WndChild); } lResult = MCSR_SHUTDOWNFINISHED; } @@ -90,7 +90,7 @@ co_IntSendMessage(pWindow->hSelf, WM_ENDSESSION, KillTimers, lParams); if (KillTimers) { - MsqRemoveTimersWindow(pWindow->pti->MessageQueue, pWindow->hSelf); + DestroyTimersForWindow(pWindow->pti, pWindow); } lResult = MCSR_SHUTDOWNFINISHED; }
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] Wed May 26 04:04:09 2010 @@ -1366,18 +1366,7 @@ UINT MsgFilterMin, UINT MsgFilterMax) { PVOID WaitObjects[2] = {MessageQueue->NewMessages, &HardwareMessageEvent}; - LARGE_INTEGER TimerExpiry; - PLARGE_INTEGER Timeout; NTSTATUS ret; - - if (MsqGetFirstTimerExpiry(MessageQueue, WndFilter, MsgFilterMin, MsgFilterMax, &TimerExpiry)) - { - Timeout = &TimerExpiry; - } - else - { - Timeout = NULL; - }
IdlePing(); // Going to wait so send Idle ping.
@@ -1389,11 +1378,9 @@ Executive, UserMode, FALSE, - Timeout, + NULL, NULL); - UserEnterCo(); - return ret; }
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/timer.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/timer.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/timer.c [iso-8859-1] Wed May 26 04:04:09 2010 @@ -216,7 +216,7 @@ }
pTmr = FindTimer(Window, IDEvent, Type, FALSE); - if (!pTmr) + if ((!pTmr) || (pTmr->flags & TMRF_DELETEPENDING)) { pTmr = CreateTimer(); if (!pTmr) return 0; @@ -240,10 +240,6 @@
pTmr->cmsCountdown = Elapse; pTmr->cmsRate = Elapse; - if (pTmr->flags & TMRF_DELETEPENDING) - { - pTmr->flags &= ~TMRF_DELETEPENDING; - }
ASSERT(MasterTimer != NULL); // Start the timer thread! @@ -342,6 +338,7 @@ LONG Time; PLIST_ENTRY pLE; PTIMER pTmr = FirstpTmr; + LONG TimerCount = 0;
if (!pTmr) return;
@@ -354,6 +351,7 @@
do { + TimerCount++; if (pTmr->flags & TMRF_WAITING) { pLE = pTmr->ptmrList.Flink; @@ -426,6 +424,7 @@ TimeLast = Time;
UserLeave(); + DPRINT("TimerCount = %d\n", TimerCount); }
// @@ -522,6 +521,35 @@
if (Ret == 0) ASSERT(FALSE); return Ret; +} + +BOOL FASTCALL +DestroyTimersForWindow(PTHREADINFO pti, PWINDOW_OBJECT Window) +{ + PLIST_ENTRY pLE; + PTIMER pTmr = FirstpTmr; + BOOL TimersRemoved = FALSE; + + if ((FirstpTmr == NULL) || (Window == NULL)) + return FALSE; + + KeEnterCriticalRegion(); + + do + { + if ((pTmr) && (pTmr->pti == pti) && (pTmr->pWnd == Window)) + { + 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 @@ -553,7 +581,6 @@ return TimersRemoved; }
- BOOL FASTCALL IntKillTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, BOOL SystemTimer) { @@ -567,7 +594,6 @@ pTmr = FindTimer(Window, IDEvent, SystemTimer ? TMRF_SYSTEM : 0, TRUE); return pTmr ? TRUE : FALSE; } -
// //
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/window.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c [iso-8859-1] Wed May 26 04:04:09 2010 @@ -424,7 +424,7 @@ if(BelongsToThreadData) co_IntSendMessage(Window->hSelf, WM_NCDESTROY, 0, 0); } - MsqRemoveTimersWindow(ThreadData->MessageQueue, Window->hSelf); + DestroyTimersForWindow(ThreadData, Window); HOOK_DestroyThreadHooks(ThreadData->pEThread); // This is needed here too!
/* flush the message queue */