mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-26 00:57:30 +09:00
Merge remote-tracking branch 'origin/tracking' into custom
This commit is contained in:
commit
35ff27f838
8 changed files with 87 additions and 43 deletions
|
|
@ -12703,41 +12703,22 @@ nsGlobalWindow::SetTimeout(JSContext* aCx, const nsAString& aHandler,
|
||||||
return SetTimeoutOrInterval(aCx, aHandler, aTimeout, false, aError);
|
return SetTimeoutOrInterval(aCx, aHandler, aTimeout, false, aError);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
IsInterval(const Optional<int32_t>& aTimeout, int32_t& aResultTimeout)
|
|
||||||
{
|
|
||||||
if (aTimeout.WasPassed()) {
|
|
||||||
aResultTimeout = aTimeout.Value();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no interval was specified, treat this like a timeout, to avoid setting
|
|
||||||
// an interval of 0 milliseconds.
|
|
||||||
aResultTimeout = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
nsGlobalWindow::SetInterval(JSContext* aCx, Function& aFunction,
|
nsGlobalWindow::SetInterval(JSContext* aCx, Function& aFunction,
|
||||||
const Optional<int32_t>& aTimeout,
|
const int32_t aTimeout,
|
||||||
const Sequence<JS::Value>& aArguments,
|
const Sequence<JS::Value>& aArguments,
|
||||||
ErrorResult& aError)
|
ErrorResult& aError)
|
||||||
{
|
{
|
||||||
int32_t timeout;
|
return SetTimeoutOrInterval(aCx, aFunction, aTimeout, aArguments, true, aError);
|
||||||
bool isInterval = IsInterval(aTimeout, timeout);
|
|
||||||
return SetTimeoutOrInterval(aCx, aFunction, timeout, aArguments, isInterval,
|
|
||||||
aError);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
nsGlobalWindow::SetInterval(JSContext* aCx, const nsAString& aHandler,
|
nsGlobalWindow::SetInterval(JSContext* aCx, const nsAString& aHandler,
|
||||||
const Optional<int32_t>& aTimeout,
|
const int32_t aTimeout,
|
||||||
const Sequence<JS::Value>& /* unused */,
|
const Sequence<JS::Value>& /* unused */,
|
||||||
ErrorResult& aError)
|
ErrorResult& aError)
|
||||||
{
|
{
|
||||||
int32_t timeout;
|
return SetTimeoutOrInterval(aCx, aHandler, aTimeout, true, aError);
|
||||||
bool isInterval = IsInterval(aTimeout, timeout);
|
|
||||||
return SetTimeoutOrInterval(aCx, aHandler, timeout, isInterval, aError);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
||||||
|
|
@ -953,11 +953,11 @@ public:
|
||||||
mozilla::ErrorResult& aError);
|
mozilla::ErrorResult& aError);
|
||||||
void ClearTimeout(int32_t aHandle);
|
void ClearTimeout(int32_t aHandle);
|
||||||
int32_t SetInterval(JSContext* aCx, mozilla::dom::Function& aFunction,
|
int32_t SetInterval(JSContext* aCx, mozilla::dom::Function& aFunction,
|
||||||
const mozilla::dom::Optional<int32_t>& aTimeout,
|
const int32_t aTimeout,
|
||||||
const mozilla::dom::Sequence<JS::Value>& aArguments,
|
const mozilla::dom::Sequence<JS::Value>& aArguments,
|
||||||
mozilla::ErrorResult& aError);
|
mozilla::ErrorResult& aError);
|
||||||
int32_t SetInterval(JSContext* aCx, const nsAString& aHandler,
|
int32_t SetInterval(JSContext* aCx, const nsAString& aHandler,
|
||||||
const mozilla::dom::Optional<int32_t>& aTimeout,
|
const int32_t aTimeout,
|
||||||
const mozilla::dom::Sequence<JS::Value>& /* unused */,
|
const mozilla::dom::Sequence<JS::Value>& /* unused */,
|
||||||
mozilla::ErrorResult& aError);
|
mozilla::ErrorResult& aError);
|
||||||
void ClearInterval(int32_t aHandle);
|
void ClearInterval(int32_t aHandle);
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,9 @@ interface WindowOrWorkerGlobalScope {
|
||||||
long setTimeout(DOMString handler, optional long timeout = 0, any... unused);
|
long setTimeout(DOMString handler, optional long timeout = 0, any... unused);
|
||||||
void clearTimeout(optional long handle = 0);
|
void clearTimeout(optional long handle = 0);
|
||||||
[Throws]
|
[Throws]
|
||||||
long setInterval(Function handler, optional long timeout, any... arguments);
|
long setInterval(Function handler, optional long timeout = 0, any... arguments);
|
||||||
[Throws]
|
[Throws]
|
||||||
long setInterval(DOMString handler, optional long timeout, any... unused);
|
long setInterval(DOMString handler, optional long timeout = 0, any... unused);
|
||||||
void clearInterval(optional long handle = 0);
|
void clearInterval(optional long handle = 0);
|
||||||
|
|
||||||
// microtask queuing
|
// microtask queuing
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,9 @@ const nsIID kDEBUGWorkerEventTargetIID = {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// The number of nested timeouts before we start clamping. HTML says 5.
|
||||||
|
const uint32_t kClampTimeoutNestingLevel = 5u;
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class AutoPtrComparator
|
class AutoPtrComparator
|
||||||
{
|
{
|
||||||
|
|
@ -1956,7 +1959,11 @@ NS_IMPL_QUERY_INTERFACE(WorkerLoadInfo::InterfaceRequestor, nsIInterfaceRequesto
|
||||||
struct WorkerPrivate::TimeoutInfo
|
struct WorkerPrivate::TimeoutInfo
|
||||||
{
|
{
|
||||||
TimeoutInfo()
|
TimeoutInfo()
|
||||||
: mId(0), mIsInterval(false), mCanceled(false)
|
: mId(0)
|
||||||
|
, mNestingLevel(0)
|
||||||
|
, mIsInterval(false)
|
||||||
|
, mCanceled(false)
|
||||||
|
, mOnChromeWorker(false)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(mozilla::dom::workers::WorkerPrivate::TimeoutInfo);
|
MOZ_COUNT_CTOR(mozilla::dom::workers::WorkerPrivate::TimeoutInfo);
|
||||||
}
|
}
|
||||||
|
|
@ -1976,12 +1983,33 @@ struct WorkerPrivate::TimeoutInfo
|
||||||
return mTargetTime < aOther.mTargetTime;
|
return mTargetTime < aOther.mTargetTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AccumulateNestingLevel(const uint32_t& aBaseLevel) {
|
||||||
|
if (aBaseLevel < kClampTimeoutNestingLevel) {
|
||||||
|
mNestingLevel = aBaseLevel + 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mNestingLevel = kClampTimeoutNestingLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CalculateTargetTime() {
|
||||||
|
auto target = mInterval;
|
||||||
|
// Clamp timeout for workers, except chrome workers
|
||||||
|
if (mNestingLevel >= kClampTimeoutNestingLevel && !mOnChromeWorker) {
|
||||||
|
target = TimeDuration::Max(
|
||||||
|
mInterval,
|
||||||
|
TimeDuration::FromMilliseconds(Preferences::GetInt("dom.min_timeout_value")));
|
||||||
|
}
|
||||||
|
mTargetTime = TimeStamp::Now() + target;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIScriptTimeoutHandler> mHandler;
|
nsCOMPtr<nsIScriptTimeoutHandler> mHandler;
|
||||||
mozilla::TimeStamp mTargetTime;
|
mozilla::TimeStamp mTargetTime;
|
||||||
mozilla::TimeDuration mInterval;
|
mozilla::TimeDuration mInterval;
|
||||||
int32_t mId;
|
int32_t mId;
|
||||||
|
uint32_t mNestingLevel;
|
||||||
bool mIsInterval;
|
bool mIsInterval;
|
||||||
bool mCanceled;
|
bool mCanceled;
|
||||||
|
bool mOnChromeWorker;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WorkerJSContextStats final : public JS::RuntimeStats
|
class WorkerJSContextStats final : public JS::RuntimeStats
|
||||||
|
|
@ -4130,6 +4158,7 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
|
||||||
, mMainThreadEventTarget(do_GetMainThread())
|
, mMainThreadEventTarget(do_GetMainThread())
|
||||||
, mErrorHandlerRecursionCount(0)
|
, mErrorHandlerRecursionCount(0)
|
||||||
, mNextTimeoutId(1)
|
, mNextTimeoutId(1)
|
||||||
|
, mCurrentTimerNestingLevel(0)
|
||||||
, mStatus(Pending)
|
, mStatus(Pending)
|
||||||
, mFrozen(false)
|
, mFrozen(false)
|
||||||
, mTimerRunning(false)
|
, mTimerRunning(false)
|
||||||
|
|
@ -6074,8 +6103,10 @@ WorkerPrivate::SetTimeout(JSContext* aCx,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAutoPtr<TimeoutInfo> newInfo(new TimeoutInfo());
|
nsAutoPtr<TimeoutInfo> newInfo(new TimeoutInfo());
|
||||||
|
newInfo->mOnChromeWorker = mIsChromeWorker;
|
||||||
newInfo->mIsInterval = aIsInterval;
|
newInfo->mIsInterval = aIsInterval;
|
||||||
newInfo->mId = timerId;
|
newInfo->mId = timerId;
|
||||||
|
newInfo->AccumulateNestingLevel(this->mCurrentTimerNestingLevel);
|
||||||
|
|
||||||
if (MOZ_UNLIKELY(timerId == INT32_MAX)) {
|
if (MOZ_UNLIKELY(timerId == INT32_MAX)) {
|
||||||
NS_WARNING("Timeout ids overflowed!");
|
NS_WARNING("Timeout ids overflowed!");
|
||||||
|
|
@ -6188,14 +6219,21 @@ WorkerPrivate::RunExpiredTimeouts(JSContext* aCx)
|
||||||
// Guard against recursion.
|
// Guard against recursion.
|
||||||
mRunningExpiredTimeouts = true;
|
mRunningExpiredTimeouts = true;
|
||||||
|
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(data->mCurrentTimerNestingLevel == 0);
|
||||||
|
|
||||||
// Run expired timeouts.
|
// Run expired timeouts.
|
||||||
for (uint32_t index = 0; index < expiredTimeouts.Length(); index++) {
|
for (uint32_t index = 0; index < expiredTimeouts.Length(); index++) {
|
||||||
TimeoutInfo*& info = expiredTimeouts[index];
|
TimeoutInfo*& info = expiredTimeouts[index];
|
||||||
|
AutoRestore<uint32_t> nestingLevel(this->mCurrentTimerNestingLevel);
|
||||||
|
|
||||||
if (info->mCanceled) {
|
if (info->mCanceled) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set current timer nesting level to current running timer handler's
|
||||||
|
// nesting level
|
||||||
|
this->mCurrentTimerNestingLevel = info->mNestingLevel;
|
||||||
|
|
||||||
LOG(TimeoutsLog(), ("Worker %p executing timeout with original delay %f ms.\n",
|
LOG(TimeoutsLog(), ("Worker %p executing timeout with original delay %f ms.\n",
|
||||||
this, info->mInterval.ToMilliseconds()));
|
this, info->mInterval.ToMilliseconds()));
|
||||||
|
|
||||||
|
|
@ -6273,8 +6311,10 @@ WorkerPrivate::RunExpiredTimeouts(JSContext* aCx)
|
||||||
info->mCanceled) {
|
info->mCanceled) {
|
||||||
if (info->mIsInterval && !info->mCanceled) {
|
if (info->mIsInterval && !info->mCanceled) {
|
||||||
// Reschedule intervals.
|
// Reschedule intervals.
|
||||||
info->mTargetTime = info->mTargetTime + info->mInterval;
|
// Reschedule a timeout and, if needed, increase the nesting level.
|
||||||
// Don't resort the list here, we'll do that at the end.
|
info->AccumulateNestingLevel(info->mNestingLevel);
|
||||||
|
info->CalculateTargetTime();
|
||||||
|
// Don't re-sort the list here, we'll do that at the end.
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/AutoRestore.h"
|
||||||
#include "mozilla/CondVar.h"
|
#include "mozilla/CondVar.h"
|
||||||
#include "mozilla/ConsoleReportCollector.h"
|
#include "mozilla/ConsoleReportCollector.h"
|
||||||
#include "mozilla/DOMEventTargetHelper.h"
|
#include "mozilla/DOMEventTargetHelper.h"
|
||||||
|
|
@ -212,6 +213,9 @@ protected:
|
||||||
RefPtr<EventTarget> mEventTarget;
|
RefPtr<EventTarget> mEventTarget;
|
||||||
nsTArray<RefPtr<WorkerRunnable>> mPreStartRunnables;
|
nsTArray<RefPtr<WorkerRunnable>> mPreStartRunnables;
|
||||||
|
|
||||||
|
// True if the worker is used in the UI
|
||||||
|
bool mIsChromeWorker;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WorkerPrivate* mParent;
|
WorkerPrivate* mParent;
|
||||||
nsString mScriptURL;
|
nsString mScriptURL;
|
||||||
|
|
@ -241,7 +245,6 @@ private:
|
||||||
uint32_t mParentWindowPausedDepth;
|
uint32_t mParentWindowPausedDepth;
|
||||||
Status mParentStatus;
|
Status mParentStatus;
|
||||||
bool mParentFrozen;
|
bool mParentFrozen;
|
||||||
bool mIsChromeWorker;
|
|
||||||
bool mMainThreadObjectsForgotten;
|
bool mMainThreadObjectsForgotten;
|
||||||
// mIsSecureContext is set once in our constructor; after that it can be read
|
// mIsSecureContext is set once in our constructor; after that it can be read
|
||||||
// from various threads. We could make this const if we were OK with setting
|
// from various threads. We could make this const if we were OK with setting
|
||||||
|
|
@ -1016,6 +1019,20 @@ class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
|
||||||
uint32_t mErrorHandlerRecursionCount;
|
uint32_t mErrorHandlerRecursionCount;
|
||||||
uint32_t mNextTimeoutId;
|
uint32_t mNextTimeoutId;
|
||||||
Status mStatus;
|
Status mStatus;
|
||||||
|
|
||||||
|
// Tracks the current setTimeout/setInterval nesting level.
|
||||||
|
// When there isn't a TimeoutHandler on the stack, this will be 0.
|
||||||
|
// Whenever setTimeout/setInterval are called, a new TimeoutInfo will be
|
||||||
|
// created with a nesting level one more than the current nesting level,
|
||||||
|
// saturating at the kClampTimeoutNestingLevel.
|
||||||
|
//
|
||||||
|
// When RunExpiredTimeouts is run, it sets this value to the
|
||||||
|
// TimeoutInfo::mNestingLevel for the duration of
|
||||||
|
// the WorkerScriptTimeoutHandler::Call which will explicitly trigger a
|
||||||
|
// microtask checkpoint so that any immediately-resolved promises will
|
||||||
|
// still see the nesting level.
|
||||||
|
uint32_t mCurrentTimerNestingLevel;
|
||||||
|
|
||||||
bool mFrozen;
|
bool mFrozen;
|
||||||
bool mTimerRunning;
|
bool mTimerRunning;
|
||||||
bool mRunningExpiredTimeouts;
|
bool mRunningExpiredTimeouts;
|
||||||
|
|
|
||||||
|
|
@ -299,28 +299,25 @@ WorkerGlobalScope::ClearTimeout(int32_t aHandle)
|
||||||
int32_t
|
int32_t
|
||||||
WorkerGlobalScope::SetInterval(JSContext* aCx,
|
WorkerGlobalScope::SetInterval(JSContext* aCx,
|
||||||
Function& aHandler,
|
Function& aHandler,
|
||||||
const Optional<int32_t>& aTimeout,
|
const int32_t aTimeout,
|
||||||
const Sequence<JS::Value>& aArguments,
|
const Sequence<JS::Value>& aArguments,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||||
|
|
||||||
bool isInterval = aTimeout.WasPassed();
|
|
||||||
int32_t timeout = aTimeout.WasPassed() ? aTimeout.Value() : 0;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIScriptTimeoutHandler> handler =
|
nsCOMPtr<nsIScriptTimeoutHandler> handler =
|
||||||
NS_CreateJSTimeoutHandler(aCx, mWorkerPrivate, aHandler, aArguments, aRv);
|
NS_CreateJSTimeoutHandler(aCx, mWorkerPrivate, aHandler, aArguments, aRv);
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mWorkerPrivate->SetTimeout(aCx, handler, timeout, isInterval, aRv);
|
return mWorkerPrivate->SetTimeout(aCx, handler, aTimeout, true, aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
WorkerGlobalScope::SetInterval(JSContext* aCx,
|
WorkerGlobalScope::SetInterval(JSContext* aCx,
|
||||||
const nsAString& aHandler,
|
const nsAString& aHandler,
|
||||||
const Optional<int32_t>& aTimeout,
|
const int32_t aTimeout,
|
||||||
const Sequence<JS::Value>& /* unused */,
|
const Sequence<JS::Value>& /* unused */,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
|
|
@ -328,12 +325,9 @@ WorkerGlobalScope::SetInterval(JSContext* aCx,
|
||||||
|
|
||||||
Sequence<JS::Value> dummy;
|
Sequence<JS::Value> dummy;
|
||||||
|
|
||||||
bool isInterval = aTimeout.WasPassed();
|
|
||||||
int32_t timeout = aTimeout.WasPassed() ? aTimeout.Value() : 0;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIScriptTimeoutHandler> handler =
|
nsCOMPtr<nsIScriptTimeoutHandler> handler =
|
||||||
NS_CreateJSTimeoutHandler(aCx, mWorkerPrivate, aHandler);
|
NS_CreateJSTimeoutHandler(aCx, mWorkerPrivate, aHandler);
|
||||||
return mWorkerPrivate->SetTimeout(aCx, handler, timeout, isInterval, aRv);
|
return mWorkerPrivate->SetTimeout(aCx, handler, aTimeout, true, aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -132,11 +132,11 @@ public:
|
||||||
ClearTimeout(int32_t aHandle);
|
ClearTimeout(int32_t aHandle);
|
||||||
int32_t
|
int32_t
|
||||||
SetInterval(JSContext* aCx, Function& aHandler,
|
SetInterval(JSContext* aCx, Function& aHandler,
|
||||||
const Optional<int32_t>& aTimeout,
|
const int32_t aTimeout,
|
||||||
const Sequence<JS::Value>& aArguments, ErrorResult& aRv);
|
const Sequence<JS::Value>& aArguments, ErrorResult& aRv);
|
||||||
int32_t
|
int32_t
|
||||||
SetInterval(JSContext* aCx, const nsAString& aHandler,
|
SetInterval(JSContext* aCx, const nsAString& aHandler,
|
||||||
const Optional<int32_t>& aTimeout,
|
const int32_t aTimeout,
|
||||||
const Sequence<JS::Value>& /* unused */, ErrorResult& aRv);
|
const Sequence<JS::Value>& /* unused */, ErrorResult& aRv);
|
||||||
void
|
void
|
||||||
ClearInterval(int32_t aHandle);
|
ClearInterval(int32_t aHandle);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#define mozilla_TimeStamp_h
|
#define mozilla_TimeStamp_h
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <algorithm> // for std::min, std::max
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/FloatingPoint.h"
|
#include "mozilla/FloatingPoint.h"
|
||||||
|
|
@ -173,6 +174,17 @@ public:
|
||||||
|
|
||||||
return FromTicks(ticks);
|
return FromTicks(ticks);
|
||||||
}
|
}
|
||||||
|
static BaseTimeDuration Max(const BaseTimeDuration& aA,
|
||||||
|
const BaseTimeDuration& aB)
|
||||||
|
{
|
||||||
|
return FromTicks(std::max(aA.mValue, aB.mValue));
|
||||||
|
}
|
||||||
|
static BaseTimeDuration Min(const BaseTimeDuration& aA,
|
||||||
|
const BaseTimeDuration& aB)
|
||||||
|
{
|
||||||
|
return FromTicks(std::min(aA.mValue, aB.mValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Block double multiplier (slower, imprecise if long duration) - Bug 853398.
|
// Block double multiplier (slower, imprecise if long duration) - Bug 853398.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue