121 lines
3.7 KiB
Diff
121 lines
3.7 KiB
Diff
Backported to icecat-31.8 from the upstream esr38 branch.
|
|
|
|
From 1a7eac06fab3b8ffca09936498887f99e233bcba Mon Sep 17 00:00:00 2001
|
|
From: Randell Jesup <rjesup@jesup.org>
|
|
Date: Thu, 9 Jul 2015 20:18:34 -0400
|
|
Subject: [PATCH] Bug 1178890 - Update timer arrays after sleep to account for
|
|
time sleeping. r=bwc, r=froydnj, a=sledru
|
|
|
|
--- icecat-31.8.0/xpcom/threads/TimerThread.cpp.orig 1969-12-31 19:00:00.000000000 -0500
|
|
+++ icecat-31.8.0/xpcom/threads/TimerThread.cpp 2015-08-12 16:38:11.789371171 -0400
|
|
@@ -28,7 +28,8 @@
|
|
mShutdown(false),
|
|
mWaiting(false),
|
|
mNotified(false),
|
|
- mSleeping(false)
|
|
+ mSleeping(false),
|
|
+ mLastTimerEventLoopRun(TimeStamp::Now())
|
|
{
|
|
}
|
|
|
|
@@ -222,6 +223,7 @@
|
|
} else {
|
|
waitFor = PR_INTERVAL_NO_TIMEOUT;
|
|
TimeStamp now = TimeStamp::Now();
|
|
+ mLastTimerEventLoopRun = now;
|
|
nsTimerImpl *timer = nullptr;
|
|
|
|
if (!mTimers.IsEmpty()) {
|
|
@@ -411,6 +413,7 @@
|
|
// This function must be called from within a lock
|
|
int32_t TimerThread::AddTimerInternal(nsTimerImpl *aTimer)
|
|
{
|
|
+ mMonitor.AssertCurrentThreadOwns();
|
|
if (mShutdown)
|
|
return -1;
|
|
|
|
@@ -434,6 +437,7 @@
|
|
|
|
bool TimerThread::RemoveTimerInternal(nsTimerImpl *aTimer)
|
|
{
|
|
+ mMonitor.AssertCurrentThreadOwns();
|
|
if (!mTimers.RemoveElement(aTimer))
|
|
return false;
|
|
|
|
@@ -443,6 +447,10 @@
|
|
|
|
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);
|
|
@@ -450,21 +458,39 @@
|
|
|
|
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();
|
|
}
|
|
|
|
|
|
--- icecat-31.8.0/xpcom/threads/TimerThread.h.orig 1969-12-31 19:00:00.000000000 -0500
|
|
+++ icecat-31.8.0/xpcom/threads/TimerThread.h 2015-08-12 16:38:38.542408062 -0400
|
|
@@ -59,7 +59,7 @@
|
|
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);
|
|
@@ -73,6 +73,7 @@
|
|
bool mWaiting;
|
|
bool mNotified;
|
|
bool mSleeping;
|
|
+ TimeStamp mLastTimerEventLoopRun;
|
|
|
|
nsTArray<nsTimerImpl*> mTimers;
|
|
};
|