mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 01:15:42 +00:00
[Win32k]
- Patch by rafalh <rafalh1992 at o2 dor pl>, see bug 5835. Fix timers implementation. svn path=/trunk/; revision=50547
This commit is contained in:
parent
3ade810715
commit
ac10b13f14
1 changed files with 55 additions and 74 deletions
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
static PTIMER FirstpTmr = NULL;
|
static LIST_ENTRY TimersListHead;
|
||||||
static LONG TimeLast = 0;
|
static LONG TimeLast = 0;
|
||||||
|
|
||||||
#define MAX_ELAPSE_TIME 0x7FFFFFFF
|
#define MAX_ELAPSE_TIME 0x7FFFFFFF
|
||||||
|
@ -62,26 +62,13 @@ CreateTimer(VOID)
|
||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
PTIMER Ret = NULL;
|
PTIMER Ret = NULL;
|
||||||
|
|
||||||
if (!FirstpTmr)
|
Ret = UserCreateObject(gHandleTable, NULL, &Handle, otTimer, sizeof(TIMER));
|
||||||
|
if (Ret)
|
||||||
{
|
{
|
||||||
ExInitializeResourceLite(&TimerLock);
|
Ret->head.h = Handle;
|
||||||
FirstpTmr = UserCreateObject(gHandleTable, NULL, &Handle, otTimer, sizeof(TIMER));
|
InsertTailList(&TimersListHead, &Ret->ptmrList);
|
||||||
if (FirstpTmr)
|
|
||||||
{
|
|
||||||
FirstpTmr->head.h = Handle;
|
|
||||||
InitializeListHead(&FirstpTmr->ptmrList);
|
|
||||||
}
|
|
||||||
Ret = FirstpTmr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Ret = UserCreateObject(gHandleTable, NULL, &Handle, otTimer, sizeof(TIMER));
|
|
||||||
if (Ret)
|
|
||||||
{
|
|
||||||
Ret->head.h = Handle;
|
|
||||||
InsertTailList(&FirstpTmr->ptmrList, &Ret->ptmrList);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,12 +105,13 @@ FindTimer(PWND Window,
|
||||||
UINT_PTR nID,
|
UINT_PTR nID,
|
||||||
UINT flags)
|
UINT flags)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY pLE;
|
PLIST_ENTRY pLE = TimersListHead.Flink;
|
||||||
PTIMER pTmr = FirstpTmr, RetTmr = NULL;
|
PTIMER pTmr, RetTmr = NULL;
|
||||||
|
|
||||||
TimerEnterExclusive();
|
TimerEnterExclusive();
|
||||||
do
|
while (pLE != &TimersListHead)
|
||||||
{
|
{
|
||||||
if (!pTmr) break;
|
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
||||||
|
|
||||||
if ( pTmr->nID == nID &&
|
if ( pTmr->nID == nID &&
|
||||||
pTmr->pWnd == Window &&
|
pTmr->pWnd == Window &&
|
||||||
|
@ -133,9 +121,8 @@ FindTimer(PWND Window,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pLE = pTmr->ptmrList.Flink;
|
pLE = pLE->Flink;
|
||||||
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
}
|
||||||
} while (pTmr != FirstpTmr);
|
|
||||||
TimerLeave();
|
TimerLeave();
|
||||||
|
|
||||||
return RetTmr;
|
return RetTmr;
|
||||||
|
@ -145,20 +132,20 @@ PTIMER
|
||||||
FASTCALL
|
FASTCALL
|
||||||
FindSystemTimer(PMSG pMsg)
|
FindSystemTimer(PMSG pMsg)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY pLE;
|
PLIST_ENTRY pLE = TimersListHead.Flink;
|
||||||
PTIMER pTmr = FirstpTmr;
|
PTIMER pTmr = NULL;
|
||||||
|
|
||||||
TimerEnterExclusive();
|
TimerEnterExclusive();
|
||||||
do
|
while (pLE != &TimersListHead)
|
||||||
{
|
{
|
||||||
if (!pTmr) break;
|
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
||||||
|
|
||||||
if ( pMsg->lParam == (LPARAM)pTmr->pfn &&
|
if ( pMsg->lParam == (LPARAM)pTmr->pfn &&
|
||||||
(pTmr->flags & TMRF_SYSTEM) )
|
(pTmr->flags & TMRF_SYSTEM) )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pLE = pTmr->ptmrList.Flink;
|
pLE = pLE->Flink;
|
||||||
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
}
|
||||||
} while (pTmr != FirstpTmr);
|
|
||||||
TimerLeave();
|
TimerLeave();
|
||||||
|
|
||||||
return pTmr;
|
return pTmr;
|
||||||
|
@ -169,15 +156,14 @@ FASTCALL
|
||||||
ValidateTimerCallback(PTHREADINFO pti,
|
ValidateTimerCallback(PTHREADINFO pti,
|
||||||
LPARAM lParam)
|
LPARAM lParam)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY pLE;
|
PLIST_ENTRY pLE = TimersListHead.Flink;
|
||||||
BOOL Ret = FALSE;
|
BOOL Ret = FALSE;
|
||||||
PTIMER pTmr = FirstpTmr;
|
PTIMER pTmr;
|
||||||
|
|
||||||
if (!pTmr) return FALSE;
|
|
||||||
|
|
||||||
TimerEnterExclusive();
|
TimerEnterExclusive();
|
||||||
do
|
while (pLE != &TimersListHead)
|
||||||
{
|
{
|
||||||
|
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
||||||
if ( (lParam == (LPARAM)pTmr->pfn) &&
|
if ( (lParam == (LPARAM)pTmr->pfn) &&
|
||||||
!(pTmr->flags & (TMRF_SYSTEM|TMRF_RIT)) &&
|
!(pTmr->flags & (TMRF_SYSTEM|TMRF_RIT)) &&
|
||||||
(pTmr->pti->ppi == pti->ppi) )
|
(pTmr->pti->ppi == pti->ppi) )
|
||||||
|
@ -185,9 +171,8 @@ ValidateTimerCallback(PTHREADINFO pti,
|
||||||
Ret = TRUE;
|
Ret = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pLE = pTmr->ptmrList.Flink;
|
pLE = pLE->Flink;
|
||||||
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
}
|
||||||
} while (pTmr != FirstpTmr);
|
|
||||||
TimerLeave();
|
TimerLeave();
|
||||||
|
|
||||||
return Ret;
|
return Ret;
|
||||||
|
@ -286,7 +271,7 @@ IntSetTimer( PWND Window,
|
||||||
|
|
||||||
ASSERT(MasterTimer != NULL);
|
ASSERT(MasterTimer != NULL);
|
||||||
// Start the timer thread!
|
// Start the timer thread!
|
||||||
if (pTmr == FirstpTmr)
|
if (TimersListHead.Flink == TimersListHead.Blink) // There is only one timer
|
||||||
KeSetTimer(MasterTimer, DueTime, NULL);
|
KeSetTimer(MasterTimer, DueTime, NULL);
|
||||||
|
|
||||||
return Ret;
|
return Ret;
|
||||||
|
@ -334,22 +319,21 @@ BOOL
|
||||||
FASTCALL
|
FASTCALL
|
||||||
PostTimerMessages(PWND Window)
|
PostTimerMessages(PWND Window)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY pLE;
|
PLIST_ENTRY pLE = TimersListHead.Flink;
|
||||||
PUSER_MESSAGE_QUEUE ThreadQueue;
|
PUSER_MESSAGE_QUEUE ThreadQueue;
|
||||||
MSG Msg;
|
MSG Msg;
|
||||||
PTHREADINFO pti;
|
PTHREADINFO pti;
|
||||||
BOOL Hit = FALSE;
|
BOOL Hit = FALSE;
|
||||||
PTIMER pTmr = FirstpTmr;
|
PTIMER pTmr;
|
||||||
|
|
||||||
if (!pTmr) return FALSE;
|
|
||||||
|
|
||||||
pti = PsGetCurrentThreadWin32Thread();
|
pti = PsGetCurrentThreadWin32Thread();
|
||||||
ThreadQueue = pti->MessageQueue;
|
ThreadQueue = pti->MessageQueue;
|
||||||
|
|
||||||
TimerEnterExclusive();
|
TimerEnterExclusive();
|
||||||
|
|
||||||
do
|
while(pLE != &TimersListHead)
|
||||||
{
|
{
|
||||||
|
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
||||||
if ( (pTmr->flags & TMRF_READY) &&
|
if ( (pTmr->flags & TMRF_READY) &&
|
||||||
(pTmr->pti == pti) &&
|
(pTmr->pti == pti) &&
|
||||||
((pTmr->pWnd == Window) || (Window == NULL)) )
|
((pTmr->pWnd == Window) || (Window == NULL)) )
|
||||||
|
@ -366,9 +350,8 @@ PostTimerMessages(PWND Window)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pLE = pTmr->ptmrList.Flink;
|
pLE = pLE->Flink;
|
||||||
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
}
|
||||||
} while (pTmr != FirstpTmr);
|
|
||||||
|
|
||||||
TimerLeave();
|
TimerLeave();
|
||||||
|
|
||||||
|
@ -381,12 +364,10 @@ ProcessTimers(VOID)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER TickCount, DueTime;
|
LARGE_INTEGER TickCount, DueTime;
|
||||||
LONG Time;
|
LONG Time;
|
||||||
PLIST_ENTRY pLE;
|
PLIST_ENTRY pLE = TimersListHead.Flink;
|
||||||
PTIMER pTmr = FirstpTmr;
|
PTIMER pTmr;
|
||||||
LONG TimerCount = 0;
|
LONG TimerCount = 0;
|
||||||
|
|
||||||
if (!pTmr) return;
|
|
||||||
|
|
||||||
TimerEnterExclusive();
|
TimerEnterExclusive();
|
||||||
|
|
||||||
KeQueryTickCount(&TickCount);
|
KeQueryTickCount(&TickCount);
|
||||||
|
@ -394,8 +375,9 @@ ProcessTimers(VOID)
|
||||||
|
|
||||||
DueTime.QuadPart = (LONGLONG)(-500000);
|
DueTime.QuadPart = (LONGLONG)(-500000);
|
||||||
|
|
||||||
do
|
while(pLE != &TimersListHead)
|
||||||
{
|
{
|
||||||
|
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
||||||
TimerCount++;
|
TimerCount++;
|
||||||
if (pTmr->flags & TMRF_WAITING)
|
if (pTmr->flags & TMRF_WAITING)
|
||||||
{
|
{
|
||||||
|
@ -440,9 +422,8 @@ ProcessTimers(VOID)
|
||||||
pTmr->cmsCountdown -= Time - TimeLast;
|
pTmr->cmsCountdown -= Time - TimeLast;
|
||||||
}
|
}
|
||||||
|
|
||||||
pLE = pTmr->ptmrList.Flink;
|
pLE = pLE->Flink;
|
||||||
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
}
|
||||||
} while (pTmr != FirstpTmr);
|
|
||||||
|
|
||||||
// Restart the timer thread!
|
// Restart the timer thread!
|
||||||
ASSERT(MasterTimer != NULL);
|
ASSERT(MasterTimer != NULL);
|
||||||
|
@ -457,24 +438,24 @@ ProcessTimers(VOID)
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
DestroyTimersForWindow(PTHREADINFO pti, PWND Window)
|
DestroyTimersForWindow(PTHREADINFO pti, PWND Window)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY pLE;
|
PLIST_ENTRY pLE = TimersListHead.Flink;
|
||||||
PTIMER pTmr = FirstpTmr;
|
PTIMER pTmr;
|
||||||
BOOL TimersRemoved = FALSE;
|
BOOL TimersRemoved = FALSE;
|
||||||
|
|
||||||
if ((FirstpTmr == NULL) || (Window == NULL))
|
if ((Window == NULL))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
TimerEnterExclusive();
|
TimerEnterExclusive();
|
||||||
|
|
||||||
do
|
while(pLE != &TimersListHead)
|
||||||
{
|
{
|
||||||
|
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
||||||
|
pLE = pLE->Flink; /* get next timer list entry before current timer is removed */
|
||||||
if ((pTmr) && (pTmr->pti == pti) && (pTmr->pWnd == Window))
|
if ((pTmr) && (pTmr->pti == pti) && (pTmr->pWnd == Window))
|
||||||
{
|
{
|
||||||
TimersRemoved = RemoveTimer(pTmr);
|
TimersRemoved = RemoveTimer(pTmr);
|
||||||
}
|
}
|
||||||
pLE = pTmr->ptmrList.Flink;
|
}
|
||||||
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
|
||||||
} while (pTmr != FirstpTmr);
|
|
||||||
|
|
||||||
TimerLeave();
|
TimerLeave();
|
||||||
|
|
||||||
|
@ -484,24 +465,21 @@ DestroyTimersForWindow(PTHREADINFO pti, PWND Window)
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
DestroyTimersForThread(PTHREADINFO pti)
|
DestroyTimersForThread(PTHREADINFO pti)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY pLE;
|
PLIST_ENTRY pLE = TimersListHead.Flink;
|
||||||
PTIMER pTmr = FirstpTmr;
|
PTIMER pTmr;
|
||||||
BOOL TimersRemoved = FALSE;
|
BOOL TimersRemoved = FALSE;
|
||||||
|
|
||||||
if (FirstpTmr == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
TimerEnterExclusive();
|
TimerEnterExclusive();
|
||||||
|
|
||||||
do
|
while(pLE != &TimersListHead)
|
||||||
{
|
{
|
||||||
|
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
||||||
|
pLE = pLE->Flink; /* get next timer list entry before current timer is removed */
|
||||||
if ((pTmr) && (pTmr->pti == pti))
|
if ((pTmr) && (pTmr->pti == pti))
|
||||||
{
|
{
|
||||||
TimersRemoved = RemoveTimer(pTmr);
|
TimersRemoved = RemoveTimer(pTmr);
|
||||||
}
|
}
|
||||||
pLE = pTmr->ptmrList.Flink;
|
}
|
||||||
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
|
||||||
} while (pTmr != FirstpTmr);
|
|
||||||
|
|
||||||
TimerLeave();
|
TimerLeave();
|
||||||
|
|
||||||
|
@ -550,6 +528,9 @@ InitTimerImpl(VOID)
|
||||||
/* yes we need this, since ExAllocatePoolWithTag isn't supposed to zero out allocated memory */
|
/* yes we need this, since ExAllocatePoolWithTag isn't supposed to zero out allocated memory */
|
||||||
RtlClearAllBits(&WindowLessTimersBitMap);
|
RtlClearAllBits(&WindowLessTimersBitMap);
|
||||||
|
|
||||||
|
ExInitializeResourceLite(&TimerLock);
|
||||||
|
InitializeListHead(&TimersListHead);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue