diff --git a/dom/base/test/test_frameLoader_switchProcess.html b/dom/base/test/test_frameLoader_switchProcess.html index 1b96d323d7f0..10c27efee57f 100644 --- a/dom/base/test/test_frameLoader_switchProcess.html +++ b/dom/base/test/test_frameLoader_switchProcess.html @@ -68,10 +68,7 @@ } SpecialPowers.pushPrefEnv( - // XXX Set LRUPoolLevels to 2 to avoid breaking priority tests - { "set": [["dom.ipc.processPriorityManager.BACKGROUND.LRUPoolLevels", 2], - ["dom.ipc.processPriorityManager.BACKGROUND_PERCEIVABLE.LRUPoolLevels", 2], - ["dom.ipc.processPriorityManager.testMode", true], + { "set": [["dom.ipc.processPriorityManager.testMode", true], ["dom.ipc.processPriorityManager.enabled", true], ["dom.ipc.tabs.disabled", false], ["dom.ipc.processCount", 3], diff --git a/dom/ipc/ProcessPriorityManager.cpp b/dom/ipc/ProcessPriorityManager.cpp index 76889f5418ff..e937bda6d2bb 100644 --- a/dom/ipc/ProcessPriorityManager.cpp +++ b/dom/ipc/ProcessPriorityManager.cpp @@ -144,6 +144,7 @@ private: class ProcessPriorityManagerImpl final : public nsIObserver , public WakeLockObserver + , public nsSupportsWeakReference { public: /** @@ -154,6 +155,7 @@ public: static void StaticInit(); static bool PrefsEnabled(); + static bool TestMode(); NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER @@ -202,7 +204,16 @@ public: */ void Unfreeze(); + /** + * Call ShutDown before destroying the ProcessPriorityManager because + * WakeLockObserver hols a strong reference to it. + */ + void ShutDown(); + private: + static bool sPrefsEnabled; + static bool sRemoteTabsDisabled; + static bool sTestMode; static bool sPrefListenersRegistered; static bool sInitialized; static bool sFrozen; @@ -288,6 +299,7 @@ public: NS_DECL_NSITIMERCALLBACK virtual void Notify(const WakeLockInformation& aInfo) override; + static void StaticInit(); void Init(); int32_t Pid() const; @@ -318,7 +330,12 @@ public: ProcessPriority CurrentPriority(); ProcessPriority ComputePriority(); - void ScheduleResetPriority(const char* aTimeoutPref); + enum TimeoutPref { + BACKGROUND_PERCEIVABLE_GRACE_PERIOD, + BACKGROUND_GRACE_PERIOD, + }; + + void ScheduleResetPriority(TimeoutPref aTimeoutPref); void ResetPriority(); void ResetPriorityNow(); void SetPriorityNow(ProcessPriority aPriority, uint32_t aLRU = 0); @@ -328,6 +345,9 @@ public: void ShutDown(); private: + static uint32_t sBackgroundPerceivableGracePeriodMS; + static uint32_t sBackgroundGracePeriodMS; + void FireTestOnlyObserverNotification( const char* aTopic, const nsACString& aData = EmptyCString()); @@ -354,26 +374,42 @@ private: }; /* static */ bool ProcessPriorityManagerImpl::sInitialized = false; +/* static */ bool ProcessPriorityManagerImpl::sPrefsEnabled = false; +/* static */ bool ProcessPriorityManagerImpl::sRemoteTabsDisabled = true; +/* static */ bool ProcessPriorityManagerImpl::sTestMode = false; /* static */ bool ProcessPriorityManagerImpl::sPrefListenersRegistered = false; /* static */ bool ProcessPriorityManagerImpl::sFrozen = false; /* static */ StaticRefPtr ProcessPriorityManagerImpl::sSingleton; +/* static */ uint32_t ParticularProcessPriorityManager::sBackgroundPerceivableGracePeriodMS = 0; +/* static */ uint32_t ParticularProcessPriorityManager::sBackgroundGracePeriodMS = 0; NS_IMPL_ISUPPORTS(ProcessPriorityManagerImpl, - nsIObserver); + nsIObserver, + nsISupportsWeakReference); /* static */ void ProcessPriorityManagerImpl::PrefChangedCallback(const char* aPref, void* aClosure) { StaticInit(); + if (!PrefsEnabled() && sSingleton) { + sSingleton->ShutDown(); + sSingleton = nullptr; + sInitialized = false; + } } /* static */ bool ProcessPriorityManagerImpl::PrefsEnabled() { - return Preferences::GetBool("dom.ipc.processPriorityManager.enabled") && - !Preferences::GetBool("dom.ipc.tabs.disabled"); + return sPrefsEnabled && !sRemoteTabsDisabled; +} + +/* static */ bool +ProcessPriorityManagerImpl::TestMode() +{ + return sTestMode; } /* static */ void @@ -389,6 +425,15 @@ ProcessPriorityManagerImpl::StaticInit() return; } + if (!sPrefListenersRegistered) { + Preferences::AddBoolVarCache(&sPrefsEnabled, + "dom.ipc.processPriorityManager.enabled"); + Preferences::AddBoolVarCache(&sRemoteTabsDisabled, + "dom.ipc.tabs.disabled"); + Preferences::AddBoolVarCache(&sTestMode, + "dom.ipc.processPriorityManager.testMode"); + } + // If IPC tabs aren't enabled at startup, don't bother with any of this. if (!PrefsEnabled()) { LOG("InitProcessPriorityManager bailing due to prefs."); @@ -432,6 +477,12 @@ ProcessPriorityManagerImpl::ProcessPriorityManagerImpl() } ProcessPriorityManagerImpl::~ProcessPriorityManagerImpl() +{ + ShutDown(); +} + +void +ProcessPriorityManagerImpl::ShutDown() { UnregisterWakeLockObserver(this); } @@ -448,9 +499,9 @@ ProcessPriorityManagerImpl::Init() nsCOMPtr os = services::GetObserverService(); if (os) { - os->AddObserver(this, "ipc:content-created", /* ownsWeak */ false); - os->AddObserver(this, "ipc:content-shutdown", /* ownsWeak */ false); - os->AddObserver(this, "screen-state-changed", /* ownsWeak */ false); + os->AddObserver(this, "ipc:content-created", /* ownsWeak */ true); + os->AddObserver(this, "ipc:content-shutdown", /* ownsWeak */ true); + os->AddObserver(this, "screen-state-changed", /* ownsWeak */ true); } } @@ -664,6 +715,15 @@ ParticularProcessPriorityManager::ParticularProcessPriorityManager( LOGP("Creating ParticularProcessPriorityManager."); } +void +ParticularProcessPriorityManager::StaticInit() +{ + Preferences::AddUintVarCache(&sBackgroundPerceivableGracePeriodMS, + "dom.ipc.processPriorityManager.backgroundPerceivableGracePeriodMS"); + Preferences::AddUintVarCache(&sBackgroundGracePeriodMS, + "dom.ipc.processPriorityManager.backgroundGracePeriodMS"); +} + void ParticularProcessPriorityManager::Init() { @@ -930,9 +990,9 @@ ParticularProcessPriorityManager::ResetPriority() // can get their next track started, if there is one, before getting // downgraded. if (mPriority == PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE) { - ScheduleResetPriority("backgroundPerceivableGracePeriodMS"); + ScheduleResetPriority(BACKGROUND_PERCEIVABLE_GRACE_PERIOD); } else { - ScheduleResetPriority("backgroundGracePeriodMS"); + ScheduleResetPriority(BACKGROUND_GRACE_PERIOD); } return; } @@ -947,15 +1007,26 @@ ParticularProcessPriorityManager::ResetPriorityNow() } void -ParticularProcessPriorityManager::ScheduleResetPriority(const char* aTimeoutPref) +ParticularProcessPriorityManager::ScheduleResetPriority(TimeoutPref aTimeoutPref) { if (mResetPriorityTimer) { LOGP("ScheduleResetPriority bailing; the timer is already running."); return; } - uint32_t timeout = Preferences::GetUint( - nsPrintfCString("dom.ipc.processPriorityManager.%s", aTimeoutPref).get()); + uint32_t timeout = 0; + switch (aTimeoutPref) { + case BACKGROUND_PERCEIVABLE_GRACE_PERIOD: + timeout = sBackgroundPerceivableGracePeriodMS; + break; + case BACKGROUND_GRACE_PERIOD: + timeout = sBackgroundGracePeriodMS; + break; + default: + MOZ_ASSERT(false, "Unrecognized timeout pref"); + break; + } + LOGP("Scheduling reset timer to fire in %dms.", timeout); mResetPriorityTimer = do_CreateInstance("@mozilla.org/timer;1"); mResetPriorityTimer->InitWithCallback(this, timeout, nsITimer::TYPE_ONE_SHOT); @@ -1134,7 +1205,7 @@ ProcessPriorityManagerImpl::FireTestOnlyObserverNotification( const char* aTopic, const nsACString& aData /* = EmptyCString() */) { - if (!Preferences::GetBool("dom.ipc.processPriorityManager.testMode")) { + if (!TestMode()) { return; } @@ -1153,7 +1224,7 @@ ParticularProcessPriorityManager::FireTestOnlyObserverNotification( const char* aTopic, const char* aData /* = nullptr */ ) { - if (!Preferences::GetBool("dom.ipc.processPriorityManager.testMode")) { + if (!ProcessPriorityManagerImpl::TestMode()) { return; } @@ -1170,7 +1241,7 @@ ParticularProcessPriorityManager::FireTestOnlyObserverNotification( const char* aTopic, const nsACString& aData /* = EmptyCString() */) { - if (!Preferences::GetBool("dom.ipc.processPriorityManager.testMode")) { + if (!ProcessPriorityManagerImpl::TestMode()) { return; } @@ -1381,6 +1452,7 @@ ProcessPriorityManager::Init() { ProcessPriorityManagerImpl::StaticInit(); ProcessPriorityManagerChild::StaticInit(); + ParticularProcessPriorityManager::StaticInit(); } /* static */ void