зеркало из 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 "mozilla/layers/APZThreadUtils.h" // for NewTimerCallback
|
||||
#include "nsComponentManagerUtils.h" // for do_CreateInstance
|
||||
#include "nsITimer.h"
|
||||
#include "base/message_loop.h"
|
||||
|
||||
#define TASK_LOG(...)
|
||||
// #define TASK_LOG(...) printf_stderr("TASK: " __VA_ARGS__)
|
||||
|
@ -23,17 +21,14 @@ TaskThrottler::TaskThrottler(const TimeStamp& aTimeStamp, const TimeDuration& aM
|
|||
, mStartTime(aTimeStamp)
|
||||
, mMaxWait(aMaxWait)
|
||||
, 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()
|
||||
{
|
||||
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
|
||||
|
@ -53,17 +48,9 @@ TaskThrottler::PostTask(const tracked_objects::Location& aLocation,
|
|||
// Make sure the queued task is sent after mMaxWait time elapses,
|
||||
// even if we don't get a TaskComplete() until then.
|
||||
TimeDuration timeout = mMaxWait - TimeSinceLastRequest(aTimeStamp, lock);
|
||||
TimeStamp timeoutTime = mStartTime + mMaxWait;
|
||||
RefPtr<TaskThrottler> refPtrThis = this;
|
||||
mTimer->InitWithCallback(NewTimerCallback(
|
||||
[refPtrThis, timeoutTime]()
|
||||
{
|
||||
MonitorAutoLock lock(refPtrThis->mMonitor);
|
||||
if (refPtrThis->mQueuedTask) {
|
||||
refPtrThis->RunQueuedTask(timeoutTime, lock);
|
||||
}
|
||||
}),
|
||||
timeout.ToMilliseconds(), nsITimer::TYPE_ONE_SHOT);
|
||||
mTimeoutTask = NewRunnableMethod(this, &TaskThrottler::OnTimeout);
|
||||
MessageLoop::current()->PostDelayedTask(FROM_HERE, mTimeoutTask,
|
||||
timeout.ToMilliseconds());
|
||||
return;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
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
|
||||
TaskThrottler::TaskComplete(const TimeStamp& aTimeStamp)
|
||||
{
|
||||
|
@ -88,7 +87,7 @@ TaskThrottler::TaskComplete(const TimeStamp& aTimeStamp)
|
|||
|
||||
if (mQueuedTask) {
|
||||
RunQueuedTask(aTimeStamp, lock);
|
||||
mTimer->Cancel();
|
||||
CancelTimeoutTask(lock);
|
||||
} else {
|
||||
mOutstanding = false;
|
||||
}
|
||||
|
@ -126,7 +125,16 @@ TaskThrottler::CancelPendingTask(const MonitorAutoLock& aProofOfLock)
|
|||
TASK_LOG("%p cancelling task %p\n", this, mQueuedTask.get());
|
||||
mQueuedTask->Cancel();
|
||||
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 "nsTArray.h" // for nsTArray
|
||||
|
||||
class nsITimer;
|
||||
|
||||
namespace tracked_objects {
|
||||
class Location;
|
||||
} // namespace tracked_objects
|
||||
|
@ -102,7 +100,8 @@ private:
|
|||
TimeStamp mStartTime;
|
||||
TimeDuration mMaxWait;
|
||||
RollingMean<TimeDuration, TimeDuration> mMean;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
CancelableTask* mTimeoutTask; // not owned because it's posted to a MessageLoop
|
||||
// which deletes it
|
||||
|
||||
~TaskThrottler();
|
||||
void RunQueuedTask(const TimeStamp& aTimeStamp,
|
||||
|
@ -110,6 +109,8 @@ private:
|
|||
void CancelPendingTask(const MonitorAutoLock& aProofOfLock);
|
||||
TimeDuration TimeSinceLastRequest(const TimeStamp& aTimeStamp,
|
||||
const MonitorAutoLock& aProofOfLock);
|
||||
void OnTimeout();
|
||||
void CancelTimeoutTask(const MonitorAutoLock& aProofOfLock);
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
Загрузка…
Ссылка в новой задаче