зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
65d8ab26f0
Коммит
b73c1c58f3
|
@ -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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче