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_ROOT_NATIVE(Timeout, AddRef)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(Timeout, Release)
|
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(Timeout, Release)
|
||||||
|
|
||||||
nsresult
|
namespace {
|
||||||
Timeout::InitTimer(uint32_t aDelay)
|
|
||||||
|
void
|
||||||
|
TimerCallback(nsITimer*, void* aClosure)
|
||||||
{
|
{
|
||||||
return mTimer->InitWithNameableFuncCallback(
|
RefPtr<Timeout> timeout = (Timeout*)aClosure;
|
||||||
nsGlobalWindow::TimerCallback, this, aDelay,
|
timeout->mWindow->RunTimeout(timeout);
|
||||||
nsITimer::TYPE_ONE_SHOT, Timeout::TimerNameCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
|
||||||
void
|
void
|
||||||
Timeout::TimerNameCallback(nsITimer* aTimer, void* aClosure, char* aBuf,
|
TimerNameCallback(nsITimer* aTimer, void* aClosure, char* aBuf, size_t aLen)
|
||||||
size_t aLen)
|
|
||||||
{
|
{
|
||||||
RefPtr<Timeout> timeout = (Timeout*)aClosure;
|
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);
|
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
|
// Return true if this timeout has a refcount of 1. This is used to check
|
||||||
// that dummy_timeout doesn't leak from nsGlobalWindow::RunTimeout.
|
// that dummy_timeout doesn't leak from nsGlobalWindow::RunTimeout.
|
||||||
|
@ -34,13 +34,13 @@ public:
|
|||||||
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(Timeout)
|
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(Timeout)
|
||||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(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 };
|
enum class Reason { eTimeoutOrInterval, eIdleCallbackTimeout };
|
||||||
|
|
||||||
static void TimerNameCallback(nsITimer* aTimer, void* aClosure, char* aBuf,
|
|
||||||
size_t aLen);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bool HasRefCntOne() const;
|
bool HasRefCntOne() const;
|
||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
|
@ -11882,7 +11882,7 @@ nsGlobalWindow::Resume()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = t->InitTimer(delay);
|
nsresult rv = t->InitTimer(GetThrottledEventQueue(), delay);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
t->mTimer = nullptr;
|
t->mTimer = nullptr;
|
||||||
t->remove();
|
t->remove();
|
||||||
@ -12601,7 +12601,7 @@ nsGlobalWindow::SetTimeoutOrInterval(nsITimeoutHandler* aHandler,
|
|||||||
|
|
||||||
RefPtr<Timeout> copy = timeout;
|
RefPtr<Timeout> copy = timeout;
|
||||||
|
|
||||||
rv = timeout->InitTimer(realInterval);
|
rv = timeout->InitTimer(GetThrottledEventQueue(), realInterval);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return 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
|
// 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.
|
// 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)) {
|
if (NS_FAILED(rv)) {
|
||||||
NS_ERROR("Error initializing timer for DOM timeout!");
|
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
|
// firing depth so that we can reentrantly run timeouts
|
||||||
timeout->mFiringDepth = firingDepth;
|
timeout->mFiringDepth = firingDepth;
|
||||||
last_expired_timeout = timeout;
|
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->mFiringDepth = firingDepth;
|
||||||
timeout->Release();
|
timeout->Release();
|
||||||
|
|
||||||
nsresult rv = timeout->InitTimer(delay.ToMilliseconds());
|
nsresult rv = timeout->InitTimer(GetThrottledEventQueue(),
|
||||||
|
delay.ToMilliseconds());
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
NS_WARNING("Error resetting non background timer for DOM timeout!");
|
NS_WARNING("Error resetting non background timer for DOM timeout!");
|
||||||
@ -13256,15 +13272,6 @@ nsGlobalWindow::InsertTimeoutIntoList(Timeout* aTimeout)
|
|||||||
aTimeout->AddRef();
|
aTimeout->AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
|
||||||
void
|
|
||||||
nsGlobalWindow::TimerCallback(nsITimer *aTimer, void *aClosure)
|
|
||||||
{
|
|
||||||
RefPtr<Timeout> timeout = (Timeout*)aClosure;
|
|
||||||
|
|
||||||
timeout->mWindow->RunTimeout(timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// nsGlobalWindow: Helper Functions
|
// nsGlobalWindow: Helper Functions
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
@ -1498,7 +1498,6 @@ public:
|
|||||||
// Insert aTimeout into the list, before all timeouts that would
|
// Insert aTimeout into the list, before all timeouts that would
|
||||||
// fire after it, but no earlier than mTimeoutInsertionPoint, if any.
|
// fire after it, but no earlier than mTimeoutInsertionPoint, if any.
|
||||||
void InsertTimeoutIntoList(mozilla::dom::Timeout* aTimeout);
|
void InsertTimeoutIntoList(mozilla::dom::Timeout* aTimeout);
|
||||||
static void TimerCallback(nsITimer *aTimer, void *aClosure);
|
|
||||||
uint32_t GetTimeoutId(mozilla::dom::Timeout::Reason aReason);
|
uint32_t GetTimeoutId(mozilla::dom::Timeout::Reason aReason);
|
||||||
|
|
||||||
// Helper Functions
|
// Helper Functions
|
||||||
|
Loading…
Reference in New Issue
Block a user