Bug 1438945 - Part 13: keeping ContentProcess alive. r=asuth,mrbkap

--HG--
extra : rebase_source : 10f03713c5f31f3a41e4f45cde367f5daaa5ebd8
This commit is contained in:
Andrea Marchesini 2018-11-19 15:18:33 -08:00
Родитель b08cb98eb5
Коммит c2d9fd8153
5 изменённых файлов: 116 добавлений и 0 удалений

Просмотреть файл

@ -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);