Final Windows timer optimisation work, for now

git-svn-id: svn://10.0.0.236/trunk@59065 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
michael.lowe%bigfoot.com 2000-01-28 14:01:42 +00:00
parent edc46c536d
commit 4be0c83a52

View File

@ -36,10 +36,11 @@
static NS_DEFINE_CID(kTimerManagerCID, NS_TIMERMANAGER_CID);
static nsCOMPtr<nsIWindowsTimerMap> sTimerMap;
static nsCOMPtr<nsITimerQueue> sTimerQueue;
class nsTimer;
#define NS_PRIORITY_IMMEDIATE 10
@ -48,17 +49,11 @@ void CALLBACK FireTimeout(HWND aWindow,
UINT aTimerID,
DWORD aTime)
{
// Don't allow old timer messages in here.
if(aMessage != WM_TIMER) {
PR_ASSERT(0);
return;
}
PR_ASSERT(aMessage == WM_TIMER);
nsresult rv;
NS_WITH_SERVICE(nsIWindowsTimerMap, manager, kTimerManagerCID, &rv);
if (NS_FAILED(rv)) return;
if (!sTimerMap) return;
nsTimer* timer = manager->GetTimer(aTimerID);
nsTimer* timer = sTimerMap->GetTimer(aTimerID);
if (timer == nsnull) {
return;
}
@ -68,26 +63,30 @@ void CALLBACK FireTimeout(HWND aWindow,
timer->KillOSTimer();
}
nsCOMPtr<nsITimerQueue> queue = do_QueryInterface(manager, &rv);
if (NS_FAILED(rv)) return;
if (!sTimerQueue) return;
MSG wmsg;
if (!::PeekMessage(&wmsg, NULL, 0, 0, PM_NOREMOVE) ||
bool eventQueueEmpty = !::PeekMessage(&wmsg, NULL, 0, 0, PM_NOREMOVE);
bool timerQueueEmpty = !sTimerQueue->HasReadyTimers(NS_PRIORITY_LOWEST);
if ((timerQueueEmpty && eventQueueEmpty) ||
timer->GetPriority() >= NS_PRIORITY_IMMEDIATE) {
// fire timer immediatly
timer->Fire();
// while event queue is empty, fire off waiting timers
while (queue->HasReadyTimers(NS_PRIORITY_LOWEST) &&
!::PeekMessage(&wmsg, NULL, 0, 0, PM_NOREMOVE)) {
queue->FireNextReadyTimer(NS_PRIORITY_LOWEST);
}
} else {
// defer timer firing
queue->AddReadyQueue(timer);
sTimerQueue->AddReadyQueue(timer);
}
if (eventQueueEmpty) {
// while event queue is empty, fire off waiting timers
while (sTimerQueue->HasReadyTimers(NS_PRIORITY_LOWEST) &&
!::PeekMessage(&wmsg, NULL, 0, 0, PM_NOREMOVE)) {
sTimerQueue->FireNextReadyTimer(NS_PRIORITY_LOWEST);
}
}
}
@ -104,6 +103,15 @@ nsTimer::nsTimer() : nsITimer()
mClosure = nsnull;
mTimerID = 0;
mTimerRunning = false;
static int cachedService = 0;
if (cachedService == 0) {
cachedService = 1;
nsresult rv;
sTimerMap = do_GetService(kTimerManagerCID, &rv);
sTimerQueue = do_GetService(kTimerManagerCID, &rv);
}
}
@ -224,15 +232,13 @@ void nsTimer::StartOSTimer(PRUint32 aDelay)
{
PR_ASSERT(mTimerID == 0);
nsresult rv;
NS_WITH_SERVICE(nsIWindowsTimerMap, manager, kTimerManagerCID, &rv);
if (NS_FAILED(rv)) return;
if (!sTimerMap) return;
// create OS timer
mTimerID = ::SetTimer(NULL, 0, aDelay, (TIMERPROC)FireTimeout);
// store mapping from OS timer to timer object
manager->AddTimer(mTimerID, this);
sTimerMap->AddTimer(mTimerID, this);
}
@ -240,12 +246,9 @@ void nsTimer::KillOSTimer()
{
if (mTimerID != 0) {
nsresult rv;
NS_WITH_SERVICE(nsIWindowsTimerMap, manager, kTimerManagerCID, &rv);
// remove mapping from OS timer to timer object
if (NS_SUCCEEDED(rv)) {
manager->RemoveTimer(mTimerID);
if (sTimerMap) {
sTimerMap->RemoveTimer(mTimerID);
}
// kill OS timer