- 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:
Michael Martin 2010-05-28 20:35:30 +00:00
parent f9cd9b9a5b
commit 18c065e00d
2 changed files with 34 additions and 46 deletions

View file

@ -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;

View file

@ -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_);