mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1114345 - Don't pop up slow script dialog after waking up laptop (r=bholley)
This commit is contained in:
parent
7843b2875a
commit
67a97e37f5
@ -1307,7 +1307,18 @@ WatchdogMain(void *arg)
|
||||
// Don't request an interrupt callback unless the current script has
|
||||
// been running long enough that we might show the slow script dialog.
|
||||
// Triggering the callback from off the main thread can be expensive.
|
||||
PRTime usecs = self->MinScriptRunTimeSeconds() * PR_USEC_PER_SEC;
|
||||
|
||||
// We want to avoid showing the slow script dialog if the user's laptop
|
||||
// goes to sleep in the middle of running a script. To ensure this, we
|
||||
// invoke the interrupt callback after only half the timeout has
|
||||
// elapsed. The callback simply records the fact that it was called in
|
||||
// the mSlowScriptSecondHalf flag. Then we wait another (timeout/2)
|
||||
// seconds and invoke the callback again. This time around it sees
|
||||
// mSlowScriptSecondHalf is set and so it shows the slow script
|
||||
// dialog. If the computer is put to sleep during one of the (timeout/2)
|
||||
// periods, the script still has the other (timeout/2) seconds to
|
||||
// finish.
|
||||
PRTime usecs = self->MinScriptRunTimeSeconds() * PR_USEC_PER_SEC / 2;
|
||||
if (manager->IsRuntimeActive() &&
|
||||
manager->TimeSinceLastRuntimeStateChange() >= usecs)
|
||||
{
|
||||
@ -1378,10 +1389,12 @@ XPCJSRuntime::InterruptCallback(JSContext *cx)
|
||||
{
|
||||
XPCJSRuntime *self = XPCJSRuntime::Get();
|
||||
|
||||
// If this is the first time the interrupt callback has fired since we last
|
||||
// returned to the event loop, mark the checkpoint.
|
||||
// Normally we record mSlowScriptCheckpoint when we start to process an
|
||||
// event. However, we can run JS outside of event handlers. This code takes
|
||||
// care of that case.
|
||||
if (self->mSlowScriptCheckpoint.IsNull()) {
|
||||
self->mSlowScriptCheckpoint = TimeStamp::NowLoRes();
|
||||
self->mSlowScriptSecondHalf = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1403,9 +1416,18 @@ XPCJSRuntime::InterruptCallback(JSContext *cx)
|
||||
int32_t limit = Preferences::GetInt(prefName, chrome ? 20 : 10);
|
||||
|
||||
// If there's no limit, or we're within the limit, let it go.
|
||||
if (limit == 0 || duration.ToSeconds() < limit)
|
||||
if (limit == 0 || duration.ToSeconds() < limit / 2.0)
|
||||
return true;
|
||||
|
||||
// In order to guard against time changes or laptops going to sleep, we
|
||||
// don't trigger the slow script warning until (limit/2) seconds have
|
||||
// elapsed twice.
|
||||
if (!self->mSlowScriptSecondHalf) {
|
||||
self->mSlowScriptCheckpoint = TimeStamp::NowLoRes();
|
||||
self->mSlowScriptSecondHalf = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// This has gone on long enough! Time to take action. ;-)
|
||||
//
|
||||
@ -3197,7 +3219,8 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
|
||||
mUnprivilegedJunkScope(this->Runtime(), nullptr),
|
||||
mPrivilegedJunkScope(this->Runtime(), nullptr),
|
||||
mCompilationScope(this->Runtime(), nullptr),
|
||||
mAsyncSnowWhiteFreer(new AsyncFreeSnowWhite())
|
||||
mAsyncSnowWhiteFreer(new AsyncFreeSnowWhite()),
|
||||
mSlowScriptSecondHalf(false)
|
||||
{
|
||||
// these jsids filled in later when we have a JSContext to work with.
|
||||
mStrIDs[0] = JSID_VOID;
|
||||
|
@ -624,8 +624,14 @@ public:
|
||||
|
||||
PRTime GetWatchdogTimestamp(WatchdogTimestampCategory aCategory);
|
||||
|
||||
void OnProcessNextEvent() { mSlowScriptCheckpoint = mozilla::TimeStamp::NowLoRes(); }
|
||||
void OnAfterProcessNextEvent() { mSlowScriptCheckpoint = mozilla::TimeStamp(); }
|
||||
void OnProcessNextEvent() {
|
||||
mSlowScriptCheckpoint = mozilla::TimeStamp::NowLoRes();
|
||||
mSlowScriptSecondHalf = false;
|
||||
}
|
||||
void OnAfterProcessNextEvent() {
|
||||
mSlowScriptCheckpoint = mozilla::TimeStamp();
|
||||
mSlowScriptSecondHalf = false;
|
||||
}
|
||||
|
||||
nsTArray<nsXPCWrappedJS*>& WrappedJSToReleaseArray() { return mWrappedJSToReleaseArray; }
|
||||
|
||||
@ -669,6 +675,23 @@ private:
|
||||
JS::PersistentRootedObject mCompilationScope;
|
||||
nsRefPtr<AsyncFreeSnowWhite> mAsyncSnowWhiteFreer;
|
||||
|
||||
// If we spend too much time running JS code in an event handler, then we
|
||||
// want to show the slow script UI. The timeout T is controlled by prefs. We
|
||||
// invoke the interrupt callback once after T/2 seconds and set
|
||||
// mSlowScriptSecondHalf to true. After another T/2 seconds, we invoke the
|
||||
// interrupt callback again. Since mSlowScriptSecondHalf is now true, it
|
||||
// shows the slow script UI. The reason we invoke the callback twice is to
|
||||
// ensure that putting the computer to sleep while running a script doesn't
|
||||
// cause the UI to be shown. If the laptop goes to sleep during one of the
|
||||
// timeout periods, the script still has the other T/2 seconds to complete
|
||||
// before the slow script UI is shown.
|
||||
bool mSlowScriptSecondHalf;
|
||||
|
||||
// mSlowScriptCheckpoint is set to the time when:
|
||||
// 1. We started processing the current event, or
|
||||
// 2. mSlowScriptSecondHalf was set to true
|
||||
// (whichever comes later). We use it to determine whether the interrupt
|
||||
// callback needs to do anything.
|
||||
mozilla::TimeStamp mSlowScriptCheckpoint;
|
||||
|
||||
friend class Watchdog;
|
||||
|
Loading…
Reference in New Issue
Block a user