mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
Bug 1300659 P3 Make setTimeout() and setInterval() use the TabGroup ThrottledEventQueue. r=smaug
This commit is contained in:
parent
18e9d9bbcc
commit
595fb0d20b
@ -55,18 +55,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(Timeout, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(Timeout, Release)
|
||||
|
||||
nsresult
|
||||
Timeout::InitTimer(uint32_t aDelay)
|
||||
namespace {
|
||||
|
||||
void
|
||||
TimerCallback(nsITimer*, void* aClosure)
|
||||
{
|
||||
return mTimer->InitWithNameableFuncCallback(
|
||||
nsGlobalWindow::TimerCallback, this, aDelay,
|
||||
nsITimer::TYPE_ONE_SHOT, Timeout::TimerNameCallback);
|
||||
RefPtr<Timeout> timeout = (Timeout*)aClosure;
|
||||
timeout->mWindow->RunTimeout(timeout);
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
Timeout::TimerNameCallback(nsITimer* aTimer, void* aClosure, char* aBuf,
|
||||
size_t aLen)
|
||||
TimerNameCallback(nsITimer* aTimer, void* aClosure, char* aBuf, size_t aLen)
|
||||
{
|
||||
RefPtr<Timeout> timeout = (Timeout*)aClosure;
|
||||
|
||||
@ -76,6 +75,28 @@ Timeout::TimerNameCallback(nsITimer* aTimer, void* aClosure, char* aBuf,
|
||||
snprintf(aBuf, aLen, "[content] %s:%u:%u", filename, lineNum, column);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
nsresult
|
||||
Timeout::InitTimer(nsIEventTarget* aTarget, uint32_t aDelay)
|
||||
{
|
||||
// If the given target does not match the timer's current target
|
||||
// then we need to override it before the Init. Note that GetTarget()
|
||||
// will return the current thread after setting the target to nullptr.
|
||||
// So we need to special case the nullptr target comparison.
|
||||
nsCOMPtr<nsIEventTarget> currentTarget;
|
||||
MOZ_ALWAYS_SUCCEEDS(mTimer->GetTarget(getter_AddRefs(currentTarget)));
|
||||
if ((aTarget && currentTarget != aTarget) ||
|
||||
(!aTarget && currentTarget != NS_GetCurrentThread())) {
|
||||
// Always call Cancel() in case we are re-using a timer. Otherwise
|
||||
// the subsequent SetTarget() may fail.
|
||||
MOZ_ALWAYS_SUCCEEDS(mTimer->Cancel());
|
||||
MOZ_ALWAYS_SUCCEEDS(mTimer->SetTarget(aTarget));
|
||||
}
|
||||
|
||||
return mTimer->InitWithNameableFuncCallback(
|
||||
TimerCallback, this, aDelay, nsITimer::TYPE_ONE_SHOT, TimerNameCallback);
|
||||
}
|
||||
|
||||
// Return true if this timeout has a refcount of 1. This is used to check
|
||||
// that dummy_timeout doesn't leak from nsGlobalWindow::RunTimeout.
|
||||
|
@ -34,13 +34,13 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(Timeout)
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(Timeout)
|
||||
|
||||
nsresult InitTimer(uint32_t aDelay);
|
||||
// The target may be specified to use a particular event queue for the
|
||||
// resulting timer runnable. A nullptr target will result in the
|
||||
// default main thread being used.
|
||||
nsresult InitTimer(nsIEventTarget* aTarget, uint32_t aDelay);
|
||||
|
||||
enum class Reason { eTimeoutOrInterval, eIdleCallbackTimeout };
|
||||
|
||||
static void TimerNameCallback(nsITimer* aTimer, void* aClosure, char* aBuf,
|
||||
size_t aLen);
|
||||
|
||||
#ifdef DEBUG
|
||||
bool HasRefCntOne() const;
|
||||
#endif // DEBUG
|
||||
|
@ -11882,7 +11882,7 @@ nsGlobalWindow::Resume()
|
||||
continue;
|
||||
}
|
||||
|
||||
nsresult rv = t->InitTimer(delay);
|
||||
nsresult rv = t->InitTimer(GetThrottledEventQueue(), delay);
|
||||
if (NS_FAILED(rv)) {
|
||||
t->mTimer = nullptr;
|
||||
t->remove();
|
||||
@ -12601,7 +12601,7 @@ nsGlobalWindow::SetTimeoutOrInterval(nsITimeoutHandler* aHandler,
|
||||
|
||||
RefPtr<Timeout> copy = timeout;
|
||||
|
||||
rv = timeout->InitTimer(realInterval);
|
||||
rv = timeout->InitTimer(GetThrottledEventQueue(), realInterval);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@ -12874,7 +12874,8 @@ nsGlobalWindow::RescheduleTimeout(Timeout* aTimeout, const TimeStamp& now,
|
||||
|
||||
// Reschedule the OS timer. Don't bother returning any error codes if
|
||||
// this fails since the callers of this method don't care about them.
|
||||
nsresult rv = aTimeout->InitTimer(delay.ToMilliseconds());
|
||||
nsresult rv = aTimeout->InitTimer(GetThrottledEventQueue(),
|
||||
delay.ToMilliseconds());
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("Error initializing timer for DOM timeout!");
|
||||
@ -12949,6 +12950,20 @@ nsGlobalWindow::RunTimeout(Timeout* aTimeout)
|
||||
// firing depth so that we can reentrantly run timeouts
|
||||
timeout->mFiringDepth = firingDepth;
|
||||
last_expired_timeout = timeout;
|
||||
|
||||
// Run available timers until we see our target timer. After
|
||||
// that, however, stop coalescing timers so we can yield the
|
||||
// main thread. Further timers that are ready will get picked
|
||||
// up by their own nsITimer runnables when they execute.
|
||||
//
|
||||
// For chrome windows, however, we do coalesce all timers and
|
||||
// do not yield the main thread. This is partly because we
|
||||
// trust chrome windows not to misbehave and partly because a
|
||||
// number of browser chrome tests have races that depend on this
|
||||
// coalescing.
|
||||
if (timeout == aTimeout && !IsChromeWindow()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13167,7 +13182,8 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
|
||||
timeout->mFiringDepth = firingDepth;
|
||||
timeout->Release();
|
||||
|
||||
nsresult rv = timeout->InitTimer(delay.ToMilliseconds());
|
||||
nsresult rv = timeout->InitTimer(GetThrottledEventQueue(),
|
||||
delay.ToMilliseconds());
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Error resetting non background timer for DOM timeout!");
|
||||
@ -13256,15 +13272,6 @@ nsGlobalWindow::InsertTimeoutIntoList(Timeout* aTimeout)
|
||||
aTimeout->AddRef();
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsGlobalWindow::TimerCallback(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
RefPtr<Timeout> timeout = (Timeout*)aClosure;
|
||||
|
||||
timeout->mWindow->RunTimeout(timeout);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsGlobalWindow: Helper Functions
|
||||
//*****************************************************************************
|
||||
|
@ -1498,7 +1498,6 @@ public:
|
||||
// Insert aTimeout into the list, before all timeouts that would
|
||||
// fire after it, but no earlier than mTimeoutInsertionPoint, if any.
|
||||
void InsertTimeoutIntoList(mozilla::dom::Timeout* aTimeout);
|
||||
static void TimerCallback(nsITimer *aTimer, void *aClosure);
|
||||
uint32_t GetTimeoutId(mozilla::dom::Timeout::Reason aReason);
|
||||
|
||||
// Helper Functions
|
||||
|
Loading…
Reference in New Issue
Block a user