mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
[win32k]
- Remove use of TMRF_DELETEPENDING for deleting timers as this was a bad idea. Timers need to be deleted immediately as waiting for them to be deleted resulted in some processes running out of handles. Fixes richedit winetest for editor. - Add flag TMRF_TIFROMWND for timers created from user mode so the thread stored in the timer object is from the window and not caller. Fixes an issue where FireFox would not show any of its windows and looked dead. - When creating and deleting timers, If the window is non null and IDEvent is 0 then the IDEvent is changed to 1. - When modifying timer list use UserEnter and Leave instead of a Critical Region only. svn path=/trunk/; revision=47385
This commit is contained in:
parent
f9cd9b9a5b
commit
18c065e00d
2 changed files with 34 additions and 46 deletions
|
@ -23,7 +23,6 @@ typedef struct _TIMER
|
|||
#define TMRF_ONESHOT 0x0010
|
||||
#define TMRF_WAITING 0x0020
|
||||
#define TMRF_TIFROMWND 0x0040
|
||||
#define TMRF_DELETEPENDING 0x8000
|
||||
|
||||
extern PKTIMER MasterTimer;
|
||||
|
||||
|
|
|
@ -69,7 +69,8 @@ RemoveTimer(PTIMER pTmr)
|
|||
if (pTmr)
|
||||
{
|
||||
/* Set the flag, it will be removed when ready */
|
||||
pTmr->flags |= TMRF_DELETEPENDING;
|
||||
RemoveEntryList(&pTmr->ptmrList);
|
||||
UserDeleteObject( UserHMGetHandle(pTmr), otTimer);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
@ -215,21 +216,25 @@ IntSetTimer( PWINDOW_OBJECT Window,
|
|||
Ret = IDEvent;
|
||||
}
|
||||
|
||||
if ((Window) && (IDEvent == 0))
|
||||
IDEvent = 1;
|
||||
|
||||
pTmr = FindTimer(Window, IDEvent, Type, FALSE);
|
||||
if ((!pTmr) || (pTmr->flags & TMRF_DELETEPENDING))
|
||||
if (!pTmr)
|
||||
{
|
||||
pTmr = CreateTimer();
|
||||
if (!pTmr) return 0;
|
||||
|
||||
if (Window && (Type & TMRF_TIFROMWND))
|
||||
pTmr->pti = Window->pti->pEThread->Tcb.Win32Thread;
|
||||
else
|
||||
{
|
||||
if (Type & TMRF_RIT)
|
||||
pTmr->pti = ptiRawInput;
|
||||
else
|
||||
pTmr->pti = PsGetCurrentThreadWin32Thread();
|
||||
if (Window && (Type & TMRF_TIFROMWND))
|
||||
pTmr->pti = Window->pti->pEThread->Tcb.Win32Thread;
|
||||
else
|
||||
{
|
||||
if (Type & TMRF_RIT)
|
||||
pTmr->pti = ptiRawInput;
|
||||
else
|
||||
pTmr->pti = PsGetCurrentThreadWin32Thread();
|
||||
}
|
||||
|
||||
pTmr->pWnd = Window;
|
||||
pTmr->cmsCountdown = Elapse;
|
||||
pTmr->cmsRate = Elapse;
|
||||
|
@ -237,9 +242,11 @@ IntSetTimer( PWINDOW_OBJECT Window,
|
|||
pTmr->nID = IDEvent;
|
||||
pTmr->flags = Type|TMRF_INIT; // Set timer to Init mode.
|
||||
}
|
||||
|
||||
pTmr->cmsCountdown = Elapse;
|
||||
pTmr->cmsRate = Elapse;
|
||||
else
|
||||
{
|
||||
pTmr->cmsCountdown = Elapse;
|
||||
pTmr->cmsRate = Elapse;
|
||||
}
|
||||
|
||||
ASSERT(MasterTimer != NULL);
|
||||
// Start the timer thread!
|
||||
|
@ -302,7 +309,7 @@ PostTimerMessages(PWINDOW_OBJECT Window)
|
|||
pti = PsGetCurrentThreadWin32Thread();
|
||||
ThreadQueue = pti->MessageQueue;
|
||||
|
||||
KeEnterCriticalRegion();
|
||||
UserEnterExclusive();
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -325,7 +332,7 @@ PostTimerMessages(PWINDOW_OBJECT Window)
|
|||
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
||||
} while (pTmr != FirstpTmr);
|
||||
|
||||
KeLeaveCriticalRegion();
|
||||
UserLeave();
|
||||
|
||||
return Hit;
|
||||
}
|
||||
|
@ -389,25 +396,7 @@ ProcessTimers(VOID)
|
|||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
pTmr->cmsCountdown = pTmr->cmsRate;
|
||||
}
|
||||
else
|
||||
pTmr->cmsCountdown -= Time - TimeLast;
|
||||
|
@ -533,21 +522,21 @@ DestroyTimersForWindow(PTHREADINFO pti, PWINDOW_OBJECT Window)
|
|||
if ((FirstpTmr == NULL) || (Window == NULL))
|
||||
return FALSE;
|
||||
|
||||
KeEnterCriticalRegion();
|
||||
UserEnterExclusive();
|
||||
|
||||
do
|
||||
{
|
||||
if ((pTmr) && (pTmr->pti == pti) && (pTmr->pWnd == Window))
|
||||
{
|
||||
pTmr->flags &= ~TMRF_READY;
|
||||
pTmr->flags |= TMRF_DELETEPENDING;
|
||||
RemoveEntryList(&pTmr->ptmrList);
|
||||
UserDeleteObject( UserHMGetHandle(pTmr), otTimer);
|
||||
TimersRemoved = TRUE;
|
||||
}
|
||||
pLE = pTmr->ptmrList.Flink;
|
||||
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
||||
} while (pTmr != FirstpTmr);
|
||||
|
||||
KeLeaveCriticalRegion();
|
||||
UserLeave();
|
||||
|
||||
return TimersRemoved;
|
||||
}
|
||||
|
@ -562,21 +551,21 @@ DestroyTimersForThread(PTHREADINFO pti)
|
|||
if (FirstpTmr == NULL)
|
||||
return FALSE;
|
||||
|
||||
KeEnterCriticalRegion();
|
||||
UserEnterExclusive();
|
||||
|
||||
do
|
||||
{
|
||||
if ((pTmr) && (pTmr->pti == pti))
|
||||
{
|
||||
pTmr->flags &= ~TMRF_READY;
|
||||
pTmr->flags |= TMRF_DELETEPENDING;
|
||||
RemoveEntryList(&pTmr->ptmrList);
|
||||
UserDeleteObject( UserHMGetHandle(pTmr), otTimer);
|
||||
TimersRemoved = TRUE;
|
||||
}
|
||||
pLE = pTmr->ptmrList.Flink;
|
||||
pTmr = CONTAINING_RECORD(pLE, TIMER, ptmrList);
|
||||
} while (pTmr != FirstpTmr);
|
||||
|
||||
KeLeaveCriticalRegion();
|
||||
UserLeave();
|
||||
|
||||
return TimersRemoved;
|
||||
}
|
||||
|
@ -588,8 +577,8 @@ IntKillTimer(PWINDOW_OBJECT Window, UINT_PTR IDEvent, BOOL SystemTimer)
|
|||
DPRINT("IntKillTimer Window %x id %p systemtimer %s\n",
|
||||
Window, IDEvent, SystemTimer ? "TRUE" : "FALSE");
|
||||
|
||||
if (IDEvent == 0)
|
||||
return FALSE;
|
||||
if ((Window) && (IDEvent == 0))
|
||||
IDEvent = 1;
|
||||
|
||||
pTmr = FindTimer(Window, IDEvent, SystemTimer ? TMRF_SYSTEM : 0, TRUE);
|
||||
return pTmr ? TRUE : FALSE;
|
||||
|
@ -692,7 +681,7 @@ NtUserSetTimer
|
|||
DPRINT("Enter NtUserSetTimer\n");
|
||||
UserEnterExclusive();
|
||||
|
||||
RETURN(IntSetTimer(UserGetWindowObject(hWnd), nIDEvent, uElapse, lpTimerFunc, 0));
|
||||
RETURN(IntSetTimer(UserGetWindowObject(hWnd), nIDEvent, uElapse, lpTimerFunc, TMRF_TIFROMWND));
|
||||
|
||||
CLEANUP:
|
||||
DPRINT("Leave NtUserSetTimer, ret=%i\n", _ret_);
|
||||
|
|
Loading…
Reference in a new issue