diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /dom/ipc/PreallocatedProcessManager.cpp | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/ipc/PreallocatedProcessManager.cpp')
-rw-r--r-- | dom/ipc/PreallocatedProcessManager.cpp | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/dom/ipc/PreallocatedProcessManager.cpp b/dom/ipc/PreallocatedProcessManager.cpp new file mode 100644 index 000000000..58ff84f21 --- /dev/null +++ b/dom/ipc/PreallocatedProcessManager.cpp @@ -0,0 +1,252 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/PreallocatedProcessManager.h" +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/Preferences.h" +#include "mozilla/Unused.h" +#include "mozilla/dom/ContentParent.h" +#include "mozilla/dom/ScriptSettings.h" +#include "nsIPropertyBag2.h" +#include "ProcessPriorityManager.h" +#include "nsServiceManagerUtils.h" + +// This number is fairly arbitrary ... the intention is to put off +// launching another app process until the last one has finished +// loading its content, to reduce CPU/memory/IO contention. +#define DEFAULT_ALLOCATE_DELAY 1000 + +using namespace mozilla; +using namespace mozilla::hal; +using namespace mozilla::dom; + +namespace { + +/** + * This singleton class implements the static methods on + * PreallocatedProcessManager. + */ +class PreallocatedProcessManagerImpl final + : public nsIObserver +{ +public: + static PreallocatedProcessManagerImpl* Singleton(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + + // See comments on PreallocatedProcessManager for these methods. + void AllocateAfterDelay(); + void AllocateOnIdle(); + void AllocateNow(); + already_AddRefed<ContentParent> Take(); + +private: + static mozilla::StaticRefPtr<PreallocatedProcessManagerImpl> sSingleton; + + PreallocatedProcessManagerImpl(); + ~PreallocatedProcessManagerImpl() {} + DISALLOW_EVIL_CONSTRUCTORS(PreallocatedProcessManagerImpl); + + void Init(); + + void RereadPrefs(); + void Enable(); + void Disable(); + + void ObserveProcessShutdown(nsISupports* aSubject); + + bool mEnabled; + bool mShutdown; + RefPtr<ContentParent> mPreallocatedAppProcess; +}; + +/* static */ StaticRefPtr<PreallocatedProcessManagerImpl> +PreallocatedProcessManagerImpl::sSingleton; + +/* static */ PreallocatedProcessManagerImpl* +PreallocatedProcessManagerImpl::Singleton() +{ + if (!sSingleton) { + sSingleton = new PreallocatedProcessManagerImpl(); + sSingleton->Init(); + ClearOnShutdown(&sSingleton); + } + + return sSingleton; +} + +NS_IMPL_ISUPPORTS(PreallocatedProcessManagerImpl, nsIObserver) + +PreallocatedProcessManagerImpl::PreallocatedProcessManagerImpl() + : + mEnabled(false) + , mShutdown(false) +{} + +void +PreallocatedProcessManagerImpl::Init() +{ + Preferences::AddStrongObserver(this, "dom.ipc.processPrelaunch.enabled"); + nsCOMPtr<nsIObserverService> os = services::GetObserverService(); + if (os) { + os->AddObserver(this, "ipc:content-shutdown", + /* weakRef = */ false); + os->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, + /* weakRef = */ false); + } + { + RereadPrefs(); + } +} + +NS_IMETHODIMP +PreallocatedProcessManagerImpl::Observe(nsISupports* aSubject, + const char* aTopic, + const char16_t* aData) +{ + if (!strcmp("ipc:content-shutdown", aTopic)) { + ObserveProcessShutdown(aSubject); + } else if (!strcmp("nsPref:changed", aTopic)) { + // The only other observer we registered was for our prefs. + RereadPrefs(); + } else if (!strcmp(NS_XPCOM_SHUTDOWN_OBSERVER_ID, aTopic)) { + mShutdown = true; + } else { + MOZ_ASSERT(false); + } + + return NS_OK; +} + +void +PreallocatedProcessManagerImpl::RereadPrefs() +{ + if (Preferences::GetBool("dom.ipc.processPrelaunch.enabled")) { + Enable(); + } else { + Disable(); + } +} + +already_AddRefed<ContentParent> +PreallocatedProcessManagerImpl::Take() +{ + return mPreallocatedAppProcess.forget(); +} + +void +PreallocatedProcessManagerImpl::Enable() +{ + if (mEnabled) { + return; + } + + mEnabled = true; + AllocateAfterDelay(); +} + +void +PreallocatedProcessManagerImpl::AllocateAfterDelay() +{ + if (!mEnabled || mPreallocatedAppProcess) { + return; + } + + MessageLoop::current()->PostDelayedTask( + NewRunnableMethod(this, &PreallocatedProcessManagerImpl::AllocateOnIdle), + Preferences::GetUint("dom.ipc.processPrelaunch.delayMs", + DEFAULT_ALLOCATE_DELAY)); +} + +void +PreallocatedProcessManagerImpl::AllocateOnIdle() +{ + if (!mEnabled || mPreallocatedAppProcess) { + return; + } + + MessageLoop::current()->PostIdleTask(NewRunnableMethod(this, &PreallocatedProcessManagerImpl::AllocateNow)); +} + +void +PreallocatedProcessManagerImpl::AllocateNow() +{ + if (!mEnabled || mPreallocatedAppProcess) { + return; + } + + mPreallocatedAppProcess = ContentParent::PreallocateAppProcess(); +} + +void +PreallocatedProcessManagerImpl::Disable() +{ + if (!mEnabled) { + return; + } + + mEnabled = false; + + if (mPreallocatedAppProcess) { + mPreallocatedAppProcess->Close(); + mPreallocatedAppProcess = nullptr; + } +} + +void +PreallocatedProcessManagerImpl::ObserveProcessShutdown(nsISupports* aSubject) +{ + if (!mPreallocatedAppProcess) { + return; + } + + nsCOMPtr<nsIPropertyBag2> props = do_QueryInterface(aSubject); + NS_ENSURE_TRUE_VOID(props); + + uint64_t childID = CONTENT_PROCESS_ID_UNKNOWN; + props->GetPropertyAsUint64(NS_LITERAL_STRING("childID"), &childID); + NS_ENSURE_TRUE_VOID(childID != CONTENT_PROCESS_ID_UNKNOWN); + + if (childID == mPreallocatedAppProcess->ChildID()) { + mPreallocatedAppProcess = nullptr; + } +} + +inline PreallocatedProcessManagerImpl* GetPPMImpl() +{ + return PreallocatedProcessManagerImpl::Singleton(); +} + +} // namespace + +namespace mozilla { + +/* static */ void +PreallocatedProcessManager::AllocateAfterDelay() +{ + GetPPMImpl()->AllocateAfterDelay(); +} + +/* static */ void +PreallocatedProcessManager::AllocateOnIdle() +{ + GetPPMImpl()->AllocateOnIdle(); +} + +/* static */ void +PreallocatedProcessManager::AllocateNow() +{ + GetPPMImpl()->AllocateNow(); +} + +/* static */ already_AddRefed<ContentParent> +PreallocatedProcessManager::Take() +{ + return GetPPMImpl()->Take(); +} + +} // namespace mozilla |