зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1231213 - Only spawn Service Workers in non-web-extensions processes that won't imminently shutdown. r=asuth
Differential Revision: https://phabricator.services.mozilla.com/D26176 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
18f1995d4d
Коммит
599888fca4
|
@ -1382,6 +1382,32 @@ RemoteWindowContext::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
void ContentParent::MaybeAsyncSendShutDownMessage() {
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
MOZ_ASSERT(!TryToRecycle());
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
// Calling this below while the lock is acquired will deadlock.
|
||||||
|
bool shouldKeepProcessAlive = ShouldKeepProcessAlive();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto lock = mRemoteWorkerActorData.Lock();
|
||||||
|
MOZ_ASSERT_IF(!lock->mCount, !shouldKeepProcessAlive);
|
||||||
|
|
||||||
|
if (lock->mCount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(!lock->mShutdownStarted);
|
||||||
|
lock->mShutdownStarted = true;
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
}
|
||||||
|
|
||||||
void ContentParent::ShutDownProcess(ShutDownMethod aMethod) {
|
void ContentParent::ShutDownProcess(ShutDownMethod aMethod) {
|
||||||
if (mScriptableHelper) {
|
if (mScriptableHelper) {
|
||||||
static_cast<ScriptableCPInfo*>(mScriptableHelper.get())->ProcessDied();
|
static_cast<ScriptableCPInfo*>(mScriptableHelper.get())->ProcessDied();
|
||||||
|
@ -1726,15 +1752,18 @@ bool ContentParent::TryToRecycle() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContentParent::ShouldKeepProcessAlive() const {
|
bool ContentParent::ShouldKeepProcessAlive() {
|
||||||
if (IsForJSPlugin()) {
|
if (IsForJSPlugin()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have active workers, we need to stay alive.
|
// If we have active workers, we need to stay alive.
|
||||||
if (mRemoteWorkerActors) {
|
{
|
||||||
|
const auto lock = mRemoteWorkerActorData.Lock();
|
||||||
|
if (lock->mCount) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!sBrowserContentParents) {
|
if (!sBrowserContentParents) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1845,11 +1874,7 @@ void ContentParent::NotifyTabDestroyed(const TabId& aTabId,
|
||||||
// us down.
|
// us down.
|
||||||
if (ManagedPBrowserParent().Count() == 1 && !ShouldKeepProcessAlive() &&
|
if (ManagedPBrowserParent().Count() == 1 && !ShouldKeepProcessAlive() &&
|
||||||
!TryToRecycle()) {
|
!TryToRecycle()) {
|
||||||
// In the case of normal shutdown, send a shutdown message to child to
|
MaybeAsyncSendShutDownMessage();
|
||||||
// allow it to perform shutdown tasks.
|
|
||||||
MessageLoop::current()->PostTask(NewRunnableMethod<ShutDownMethod>(
|
|
||||||
"dom::ContentParent::ShutDownProcess", this,
|
|
||||||
&ContentParent::ShutDownProcess, SEND_SHUTDOWN_MESSAGE));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2274,7 +2299,7 @@ ContentParent::ContentParent(ContentParent* aOpener,
|
||||||
mChildID(gContentChildID++),
|
mChildID(gContentChildID++),
|
||||||
mGeolocationWatchID(-1),
|
mGeolocationWatchID(-1),
|
||||||
mJSPluginID(aJSPluginID),
|
mJSPluginID(aJSPluginID),
|
||||||
mRemoteWorkerActors(0),
|
mRemoteWorkerActorData("ContentParent::mRemoteWorkerActorData"),
|
||||||
mNumDestroyingTabs(0),
|
mNumDestroyingTabs(0),
|
||||||
mLifecycleState(LifecycleState::LAUNCHING),
|
mLifecycleState(LifecycleState::LAUNCHING),
|
||||||
mIsForBrowser(!mRemoteType.IsEmpty()),
|
mIsForBrowser(!mRemoteType.IsEmpty()),
|
||||||
|
@ -5909,23 +5934,25 @@ mozilla::ipc::IPCResult ContentParent::RecvRestoreBrowsingContextChildren(
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentParent::RegisterRemoteWorkerActor() { ++mRemoteWorkerActors; }
|
void ContentParent::RegisterRemoteWorkerActor() {
|
||||||
|
auto lock = mRemoteWorkerActorData.Lock();
|
||||||
|
++lock->mCount;
|
||||||
|
}
|
||||||
|
|
||||||
void ContentParent::UnregisterRemoveWorkerActor() {
|
void ContentParent::UnregisterRemoveWorkerActor() {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
if (--mRemoteWorkerActors) {
|
{
|
||||||
|
auto lock = mRemoteWorkerActorData.Lock();
|
||||||
|
if (--lock->mCount) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
|
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
|
||||||
if (!cpm->GetBrowserParentCountByProcessId(ChildID()) &&
|
if (!cpm->GetBrowserParentCountByProcessId(ChildID()) &&
|
||||||
!ShouldKeepProcessAlive() && !TryToRecycle()) {
|
!ShouldKeepProcessAlive() && !TryToRecycle()) {
|
||||||
// In the case of normal shutdown, send a shutdown message to child to
|
MaybeAsyncSendShutDownMessage();
|
||||||
// allow it to perform shutdown tasks.
|
|
||||||
MessageLoop::current()->PostTask(NewRunnableMethod<ShutDownMethod>(
|
|
||||||
"dom::ContentParent::ShutDownProcess", this,
|
|
||||||
&ContentParent::ShutDownProcess, SEND_SHUTDOWN_MESSAGE));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "mozilla/ipc/PParentToChildStreamParent.h"
|
#include "mozilla/ipc/PParentToChildStreamParent.h"
|
||||||
#include "mozilla/ipc/PChildToParentStreamParent.h"
|
#include "mozilla/ipc/PChildToParentStreamParent.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/DataMutex.h"
|
||||||
#include "mozilla/FileUtils.h"
|
#include "mozilla/FileUtils.h"
|
||||||
#include "mozilla/HalTypes.h"
|
#include "mozilla/HalTypes.h"
|
||||||
#include "mozilla/LinkedList.h"
|
#include "mozilla/LinkedList.h"
|
||||||
|
@ -114,6 +115,7 @@ class MemoryReport;
|
||||||
class TabContext;
|
class TabContext;
|
||||||
class GetFilesHelper;
|
class GetFilesHelper;
|
||||||
class MemoryReportRequestHost;
|
class MemoryReportRequestHost;
|
||||||
|
class RemoteWorkerManager;
|
||||||
struct CancelContentJSOptions;
|
struct CancelContentJSOptions;
|
||||||
|
|
||||||
#define NS_CONTENTPARENT_IID \
|
#define NS_CONTENTPARENT_IID \
|
||||||
|
@ -145,6 +147,7 @@ class ContentParent final : public PContentParent,
|
||||||
|
|
||||||
friend class mozilla::PreallocatedProcessManagerImpl;
|
friend class mozilla::PreallocatedProcessManagerImpl;
|
||||||
friend class PContentParent;
|
friend class PContentParent;
|
||||||
|
friend class mozilla::dom::RemoteWorkerManager;
|
||||||
#ifdef FUZZING
|
#ifdef FUZZING
|
||||||
friend class mozilla::ipc::ProtocolFuzzerHelper;
|
friend class mozilla::ipc::ProtocolFuzzerHelper;
|
||||||
#endif
|
#endif
|
||||||
|
@ -748,7 +751,7 @@ class ContentParent final : public PContentParent,
|
||||||
* Decide whether the process should be kept alive even when it would normally
|
* Decide whether the process should be kept alive even when it would normally
|
||||||
* be shut down, for example when all its tabs are closed.
|
* be shut down, for example when all its tabs are closed.
|
||||||
*/
|
*/
|
||||||
bool ShouldKeepProcessAlive() const;
|
bool ShouldKeepProcessAlive();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark this ContentParent as "troubled". This means that it is still alive,
|
* Mark this ContentParent as "troubled". This means that it is still alive,
|
||||||
|
@ -774,6 +777,8 @@ class ContentParent final : public PContentParent,
|
||||||
CLOSE_CHANNEL_WITH_ERROR,
|
CLOSE_CHANNEL_WITH_ERROR,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void MaybeAsyncSendShutDownMessage();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exit the subprocess and vamoose. After this call IsAlive()
|
* Exit the subprocess and vamoose. After this call IsAlive()
|
||||||
* will return false and this ContentParent will not be returned
|
* will return false and this ContentParent will not be returned
|
||||||
|
@ -1236,11 +1241,24 @@ class ContentParent final : public PContentParent,
|
||||||
// timer.
|
// timer.
|
||||||
nsCOMPtr<nsITimer> mForceKillTimer;
|
nsCOMPtr<nsITimer> mForceKillTimer;
|
||||||
|
|
||||||
// Number of active remote workers. This value is increased when a
|
// `mCount` is increased when a RemoteWorkerParent actor is created for this
|
||||||
// RemoteWorkerParent actor is created for this ContentProcess and it is
|
// ContentProcess and it is decreased when the actor is destroyed.
|
||||||
// decreased when the actor is destroyed.
|
//
|
||||||
|
// `mShutdownStarted` is flipped to `true` when a runnable that calls
|
||||||
|
// `ShutDownProcess` is dispatched; it's needed because the corresponding
|
||||||
|
// Content Process may be shutdown if there's no remote worker actors, and
|
||||||
|
// decrementing `mCount` and the call to `ShutDownProcess` are async. So,
|
||||||
|
// when a worker is going to be spawned and we see that `mCount` is 0,
|
||||||
|
// we can decide whether or not to use that process based on the value of
|
||||||
|
// `mShutdownStarted.`
|
||||||
|
//
|
||||||
// It's touched on PBackground thread and on main-thread.
|
// It's touched on PBackground thread and on main-thread.
|
||||||
Atomic<uint32_t> mRemoteWorkerActors;
|
struct RemoteWorkerActorData {
|
||||||
|
uint32_t mCount = 0;
|
||||||
|
bool mShutdownStarted = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
DataMutex<RemoteWorkerActorData> mRemoteWorkerActorData;
|
||||||
|
|
||||||
// How many tabs we're waiting to finish their destruction
|
// How many tabs we're waiting to finish their destruction
|
||||||
// sequence. Precisely, how many BrowserParents have called
|
// sequence. Precisely, how many BrowserParents have called
|
||||||
|
|
|
@ -6,11 +6,19 @@
|
||||||
|
|
||||||
#include "RemoteWorkerManager.h"
|
#include "RemoteWorkerManager.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "mozilla/RefPtr.h"
|
||||||
|
#include "mozilla/ScopeExit.h"
|
||||||
|
#include "mozilla/SystemGroup.h"
|
||||||
#include "mozilla/dom/ContentParent.h"
|
#include "mozilla/dom/ContentParent.h"
|
||||||
#include "mozilla/dom/RemoteWorkerParent.h"
|
#include "mozilla/dom/RemoteWorkerParent.h"
|
||||||
#include "mozilla/ipc/BackgroundParent.h"
|
#include "mozilla/ipc/BackgroundParent.h"
|
||||||
#include "mozilla/ipc/PBackgroundParent.h"
|
#include "mozilla/ipc/PBackgroundParent.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIXULRuntime.h"
|
#include "nsIXULRuntime.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
|
#include "nsThreadUtils.h"
|
||||||
#include "RemoteWorkerServiceParent.h"
|
#include "RemoteWorkerServiceParent.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
@ -25,12 +33,17 @@ namespace {
|
||||||
// actors.
|
// actors.
|
||||||
RemoteWorkerManager* sRemoteWorkerManager;
|
RemoteWorkerManager* sRemoteWorkerManager;
|
||||||
|
|
||||||
|
bool IsServiceWorker(const RemoteWorkerData& aData) {
|
||||||
|
return aData.serviceWorkerData().type() ==
|
||||||
|
OptionalServiceWorkerData::TServiceWorkerData;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
already_AddRefed<RemoteWorkerManager> RemoteWorkerManager::GetOrCreate() {
|
already_AddRefed<RemoteWorkerManager> RemoteWorkerManager::GetOrCreate() {
|
||||||
|
AssertIsInMainProcess();
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
|
||||||
|
|
||||||
if (!sRemoteWorkerManager) {
|
if (!sRemoteWorkerManager) {
|
||||||
sRemoteWorkerManager = new RemoteWorkerManager();
|
sRemoteWorkerManager = new RemoteWorkerManager();
|
||||||
|
@ -41,21 +54,21 @@ already_AddRefed<RemoteWorkerManager> RemoteWorkerManager::GetOrCreate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteWorkerManager::RemoteWorkerManager() : mParentActor(nullptr) {
|
RemoteWorkerManager::RemoteWorkerManager() : mParentActor(nullptr) {
|
||||||
|
AssertIsInMainProcess();
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
|
||||||
MOZ_ASSERT(!sRemoteWorkerManager);
|
MOZ_ASSERT(!sRemoteWorkerManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteWorkerManager::~RemoteWorkerManager() {
|
RemoteWorkerManager::~RemoteWorkerManager() {
|
||||||
|
AssertIsInMainProcess();
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
|
||||||
MOZ_ASSERT(sRemoteWorkerManager == this);
|
MOZ_ASSERT(sRemoteWorkerManager == this);
|
||||||
sRemoteWorkerManager = nullptr;
|
sRemoteWorkerManager = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteWorkerManager::RegisterActor(RemoteWorkerServiceParent* aActor) {
|
void RemoteWorkerManager::RegisterActor(RemoteWorkerServiceParent* aActor) {
|
||||||
|
AssertIsInMainProcess();
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
|
||||||
MOZ_ASSERT(aActor);
|
MOZ_ASSERT(aActor);
|
||||||
|
|
||||||
if (!BackgroundParent::IsOtherProcessActor(aActor->Manager())) {
|
if (!BackgroundParent::IsOtherProcessActor(aActor->Manager())) {
|
||||||
|
@ -83,8 +96,8 @@ void RemoteWorkerManager::RegisterActor(RemoteWorkerServiceParent* aActor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteWorkerManager::UnregisterActor(RemoteWorkerServiceParent* aActor) {
|
void RemoteWorkerManager::UnregisterActor(RemoteWorkerServiceParent* aActor) {
|
||||||
|
AssertIsInMainProcess();
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
|
||||||
MOZ_ASSERT(aActor);
|
MOZ_ASSERT(aActor);
|
||||||
|
|
||||||
if (aActor == mParentActor) {
|
if (aActor == mParentActor) {
|
||||||
|
@ -98,8 +111,8 @@ void RemoteWorkerManager::UnregisterActor(RemoteWorkerServiceParent* aActor) {
|
||||||
void RemoteWorkerManager::Launch(RemoteWorkerController* aController,
|
void RemoteWorkerManager::Launch(RemoteWorkerController* aController,
|
||||||
const RemoteWorkerData& aData,
|
const RemoteWorkerData& aData,
|
||||||
base::ProcessId aProcessId) {
|
base::ProcessId aProcessId) {
|
||||||
|
AssertIsInMainProcess();
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
|
||||||
|
|
||||||
RemoteWorkerServiceParent* targetActor = SelectTargetActor(aData, aProcessId);
|
RemoteWorkerServiceParent* targetActor = SelectTargetActor(aData, aProcessId);
|
||||||
|
|
||||||
|
@ -120,14 +133,20 @@ void RemoteWorkerManager::Launch(RemoteWorkerController* aController,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchInternal(aController, targetActor, aData);
|
/**
|
||||||
|
* If a target actor for a Service Worker has been selected, the actor has
|
||||||
|
* already been registered with the corresponding ContentParent (see
|
||||||
|
* `SelectTargetActorForServiceWorker()`).
|
||||||
|
*/
|
||||||
|
LaunchInternal(aController, targetActor, aData, IsServiceWorker(aData));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteWorkerManager::LaunchInternal(
|
void RemoteWorkerManager::LaunchInternal(
|
||||||
RemoteWorkerController* aController,
|
RemoteWorkerController* aController,
|
||||||
RemoteWorkerServiceParent* aTargetActor, const RemoteWorkerData& aData) {
|
RemoteWorkerServiceParent* aTargetActor, const RemoteWorkerData& aData,
|
||||||
|
bool aRemoteWorkerAlreadyRegistered) {
|
||||||
|
AssertIsInMainProcess();
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
|
||||||
MOZ_ASSERT(aController);
|
MOZ_ASSERT(aController);
|
||||||
MOZ_ASSERT(aTargetActor);
|
MOZ_ASSERT(aTargetActor);
|
||||||
MOZ_ASSERT(aTargetActor == mParentActor ||
|
MOZ_ASSERT(aTargetActor == mParentActor ||
|
||||||
|
@ -140,7 +159,7 @@ void RemoteWorkerManager::LaunchInternal(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
workerActor->Initialize();
|
workerActor->Initialize(aRemoteWorkerAlreadyRegistered);
|
||||||
|
|
||||||
// This makes the link better the 2 actors.
|
// This makes the link better the 2 actors.
|
||||||
aController->SetWorkerActor(workerActor);
|
aController->SetWorkerActor(workerActor);
|
||||||
|
@ -157,10 +176,75 @@ void RemoteWorkerManager::AsyncCreationFailed(
|
||||||
NS_DispatchToCurrentThread(r.forget());
|
NS_DispatchToCurrentThread(r.forget());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service Workers can spawn even when their registering page/script isn't
|
||||||
|
* active (e.g. push notifications), so we don't attempt to spawn the worker
|
||||||
|
* in its registering script's process. We search linearly and choose the
|
||||||
|
* search's starting position randomly.
|
||||||
|
*
|
||||||
|
* Spawning the workers in a random process makes the process selection criteria
|
||||||
|
* a little tricky, as a candidate process may imminently shutdown due to a
|
||||||
|
* remove worker actor unregistering
|
||||||
|
* (see `ContentParent::UnregisterRemoveWorkerActor`).
|
||||||
|
*
|
||||||
|
* In `ContentParent::MaybeAsyncSendShutDownMessage` we only dispatch a runnable
|
||||||
|
* to call `ContentParent::ShutDownProcess` if there are no registered remote
|
||||||
|
* worker actors, and we ensure that the check for the number of registered
|
||||||
|
* actors and the dispatching of the runnable are atomic. That happens on the
|
||||||
|
* main thread, so here on the background thread, while
|
||||||
|
* `ContentParent::mRemoteWorkerActorData` is locked, if `mCount` > 0, we can
|
||||||
|
* register a remote worker actor "early" and guarantee that the corresponding
|
||||||
|
* content process will not shutdown.
|
||||||
|
*/
|
||||||
|
RemoteWorkerServiceParent*
|
||||||
|
RemoteWorkerManager::SelectTargetActorForServiceWorker() const {
|
||||||
|
AssertIsInMainProcess();
|
||||||
|
AssertIsOnBackgroundThread();
|
||||||
|
MOZ_ASSERT(!mChildActors.IsEmpty());
|
||||||
|
|
||||||
|
nsTArray<RefPtr<ContentParent>> contentParents;
|
||||||
|
|
||||||
|
auto scopeExit = MakeScopeExit([&] {
|
||||||
|
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||||
|
__func__,
|
||||||
|
[doomed = std::move(contentParents)]() mutable { doomed.Clear(); });
|
||||||
|
|
||||||
|
SystemGroup::Dispatch(TaskCategory::Other, r.forget());
|
||||||
|
});
|
||||||
|
|
||||||
|
uint32_t random = uint32_t(rand() % mChildActors.Length());
|
||||||
|
uint32_t i = random;
|
||||||
|
|
||||||
|
do {
|
||||||
|
auto actor = mChildActors[i];
|
||||||
|
PBackgroundParent* bgParent = actor->Manager();
|
||||||
|
MOZ_ASSERT(bgParent);
|
||||||
|
|
||||||
|
RefPtr<ContentParent> contentParent =
|
||||||
|
BackgroundParent::GetContentParent(bgParent);
|
||||||
|
|
||||||
|
auto scopeExit = MakeScopeExit(
|
||||||
|
[&] { contentParents.AppendElement(std::move(contentParent)); });
|
||||||
|
|
||||||
|
if (contentParent->GetRemoteType().EqualsLiteral(DEFAULT_REMOTE_TYPE)) {
|
||||||
|
auto lock = contentParent->mRemoteWorkerActorData.Lock();
|
||||||
|
|
||||||
|
if (lock->mCount || !lock->mShutdownStarted) {
|
||||||
|
++lock->mCount;
|
||||||
|
return actor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i = (i + 1) % mChildActors.Length();
|
||||||
|
} while (i != random);
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
RemoteWorkerServiceParent* RemoteWorkerManager::SelectTargetActor(
|
RemoteWorkerServiceParent* RemoteWorkerManager::SelectTargetActor(
|
||||||
const RemoteWorkerData& aData, base::ProcessId aProcessId) {
|
const RemoteWorkerData& aData, base::ProcessId aProcessId) {
|
||||||
|
AssertIsInMainProcess();
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
|
||||||
|
|
||||||
// System principal workers should run on the parent process.
|
// System principal workers should run on the parent process.
|
||||||
if (aData.principalInfo().type() == PrincipalInfo::TSystemPrincipalInfo) {
|
if (aData.principalInfo().type() == PrincipalInfo::TSystemPrincipalInfo) {
|
||||||
|
@ -181,6 +265,10 @@ RemoteWorkerServiceParent* RemoteWorkerManager::SelectTargetActor(
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsServiceWorker(aData)) {
|
||||||
|
return SelectTargetActorForServiceWorker();
|
||||||
|
}
|
||||||
|
|
||||||
for (RemoteWorkerServiceParent* actor : mChildActors) {
|
for (RemoteWorkerServiceParent* actor : mChildActors) {
|
||||||
// Let's execute the RemoteWorker on the same process.
|
// Let's execute the RemoteWorker on the same process.
|
||||||
if (actor->OtherPid() == aProcessId) {
|
if (actor->OtherPid() == aProcessId) {
|
||||||
|
@ -194,8 +282,8 @@ RemoteWorkerServiceParent* RemoteWorkerManager::SelectTargetActor(
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteWorkerManager::LaunchNewContentProcess() {
|
void RemoteWorkerManager::LaunchNewContentProcess() {
|
||||||
|
AssertIsInMainProcess();
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
|
||||||
|
|
||||||
// This runnable will spawn a new process if it doesn't exist yet.
|
// This runnable will spawn a new process if it doesn't exist yet.
|
||||||
nsCOMPtr<nsIRunnable> r =
|
nsCOMPtr<nsIRunnable> r =
|
||||||
|
|
|
@ -39,9 +39,12 @@ class RemoteWorkerManager final {
|
||||||
RemoteWorkerServiceParent* SelectTargetActor(const RemoteWorkerData& aData,
|
RemoteWorkerServiceParent* SelectTargetActor(const RemoteWorkerData& aData,
|
||||||
base::ProcessId aProcessId);
|
base::ProcessId aProcessId);
|
||||||
|
|
||||||
|
RemoteWorkerServiceParent* SelectTargetActorForServiceWorker() const;
|
||||||
|
|
||||||
void LaunchInternal(RemoteWorkerController* aController,
|
void LaunchInternal(RemoteWorkerController* aController,
|
||||||
RemoteWorkerServiceParent* aTargetActor,
|
RemoteWorkerServiceParent* aTargetActor,
|
||||||
const RemoteWorkerData& aData);
|
const RemoteWorkerData& aData,
|
||||||
|
bool aRemoteWorkerAlreadyRegistered = false);
|
||||||
|
|
||||||
void LaunchNewContentProcess();
|
void LaunchNewContentProcess();
|
||||||
|
|
||||||
|
|
|
@ -53,12 +53,14 @@ RemoteWorkerParent::~RemoteWorkerParent() {
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteWorkerParent::Initialize() {
|
void RemoteWorkerParent::Initialize(bool aAlreadyRegistered) {
|
||||||
RefPtr<ContentParent> parent = BackgroundParent::GetContentParent(Manager());
|
RefPtr<ContentParent> parent = BackgroundParent::GetContentParent(Manager());
|
||||||
|
|
||||||
// Parent is null if the child actor runs on the parent process.
|
// Parent is null if the child actor runs on the parent process.
|
||||||
if (parent) {
|
if (parent) {
|
||||||
|
if (!aAlreadyRegistered) {
|
||||||
parent->RegisterRemoteWorkerActor();
|
parent->RegisterRemoteWorkerActor();
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIEventTarget> target =
|
nsCOMPtr<nsIEventTarget> target =
|
||||||
SystemGroup::EventTargetFor(TaskCategory::Other);
|
SystemGroup::EventTargetFor(TaskCategory::Other);
|
||||||
|
|
|
@ -22,7 +22,7 @@ class RemoteWorkerParent final : public PRemoteWorkerParent {
|
||||||
|
|
||||||
RemoteWorkerParent();
|
RemoteWorkerParent();
|
||||||
|
|
||||||
void Initialize();
|
void Initialize(bool aAlreadyRegistered = false);
|
||||||
|
|
||||||
void SetController(RemoteWorkerController* aController);
|
void SetController(RemoteWorkerController* aController);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче