Bug 508518, Implement nsUITimerCallback with one-shot timer, r=jst, a=blocking

This commit is contained in:
Olli Pettay 2010-11-07 21:07:59 +02:00
parent 14b91d5c34
commit 0a2ef887ea
6 changed files with 57 additions and 12 deletions

View File

@ -290,8 +290,13 @@ nsUITimerCallback::Notify(nsITimer* aTimer)
if ((gMouseOrKeyboardEventCounter == mPreviousCount) || !aTimer) {
gMouseOrKeyboardEventCounter = 0;
obs->NotifyObservers(nsnull, "user-interaction-inactive", nsnull);
if (gUserInteractionTimer) {
gUserInteractionTimer->Cancel();
NS_RELEASE(gUserInteractionTimer);
}
} else {
obs->NotifyObservers(nsnull, "user-interaction-active", nsnull);
nsEventStateManager::UpdateUserActivityTimer();
}
mPreviousCount = gMouseOrKeyboardEventCounter;
return NS_OK;
@ -784,19 +789,30 @@ nsEventStateManager::nsEventStateManager()
{
if (sESMInstanceCount == 0) {
gUserInteractionTimerCallback = new nsUITimerCallback();
if (gUserInteractionTimerCallback) {
if (gUserInteractionTimerCallback)
NS_ADDREF(gUserInteractionTimerCallback);
CallCreateInstance("@mozilla.org/timer;1", &gUserInteractionTimer);
if (gUserInteractionTimer) {
gUserInteractionTimer->InitWithCallback(gUserInteractionTimerCallback,
NS_USER_INTERACTION_INTERVAL,
nsITimer::TYPE_REPEATING_SLACK);
}
}
UpdateUserActivityTimer();
}
++sESMInstanceCount;
}
nsresult
nsEventStateManager::UpdateUserActivityTimer(void)
{
if (!gUserInteractionTimerCallback)
return NS_OK;
if (!gUserInteractionTimer)
CallCreateInstance("@mozilla.org/timer;1", &gUserInteractionTimer);
if (gUserInteractionTimer) {
gUserInteractionTimer->InitWithCallback(gUserInteractionTimerCallback,
NS_USER_INTERACTION_INTERVAL,
nsITimer::TYPE_ONE_SHOT);
}
return NS_OK;
}
NS_IMETHODIMP
nsEventStateManager::Init()
{
@ -1071,6 +1087,7 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
mozilla::services::GetObserverService();
if (obs) {
obs->NotifyObservers(nsnull, "user-interaction-active", nsnull);
UpdateUserActivityTimer();
}
}
++gMouseOrKeyboardEventCounter;

View File

@ -406,6 +406,9 @@ protected:
PRPackedBool m_haveShutdown;
public:
static nsresult UpdateUserActivityTimer(void);
// Array for accesskey support
nsCOMArray<nsIContent> mAccessKeys;

View File

@ -3624,10 +3624,14 @@ nsJSContext::CC(nsICycleCollectorListener *aListener)
sCCSuspectChanges = 0;
// nsCycleCollector_collect() no longer forces a JS garbage collection,
// so we have to do it ourselves here.
nsContentUtils::XPConnect()->GarbageCollect();
if (nsContentUtils::XPConnect()) {
nsContentUtils::XPConnect()->GarbageCollect();
}
sCollectedObjectsCounts = nsCycleCollector_collect(aListener);
sCCSuspectedCount = nsCycleCollector_suspectedCount();
sSavedGCCount = JS_GetGCParameter(nsJSRuntime::sRuntime, JSGC_NUMBER);
if (nsJSRuntime::sRuntime) {
sSavedGCCount = JS_GetGCParameter(nsJSRuntime::sRuntime, JSGC_NUMBER);
}
#ifdef DEBUG_smaug
printf("Collected %u objects, %u suspected objects, took %lldms\n",
sCollectedObjectsCounts, sCCSuspectedCount,
@ -3684,6 +3688,10 @@ nsJSContext::MaybeCC(PRBool aHigherProbability)
if (aHigherProbability ||
sCollectedObjectsCounts > NS_COLLECTED_OBJECTS_LIMIT) {
sDelayedCCollectCount *= NS_PROBABILITY_MULTIPLIER;
} else if (!sUserIsActive && sCCSuspectChanges > NS_MAX_SUSPECT_CHANGES) {
// If user is inactive and there are lots of new suspected objects,
// increase the probability for cycle collection.
sDelayedCCollectCount += (sCCSuspectChanges / NS_MAX_SUSPECT_CHANGES);
}
if (!sGCTimer &&
@ -3707,6 +3715,15 @@ nsJSContext::CCIfUserInactive()
}
}
//static
void
nsJSContext::MaybeCCIfUserInactive()
{
if (!sUserIsActive) {
MaybeCC(PR_FALSE);
}
}
//static
PRBool
nsJSContext::IntervalCC()
@ -3914,7 +3931,7 @@ nsJSRuntime::Startup()
sDelayedCCollectCount = 0;
sCCollectCount = 0;
sUserIsActive = PR_FALSE;
sPreviousCCTime = 0;
sPreviousCCTime = PR_Now();
sCollectedObjectsCounts = 0;
sSavedGCCount = 0;
sCCSuspectChanges = 0;

View File

@ -213,6 +213,8 @@ public:
// Calls IntervalCC() if user is currently inactive, otherwise MaybeCC(PR_TRUE)
static void CCIfUserInactive();
static void MaybeCCIfUserInactive();
static void FireGCTimer(PRBool aLoadInProgress);
protected:

View File

@ -123,6 +123,7 @@ LOCAL_INCLUDES = \
-I$(topsrcdir)/content/svg/content/src \
-I$(topsrcdir)/layout/style \
-I$(topsrcdir)/layout/base \
-I$(topsrcdir)/dom/base \
$(NULL)
EXTRA_DSO_LDOPTS += \

View File

@ -54,7 +54,7 @@
#include "dom_quickstubs.h"
#include "nsNullPrincipal.h"
#include "nsIURI.h"
#include "nsJSEnvironment.h"
#include "jstypedarray.h"
#include "XrayWrapper.h"
@ -2279,6 +2279,11 @@ NS_IMETHODIMP
nsXPConnect::AfterProcessNextEvent(nsIThreadInternal *aThread,
PRUint32 aRecursionDepth)
{
// Call cycle collector occasionally.
if (NS_IsMainThread()) {
nsJSContext::MaybeCCIfUserInactive();
}
return Pop(nsnull);
}