at last! All hail mjmartin! :-) On Mon, May 17, 2010 at 9:41 AM, Ged Murphy <[email protected]> wrote:
> Congrats, good stuff Michael :) > > -----Original Message----- > From: [email protected] [mailto:[email protected]] > On Behalf Of [email protected] > Sent: 15 May 2010 20:41 > To: [email protected] > 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 > [email protected] > http://www.reactos.org/mailman/listinfo/ros-dev >
_______________________________________________ Ros-dev mailing list [email protected] http://www.reactos.org/mailman/listinfo/ros-dev
