зеркало из https://github.com/mozilla/gecko-dev.git
Bug 844323 - Part 1: Move process preallocation logic out of ContentParent and into a new file, PreallocatedProcessManager. r=bent
Also make the PreallocatedProcessManager respond to pref changes. This allows us to write a test involving the preallocated process. Making this change was the main motivation for this patch; I moved the logic out of ContentParent because with the pref-watching code it was becoming unweildy.
This commit is contained in:
Родитель
d5a4a10ea7
Коммит
c73b99561e
|
@ -80,6 +80,8 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "nsToolkitCompsCID.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "PreallocatedProcessManager.h"
|
||||
#include "ProcessPriorityManager.h"
|
||||
#include "SandboxHal.h"
|
||||
#include "StructuredCloneUtils.h"
|
||||
#include "TabParent.h"
|
||||
|
@ -197,6 +199,7 @@ MemoryReportRequestParent::~MemoryReportRequestParent()
|
|||
nsDataHashtable<nsStringHashKey, ContentParent*>* ContentParent::sAppContentParents;
|
||||
nsTArray<ContentParent*>* ContentParent::sNonAppContentParents;
|
||||
nsTArray<ContentParent*>* ContentParent::sPrivateContent;
|
||||
LinkedList<ContentParent> ContentParent::sContentParents;
|
||||
|
||||
// This is true when subprocess launching is enabled. This is the
|
||||
// case between StartUp() and ShutDown() or JoinAllSubprocesses().
|
||||
|
@ -205,60 +208,27 @@ static bool sCanLaunchSubprocesses;
|
|||
// The first content child has ID 1, so the chrome process can have ID 0.
|
||||
static uint64_t gContentChildID = 1;
|
||||
|
||||
// Try to keep an app process always preallocated, to get
|
||||
// initialization off the critical path of app startup.
|
||||
static bool sKeepAppProcessPreallocated;
|
||||
static StaticRefPtr<ContentParent> sPreallocatedAppProcess;
|
||||
static CancelableTask* sPreallocateAppProcessTask;
|
||||
// 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.
|
||||
static int sPreallocateDelayMs;
|
||||
// We want the prelaunched process to know that it's for apps, but not
|
||||
// actually for any app in particular. Use a magic manifest URL.
|
||||
// Can't be a static constant.
|
||||
#define MAGIC_PREALLOCATED_APP_MANIFEST_URL NS_LITERAL_STRING("{{template}}")
|
||||
|
||||
/*static*/ void
|
||||
// PreallocateAppProcess is called by the PreallocatedProcessManager.
|
||||
// ContentParent then takes this process back within
|
||||
// MaybeTakePreallocatedAppProcess.
|
||||
|
||||
/*static*/ already_AddRefed<ContentParent>
|
||||
ContentParent::PreallocateAppProcess()
|
||||
{
|
||||
MOZ_ASSERT(!sPreallocatedAppProcess);
|
||||
|
||||
if (sPreallocateAppProcessTask) {
|
||||
// We were called directly while a delayed task was scheduled.
|
||||
sPreallocateAppProcessTask->Cancel();
|
||||
sPreallocateAppProcessTask = nullptr;
|
||||
}
|
||||
|
||||
sPreallocatedAppProcess =
|
||||
nsRefPtr<ContentParent> process =
|
||||
new ContentParent(MAGIC_PREALLOCATED_APP_MANIFEST_URL,
|
||||
/*isBrowserElement=*/false,
|
||||
// Final privileges are set when we
|
||||
// transform into our app.
|
||||
base::PRIVILEGES_INHERIT,
|
||||
PROCESS_PRIORITY_BACKGROUND);
|
||||
sPreallocatedAppProcess->Init();
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
ContentParent::DelayedPreallocateAppProcess()
|
||||
{
|
||||
sPreallocateAppProcessTask = nullptr;
|
||||
if (!sPreallocatedAppProcess) {
|
||||
PreallocateAppProcess();
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
ContentParent::ScheduleDelayedPreallocateAppProcess()
|
||||
{
|
||||
if (!sKeepAppProcessPreallocated || sPreallocateAppProcessTask) {
|
||||
return;
|
||||
}
|
||||
sPreallocateAppProcessTask =
|
||||
NewRunnableFunction(DelayedPreallocateAppProcess);
|
||||
MessageLoop::current()->PostDelayedTask(
|
||||
FROM_HERE, sPreallocateAppProcessTask, sPreallocateDelayMs);
|
||||
process->Init();
|
||||
return process.forget();
|
||||
}
|
||||
|
||||
/*static*/ already_AddRefed<ContentParent>
|
||||
|
@ -266,9 +236,7 @@ ContentParent::MaybeTakePreallocatedAppProcess(const nsAString& aAppManifestURL,
|
|||
ChildPrivileges aPrivs,
|
||||
ProcessPriority aInitialPriority)
|
||||
{
|
||||
nsRefPtr<ContentParent> process = sPreallocatedAppProcess.get();
|
||||
sPreallocatedAppProcess = nullptr;
|
||||
|
||||
nsRefPtr<ContentParent> process = PreallocatedProcessManager::Take();
|
||||
if (!process) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -284,14 +252,6 @@ ContentParent::MaybeTakePreallocatedAppProcess(const nsAString& aAppManifestURL,
|
|||
return process.forget();
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
ContentParent::FirstIdle(void)
|
||||
{
|
||||
// The parent has gone idle for the first time. This would be a good
|
||||
// time to preallocate an app process.
|
||||
ScheduleDelayedPreallocateAppProcess();
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
ContentParent::StartUp()
|
||||
{
|
||||
|
@ -299,22 +259,10 @@ ContentParent::StartUp()
|
|||
return;
|
||||
}
|
||||
|
||||
sKeepAppProcessPreallocated =
|
||||
Preferences::GetBool("dom.ipc.processPrelaunch.enabled", false);
|
||||
if (sKeepAppProcessPreallocated) {
|
||||
ClearOnShutdown(&sPreallocatedAppProcess);
|
||||
|
||||
sPreallocateDelayMs = Preferences::GetUint(
|
||||
"dom.ipc.processPrelaunch.delayMs", 1000);
|
||||
|
||||
MOZ_ASSERT(!sPreallocateAppProcessTask);
|
||||
|
||||
// Let's not slow down the main process initialization. Wait until
|
||||
// the main process goes idle before we preallocate a process
|
||||
MessageLoop::current()->PostIdleTask(FROM_HERE, NewRunnableFunction(FirstIdle));
|
||||
}
|
||||
|
||||
sCanLaunchSubprocesses = true;
|
||||
|
||||
// Try to preallocate a process that we can transform into an app later.
|
||||
PreallocatedProcessManager::AllocateAfterDelay();
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
|
@ -544,30 +492,14 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
|||
return static_cast<TabParent*>(browser);
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
AppendToTArray(const nsAString& aKey, ContentParent* aValue, void* aArray)
|
||||
{
|
||||
nsTArray<ContentParent*> *array =
|
||||
static_cast<nsTArray<ContentParent*>*>(aArray);
|
||||
array->AppendElement(aValue);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::GetAll(nsTArray<ContentParent*>& aArray)
|
||||
{
|
||||
aArray.Clear();
|
||||
|
||||
if (gNonAppContentParents) {
|
||||
aArray.AppendElements(*gNonAppContentParents);
|
||||
}
|
||||
|
||||
if (gAppContentParents) {
|
||||
gAppContentParents->EnumerateRead(&AppendToTArray, &aArray);
|
||||
}
|
||||
|
||||
if (sPreallocatedAppProcess) {
|
||||
aArray.AppendElement(sPreallocatedAppProcess);
|
||||
for (ContentParent* cp = sContentParents.getFirst(); cp;
|
||||
cp = cp->getNext()) {
|
||||
aArray.AppendElement(cp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -814,6 +746,11 @@ ContentParent::MarkAsDead()
|
|||
}
|
||||
|
||||
mIsAlive = false;
|
||||
|
||||
// Remove from sContentParents.
|
||||
if (isInList()) {
|
||||
remove();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -922,10 +859,6 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
|||
#endif
|
||||
}
|
||||
|
||||
if (sPreallocatedAppProcess == this) {
|
||||
sPreallocatedAppProcess = nullptr;
|
||||
}
|
||||
|
||||
mMessageManager->Disconnect();
|
||||
|
||||
// clear the child memory reporters
|
||||
|
@ -1086,6 +1019,9 @@ ContentParent::ContentParent(const nsAString& aAppManifestURL,
|
|||
, mSendPermissionUpdates(false)
|
||||
, mIsForBrowser(aIsForBrowser)
|
||||
{
|
||||
// Insert ourselves into the global linked list of ContentParent objects.
|
||||
sContentParents.insertBack(this);
|
||||
|
||||
// From this point on, NS_WARNING, NS_ASSERTION, etc. should print out the
|
||||
// PID along with the warning.
|
||||
nsDebugImpl::SetMultiprocessMode("Parent");
|
||||
|
@ -1380,11 +1316,11 @@ ContentParent::RecvGetShowPasswordSetting(bool* showPassword)
|
|||
bool
|
||||
ContentParent::RecvFirstIdle()
|
||||
{
|
||||
// When the ContentChild goes idle, it sends us a FirstIdle message
|
||||
// which we use as a good time to prelaunch another process. If we
|
||||
// prelaunch any sooner than this, then we'll be competing with the
|
||||
// When the ContentChild goes idle, it sends us a FirstIdle message which we
|
||||
// use as an indicator that it's a good time to prelaunch another process.
|
||||
// If we prelaunch any sooner than this, then we'll be competing with the
|
||||
// child process and slowing it down.
|
||||
ScheduleDelayedPreallocateAppProcess();
|
||||
PreallocatedProcessManager::AllocateOnIdle();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ class ContentParent : public PContentParent
|
|||
, public nsIThreadObserver
|
||||
, public nsIDOMGeoPositionCallback
|
||||
, public mozilla::dom::ipc::MessageManagerCallback
|
||||
, public mozilla::LinkedListElement<ContentParent>
|
||||
{
|
||||
typedef mozilla::ipc::GeckoChildProcessHost GeckoChildProcessHost;
|
||||
typedef mozilla::ipc::OptionalURIParams OptionalURIParams;
|
||||
|
@ -84,6 +85,11 @@ public:
|
|||
static already_AddRefed<ContentParent>
|
||||
GetNewOrUsed(bool aForBrowserElement = false);
|
||||
|
||||
/**
|
||||
* Create a subprocess suitable for use as a preallocated app process.
|
||||
*/
|
||||
static already_AddRefed<ContentParent> PreallocateAppProcess();
|
||||
|
||||
/**
|
||||
* Get or create a content process for the given TabContext. aFrameElement
|
||||
* should be the frame/iframe element with which this process will
|
||||
|
@ -154,14 +160,11 @@ private:
|
|||
static nsDataHashtable<nsStringHashKey, ContentParent*> *sAppContentParents;
|
||||
static nsTArray<ContentParent*>* sNonAppContentParents;
|
||||
static nsTArray<ContentParent*>* sPrivateContent;
|
||||
static LinkedList<ContentParent> sContentParents;
|
||||
|
||||
static void JoinProcessesIOThread(const nsTArray<ContentParent*>* aProcesses,
|
||||
Monitor* aMonitor, bool* aDone);
|
||||
|
||||
static void PreallocateAppProcess();
|
||||
static void DelayedPreallocateAppProcess();
|
||||
static void ScheduleDelayedPreallocateAppProcess();
|
||||
|
||||
// Take the preallocated process and transform it into a "real" app process,
|
||||
// for the specified manifest URL. If there is no preallocated process (or
|
||||
// if it's dead), this returns false.
|
||||
|
@ -172,8 +175,6 @@ private:
|
|||
|
||||
static hal::ProcessPriority GetInitialProcessPriority(nsIDOMElement* aFrameElement);
|
||||
|
||||
static void FirstIdle();
|
||||
|
||||
// Hide the raw constructor methods since we don't want client code
|
||||
// using them.
|
||||
using PContentParent::SendPBrowserConstructor;
|
||||
|
|
|
@ -24,6 +24,7 @@ CPPSRCS = \
|
|||
CrashReporterParent.cpp \
|
||||
CrashReporterChild.cpp \
|
||||
PermissionMessageUtils.cpp \
|
||||
PreallocatedProcessManager.cpp \
|
||||
ProcessPriorityManager.cpp \
|
||||
StructuredCloneUtils.cpp \
|
||||
TabParent.cpp \
|
||||
|
|
|
@ -0,0 +1,229 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et ft=cpp : */
|
||||
/* 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/dom/ContentParent.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::hal;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* This singleton class implements the static methods on
|
||||
* PreallocatedProcessManager.
|
||||
*/
|
||||
class PreallocatedProcessManagerImpl MOZ_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();
|
||||
DISALLOW_EVIL_CONSTRUCTORS(PreallocatedProcessManagerImpl);
|
||||
|
||||
void Init();
|
||||
|
||||
void RereadPrefs();
|
||||
void Enable();
|
||||
void Disable();
|
||||
|
||||
void ObserveProcessShutdown(nsISupports* aSubject);
|
||||
|
||||
bool mEnabled;
|
||||
nsRefPtr<ContentParent> mPreallocatedAppProcess;
|
||||
};
|
||||
|
||||
/* static */ StaticRefPtr<PreallocatedProcessManagerImpl>
|
||||
PreallocatedProcessManagerImpl::sSingleton;
|
||||
|
||||
/* static */ PreallocatedProcessManagerImpl*
|
||||
PreallocatedProcessManagerImpl::Singleton()
|
||||
{
|
||||
if (!sSingleton) {
|
||||
sSingleton = new PreallocatedProcessManagerImpl();
|
||||
sSingleton->Init();
|
||||
ClearOnShutdown(&sSingleton);
|
||||
}
|
||||
|
||||
return sSingleton;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(PreallocatedProcessManagerImpl, nsIObserver)
|
||||
|
||||
PreallocatedProcessManagerImpl::PreallocatedProcessManagerImpl()
|
||||
: mEnabled(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);
|
||||
}
|
||||
RereadPrefs();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PreallocatedProcessManagerImpl::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const PRUnichar* 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 {
|
||||
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(
|
||||
FROM_HERE,
|
||||
NewRunnableMethod(this, &PreallocatedProcessManagerImpl::AllocateOnIdle),
|
||||
Preferences::GetUint("dom.ipc.processPrelaunch.delayMs", 1000));
|
||||
}
|
||||
|
||||
void
|
||||
PreallocatedProcessManagerImpl::AllocateOnIdle()
|
||||
{
|
||||
if (!mEnabled || mPreallocatedAppProcess) {
|
||||
return;
|
||||
}
|
||||
|
||||
MessageLoop::current()->PostIdleTask(
|
||||
FROM_HERE,
|
||||
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->ShutDown();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/* static */ void
|
||||
PreallocatedProcessManager::AllocateAfterDelay()
|
||||
{
|
||||
PreallocatedProcessManagerImpl::Singleton()->AllocateAfterDelay();
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
PreallocatedProcessManager::AllocateOnIdle()
|
||||
{
|
||||
PreallocatedProcessManagerImpl::Singleton()->AllocateOnIdle();
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
PreallocatedProcessManager::AllocateNow()
|
||||
{
|
||||
PreallocatedProcessManagerImpl::Singleton()->AllocateNow();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<ContentParent>
|
||||
PreallocatedProcessManager::Take()
|
||||
{
|
||||
return PreallocatedProcessManagerImpl::Singleton()->Take();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,90 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et ft=cpp : */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_PreallocatedProcessManager_h
|
||||
#define mozilla_PreallocatedProcessManager_h
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class ContentParent;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class manages a ContentParent that it starts up ahead of any particular
|
||||
* need. You can then call Take() to get this process and use it. Since we
|
||||
* already started it up, it should be ready for use faster than if you'd
|
||||
* created the process when you needed it.
|
||||
*
|
||||
* This class watches the dom.ipc.processPrelaunch.enabled pref. If it changes
|
||||
* from false to true, it preallocates a process. If it changes from true to
|
||||
* false, it kills the preallocated process, if any.
|
||||
*
|
||||
* We don't expect this pref to flip between true and false in production, but
|
||||
* flipping the pref is important for tests.
|
||||
*
|
||||
* The static methods here are implemented by forwarding calls on to a
|
||||
* PreallocatedProcessManagerImpl singleton class, so if you add a new static
|
||||
* method here, you'll need to write a corresponding public method on the
|
||||
* singleton.
|
||||
*/
|
||||
class PreallocatedProcessManager MOZ_FINAL
|
||||
{
|
||||
typedef mozilla::dom::ContentParent ContentParent;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create a process after a delay. We wait for a period of time (specified
|
||||
* by the dom.ipc.processPrelaunch.delayMs pref), then wait for this process
|
||||
* to go idle, then allocate the new process.
|
||||
*
|
||||
* If the dom.ipc.processPrelaunch.enabled pref is false, or if we already
|
||||
* have a preallocated process, this function does nothing.
|
||||
*/
|
||||
static void AllocateAfterDelay();
|
||||
|
||||
/**
|
||||
* Create a process once this process goes idle.
|
||||
*
|
||||
* If the dom.ipc.processPrelaunch.enabled pref is false, or if we already
|
||||
* have a preallocated process, this function does nothing.
|
||||
*/
|
||||
static void AllocateOnIdle();
|
||||
|
||||
/**
|
||||
* Create a process right now.
|
||||
*
|
||||
* If the dom.ipc.processPrelaunch.enabled pref is false, or if we already
|
||||
* have a preallocated process, this function does nothing.
|
||||
*/
|
||||
static void AllocateNow();
|
||||
|
||||
/**
|
||||
* Take the preallocated process, if we have one. If we don't have one, this
|
||||
* returns null.
|
||||
*
|
||||
* If you call Take() twice in a row, the second call is guaranteed to return
|
||||
* null.
|
||||
*
|
||||
* After you Take() the preallocated process, you need to call one of the
|
||||
* Allocate* functions (or change the dom.ipc.processPrelaunch pref from
|
||||
* false to true) before we'll create a new process.
|
||||
*/
|
||||
static already_AddRefed<ContentParent> Take();
|
||||
|
||||
private:
|
||||
PreallocatedProcessManager();
|
||||
DISALLOW_EVIL_CONSTRUCTORS(PreallocatedProcessManager);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // defined mozilla_PreallocatedProcessManager_h
|
|
@ -5,7 +5,7 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/dom/ipc/ProcessPriorityManager.h"
|
||||
#include "mozilla/ProcessPriorityManager.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/Hal.h"
|
||||
|
|
|
@ -35,6 +35,7 @@ EXPORTS.mozilla.dom += [
|
|||
|
||||
EXPORTS.mozilla += [
|
||||
'AppProcessChecker.h',
|
||||
'PreallocatedProcessManager.h',
|
||||
'ProcessPriorityManager.h',
|
||||
]
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче