зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1438945 - Part 13: keeping ContentProcess alive. r=asuth,mrbkap
--HG-- extra : rebase_source : 10f03713c5f31f3a41e4f45cde367f5daaa5ebd8
This commit is contained in:
Родитель
b08cb98eb5
Коммит
c2d9fd8153
|
@ -1862,6 +1862,11 @@ ContentParent::ShouldKeepProcessAlive() const
|
|||
return true;
|
||||
}
|
||||
|
||||
// If we have active workers, we need to stay alive.
|
||||
if (mRemoteWorkerActors) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!sBrowserContentParents) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2385,6 +2390,7 @@ ContentParent::ContentParent(ContentParent* aOpener,
|
|||
, mChildID(gContentChildID++)
|
||||
, mGeolocationWatchID(-1)
|
||||
, mJSPluginID(aJSPluginID)
|
||||
, mRemoteWorkerActors(0)
|
||||
, mNumDestroyingTabs(0)
|
||||
, mIsAvailable(true)
|
||||
, mIsAlive(true)
|
||||
|
@ -6162,3 +6168,32 @@ ContentParent::RecvSetOpenerBrowsingContext(
|
|||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::RegisterRemoteWorkerActor()
|
||||
{
|
||||
++mRemoteWorkerActors;
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::UnregisterRemoveWorkerActor()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (--mRemoteWorkerActors) {
|
||||
return;
|
||||
}
|
||||
|
||||
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
|
||||
if (!cpm->GetTabParentCountByProcessId(ChildID()) &&
|
||||
!ShouldKeepProcessAlive() &&
|
||||
!TryToRecycle()) {
|
||||
// In the case of normal shutdown, send a shutdown message to child to
|
||||
// allow it to perform shutdown tasks.
|
||||
MessageLoop::current()->PostTask(
|
||||
NewRunnableMethod<ShutDownMethod>("dom::ContentParent::ShutDownProcess",
|
||||
this,
|
||||
&ContentParent::ShutDownProcess,
|
||||
SEND_SHUTDOWN_MESSAGE));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -363,6 +363,15 @@ public:
|
|||
const ContentParentId& aCpId,
|
||||
bool aMarkedDestroying);
|
||||
|
||||
// This method can be called on any thread.
|
||||
void
|
||||
RegisterRemoteWorkerActor();
|
||||
|
||||
// This method _must_ be called on main-thread because it can start the
|
||||
// shutting down of the content process.
|
||||
void
|
||||
UnregisterRemoveWorkerActor();
|
||||
|
||||
void ReportChildAlreadyBlocked();
|
||||
|
||||
bool RequestRunToCompletion();
|
||||
|
@ -1300,6 +1309,13 @@ private:
|
|||
// SIGSTOP), are still killed eventually. This task enforces that
|
||||
// timer.
|
||||
nsCOMPtr<nsITimer> mForceKillTimer;
|
||||
|
||||
// Number of active remote workers. This value is increased when a
|
||||
// RemoteWorkerParent actor is created for this ContentProcess and it is
|
||||
// decreased when the actor is destroyed.
|
||||
// It's touched on PBackground thread and on main-thread.
|
||||
Atomic<uint32_t> mRemoteWorkerActors;
|
||||
|
||||
// How many tabs we're waiting to finish their destruction
|
||||
// sequence. Precisely, how many TabParents have called
|
||||
// NotifyTabDestroying() but not called NotifyTabDestroyed().
|
||||
|
|
|
@ -139,6 +139,8 @@ RemoteWorkerManager::LaunchInternal(RemoteWorkerController* aController,
|
|||
return;
|
||||
}
|
||||
|
||||
workerActor->Initialize();
|
||||
|
||||
// This makes the link better the 2 actors.
|
||||
aController->SetWorkerActor(workerActor);
|
||||
workerActor->SetController(aController);
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
|
||||
#include "RemoteWorkerParent.h"
|
||||
#include "RemoteWorkerController.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsProxyRelease.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -15,6 +17,35 @@ using namespace ipc;
|
|||
|
||||
namespace dom {
|
||||
|
||||
namespace {
|
||||
|
||||
class UnregisterActorRunnable final : public Runnable
|
||||
{
|
||||
public:
|
||||
explicit UnregisterActorRunnable(already_AddRefed<ContentParent> aParent)
|
||||
: Runnable("UnregisterActorRunnable")
|
||||
, mContentParent(aParent)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mContentParent->UnregisterRemoveWorkerActor();
|
||||
mContentParent = nullptr;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<ContentParent> mContentParent;
|
||||
};
|
||||
|
||||
} // anonymous
|
||||
|
||||
RemoteWorkerParent::RemoteWorkerParent()
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
@ -27,12 +58,41 @@ RemoteWorkerParent::~RemoteWorkerParent()
|
|||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
}
|
||||
|
||||
void
|
||||
RemoteWorkerParent::Initialize()
|
||||
{
|
||||
RefPtr<ContentParent> parent = BackgroundParent::GetContentParent(Manager());
|
||||
|
||||
// Parent is null if the child actor runs on the parent process.
|
||||
if (parent) {
|
||||
parent->RegisterRemoteWorkerActor();
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target =
|
||||
SystemGroup::EventTargetFor(TaskCategory::Other);
|
||||
|
||||
NS_ProxyRelease("RemoteWorkerParent::Initialize ContentParent",
|
||||
target, parent.forget());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RemoteWorkerParent::ActorDestroy(IProtocol::ActorDestroyReason)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
RefPtr<ContentParent> parent = BackgroundParent::GetContentParent(Manager());
|
||||
|
||||
// Parent is null if the child actor runs on the parent process.
|
||||
if (parent) {
|
||||
RefPtr<UnregisterActorRunnable> r =
|
||||
new UnregisterActorRunnable(parent.forget());
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target =
|
||||
SystemGroup::EventTargetFor(TaskCategory::Other);
|
||||
target->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
mController = nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,9 @@ public:
|
|||
|
||||
RemoteWorkerParent();
|
||||
|
||||
void
|
||||
Initialize();
|
||||
|
||||
void
|
||||
SetController(RemoteWorkerController* aController);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче