mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 05:45:37 +00:00
Bug 1178890: Update timer arrays after sleep to account for time sleeping r=bwc,froydnj
This commit is contained in:
parent
a317499767
commit
78f6d80fa0
@ -30,7 +30,8 @@ TimerThread::TimerThread() :
|
||||
mShutdown(false),
|
||||
mWaiting(false),
|
||||
mNotified(false),
|
||||
mSleeping(false)
|
||||
mSleeping(false),
|
||||
mLastTimerEventLoopRun(TimeStamp::Now())
|
||||
{
|
||||
}
|
||||
|
||||
@ -242,6 +243,7 @@ TimerThread::Run()
|
||||
} else {
|
||||
waitFor = PR_INTERVAL_NO_TIMEOUT;
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
mLastTimerEventLoopRun = now;
|
||||
nsTimerImpl* timer = nullptr;
|
||||
|
||||
if (!mTimers.IsEmpty()) {
|
||||
@ -435,6 +437,7 @@ TimerThread::RemoveTimer(nsTimerImpl* aTimer)
|
||||
int32_t
|
||||
TimerThread::AddTimerInternal(nsTimerImpl* aTimer)
|
||||
{
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
if (mShutdown) {
|
||||
return -1;
|
||||
}
|
||||
@ -463,6 +466,7 @@ TimerThread::AddTimerInternal(nsTimerImpl* aTimer)
|
||||
bool
|
||||
TimerThread::RemoveTimerInternal(nsTimerImpl* aTimer)
|
||||
{
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
if (!mTimers.RemoveElement(aTimer)) {
|
||||
return false;
|
||||
}
|
||||
@ -474,6 +478,10 @@ TimerThread::RemoveTimerInternal(nsTimerImpl* aTimer)
|
||||
void
|
||||
TimerThread::ReleaseTimerInternal(nsTimerImpl* aTimer)
|
||||
{
|
||||
if (!mShutdown) {
|
||||
// copied to a local array before releasing in shutdown
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
}
|
||||
// Order is crucial here -- see nsTimerImpl::Release.
|
||||
aTimer->mArmed = false;
|
||||
NS_RELEASE(aTimer);
|
||||
@ -482,22 +490,40 @@ TimerThread::ReleaseTimerInternal(nsTimerImpl* aTimer)
|
||||
void
|
||||
TimerThread::DoBeforeSleep()
|
||||
{
|
||||
// Mainthread
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mLastTimerEventLoopRun = TimeStamp::Now();
|
||||
mSleeping = true;
|
||||
}
|
||||
|
||||
// Note: wake may be notified without preceding sleep notification
|
||||
void
|
||||
TimerThread::DoAfterSleep()
|
||||
{
|
||||
mSleeping = true; // wake may be notified without preceding sleep notification
|
||||
// Mainthread
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
// an over-estimate of time slept, usually small
|
||||
TimeDuration slept = now - mLastTimerEventLoopRun;
|
||||
|
||||
// Adjust all old timers to expire roughly similar times in the future
|
||||
// compared to when we went to sleep, by adding the time we slept to the
|
||||
// target time. It's slightly possible a few will end up slightly in the
|
||||
// past and fire immediately, but ordering should be preserved. All
|
||||
// timers retain the exact same order (and relative times) as before
|
||||
// going to sleep.
|
||||
for (uint32_t i = 0; i < mTimers.Length(); i ++) {
|
||||
nsTimerImpl* timer = mTimers[i];
|
||||
// get and set the delay to cause its timeout to be recomputed
|
||||
uint32_t delay;
|
||||
timer->GetDelay(&delay);
|
||||
timer->SetDelay(delay);
|
||||
timer->mTimeout += slept;
|
||||
}
|
||||
|
||||
mSleeping = false;
|
||||
mLastTimerEventLoopRun = now;
|
||||
|
||||
// Wake up the timer thread to process the updated array
|
||||
mNotified = true;
|
||||
mMonitor.Notify();
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,7 +61,7 @@ private:
|
||||
mozilla::Atomic<bool> mInitInProgress;
|
||||
bool mInitialized;
|
||||
|
||||
// These two internal helper methods must be called while mLock is held.
|
||||
// These two internal helper methods must be called while mMonitor is held.
|
||||
// AddTimerInternal returns the position where the timer was added in the
|
||||
// list, or -1 if it failed.
|
||||
int32_t AddTimerInternal(nsTimerImpl* aTimer);
|
||||
@ -75,6 +75,7 @@ private:
|
||||
bool mWaiting;
|
||||
bool mNotified;
|
||||
bool mSleeping;
|
||||
TimeStamp mLastTimerEventLoopRun;
|
||||
|
||||
nsTArray<nsTimerImpl*> mTimers;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user