Bug 1213273 - Use a chromium Task instead of an nsITimer for the timeout in TaskThrottler. r=mstange

--HG--
extra : rebase_source : 2ddc7714fff1d62aa394332fdafd8c2e5c97b065
extra : source : 00f7757e184487dc77e1be0e07ef7c4e9360e6c3
This commit is contained in:
Botond Ballo 2015-10-16 19:00:15 -04:00
Родитель 65d8ab26f0
Коммит b73c1c58f3
2 изменённых файлов: 34 добавлений и 25 удалений

Просмотреть файл

@ -6,9 +6,7 @@
#include "TaskThrottler.h" #include "TaskThrottler.h"
#include "mozilla/layers/APZThreadUtils.h" // for NewTimerCallback #include "base/message_loop.h"
#include "nsComponentManagerUtils.h" // for do_CreateInstance
#include "nsITimer.h"
#define TASK_LOG(...) #define TASK_LOG(...)
// #define TASK_LOG(...) printf_stderr("TASK: " __VA_ARGS__) // #define TASK_LOG(...) printf_stderr("TASK: " __VA_ARGS__)
@ -23,17 +21,14 @@ TaskThrottler::TaskThrottler(const TimeStamp& aTimeStamp, const TimeDuration& aM
, mStartTime(aTimeStamp) , mStartTime(aTimeStamp)
, mMaxWait(aMaxWait) , mMaxWait(aMaxWait)
, mMean(1) , mMean(1)
, mTimer(do_CreateInstance(NS_TIMER_CONTRACTID)) , mTimeoutTask(nullptr)
{ {
// The TaskThrottler must be created on the main thread (or some nsITimer-
// compatible thread) for the nsITimer to work properly. In particular,
// creating it on the Compositor thread doesn't work.
MOZ_ASSERT(NS_IsMainThread());
} }
TaskThrottler::~TaskThrottler() TaskThrottler::~TaskThrottler()
{ {
mTimer->Cancel(); // The timeout task holds a strong reference to the TaskThrottler, so if the
// TaskThrottler is being destroyed, there's no need to cancel the task.
} }
void void
@ -53,17 +48,9 @@ TaskThrottler::PostTask(const tracked_objects::Location& aLocation,
// Make sure the queued task is sent after mMaxWait time elapses, // Make sure the queued task is sent after mMaxWait time elapses,
// even if we don't get a TaskComplete() until then. // even if we don't get a TaskComplete() until then.
TimeDuration timeout = mMaxWait - TimeSinceLastRequest(aTimeStamp, lock); TimeDuration timeout = mMaxWait - TimeSinceLastRequest(aTimeStamp, lock);
TimeStamp timeoutTime = mStartTime + mMaxWait; mTimeoutTask = NewRunnableMethod(this, &TaskThrottler::OnTimeout);
RefPtr<TaskThrottler> refPtrThis = this; MessageLoop::current()->PostDelayedTask(FROM_HERE, mTimeoutTask,
mTimer->InitWithCallback(NewTimerCallback( timeout.ToMilliseconds());
[refPtrThis, timeoutTime]()
{
MonitorAutoLock lock(refPtrThis->mMonitor);
if (refPtrThis->mQueuedTask) {
refPtrThis->RunQueuedTask(timeoutTime, lock);
}
}),
timeout.ToMilliseconds(), nsITimer::TYPE_ONE_SHOT);
return; return;
} }
// we've been waiting for more than the max-wait limit, so just fall through // we've been waiting for more than the max-wait limit, so just fall through
@ -75,6 +62,18 @@ TaskThrottler::PostTask(const tracked_objects::Location& aLocation,
mOutstanding = true; mOutstanding = true;
} }
void
TaskThrottler::OnTimeout()
{
MonitorAutoLock lock(mMonitor);
if (mQueuedTask) {
RunQueuedTask(TimeStamp::Now(), lock);
}
// The message loop will delete the posted timeout task. Make sure we don't
// keep a dangling pointer to it.
mTimeoutTask = nullptr;
}
void void
TaskThrottler::TaskComplete(const TimeStamp& aTimeStamp) TaskThrottler::TaskComplete(const TimeStamp& aTimeStamp)
{ {
@ -88,7 +87,7 @@ TaskThrottler::TaskComplete(const TimeStamp& aTimeStamp)
if (mQueuedTask) { if (mQueuedTask) {
RunQueuedTask(aTimeStamp, lock); RunQueuedTask(aTimeStamp, lock);
mTimer->Cancel(); CancelTimeoutTask(lock);
} else { } else {
mOutstanding = false; mOutstanding = false;
} }
@ -126,7 +125,16 @@ TaskThrottler::CancelPendingTask(const MonitorAutoLock& aProofOfLock)
TASK_LOG("%p cancelling task %p\n", this, mQueuedTask.get()); TASK_LOG("%p cancelling task %p\n", this, mQueuedTask.get());
mQueuedTask->Cancel(); mQueuedTask->Cancel();
mQueuedTask = nullptr; mQueuedTask = nullptr;
mTimer->Cancel(); CancelTimeoutTask(aProofOfLock);
}
}
void
TaskThrottler::CancelTimeoutTask(const MonitorAutoLock& aProofOfLock)
{
if (mTimeoutTask) {
mTimeoutTask->Cancel();
mTimeoutTask = nullptr; // the MessageLoop will destroy it
} }
} }

Просмотреть файл

@ -18,8 +18,6 @@
#include "nsISupportsImpl.h" // for NS_INLINE_DECL_THREADSAFE_REFCOUNTING #include "nsISupportsImpl.h" // for NS_INLINE_DECL_THREADSAFE_REFCOUNTING
#include "nsTArray.h" // for nsTArray #include "nsTArray.h" // for nsTArray
class nsITimer;
namespace tracked_objects { namespace tracked_objects {
class Location; class Location;
} // namespace tracked_objects } // namespace tracked_objects
@ -102,7 +100,8 @@ private:
TimeStamp mStartTime; TimeStamp mStartTime;
TimeDuration mMaxWait; TimeDuration mMaxWait;
RollingMean<TimeDuration, TimeDuration> mMean; RollingMean<TimeDuration, TimeDuration> mMean;
nsCOMPtr<nsITimer> mTimer; CancelableTask* mTimeoutTask; // not owned because it's posted to a MessageLoop
// which deletes it
~TaskThrottler(); ~TaskThrottler();
void RunQueuedTask(const TimeStamp& aTimeStamp, void RunQueuedTask(const TimeStamp& aTimeStamp,
@ -110,6 +109,8 @@ private:
void CancelPendingTask(const MonitorAutoLock& aProofOfLock); void CancelPendingTask(const MonitorAutoLock& aProofOfLock);
TimeDuration TimeSinceLastRequest(const TimeStamp& aTimeStamp, TimeDuration TimeSinceLastRequest(const TimeStamp& aTimeStamp,
const MonitorAutoLock& aProofOfLock); const MonitorAutoLock& aProofOfLock);
void OnTimeout();
void CancelTimeoutTask(const MonitorAutoLock& aProofOfLock);
}; };
} // namespace layers } // namespace layers