Bug 1753424 - Support running multiple UtilityProcess r=nika

Differential Revision: https://phabricator.services.mozilla.com/D139817
This commit is contained in:
Alexandre Lissy 2022-03-26 09:53:47 +00:00
Родитель 6c667ad60a
Коммит baebfcdc76
13 изменённых файлов: 268 добавлений и 127 удалений

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

@ -164,7 +164,8 @@ mozilla::ipc::IPCResult UtilityProcessChild::RecvRequestMemoryReport(
const uint32_t& aGeneration, const bool& aAnonymize,
const bool& aMinimizeMemoryUsage, const Maybe<FileDescriptor>& aDMDFile,
const RequestMemoryReportResolver& aResolver) {
nsPrintfCString processName("Utility (pid %u)", base::GetCurrentProcId());
nsPrintfCString processName("Utility (pid: %u, sandboxingKind: %" PRIu64 ")",
base::GetCurrentProcId(), mSandbox);
mozilla::dom::MemoryReportRequestClient::Start(
aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName,

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

@ -72,9 +72,9 @@ class UtilityProcessHost final : public mozilla::ipc::GeckoChildProcessHost {
// Return the actor for the top-level actor of the process. If the process
// has not connected yet, this returns null.
UtilityProcessParent* GetActor() const {
RefPtr<UtilityProcessParent> GetActor() const {
MOZ_ASSERT(NS_IsMainThread());
return mUtilityProcessParent.get();
return mUtilityProcessParent;
}
bool IsConnected() const {

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

@ -44,7 +44,7 @@ bool UtilityProcessImpl::Init(int aArgc, char* aArgv[]) {
// This checks needs to be kept in sync with SandboxingKind enum living in
// ipc/glue/UtilityProcessSandboxing.h
if (*sandboxingKind < SandboxingKind::GENERIC_UTILITY ||
*sandboxingKind > SandboxingKind::GENERIC_UTILITY) {
*sandboxingKind >= SandboxingKind::COUNT) {
return false;
}

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

@ -54,8 +54,8 @@ UtilityProcessManager::UtilityProcessManager() : mObserver(new Observer(this)) {
}
UtilityProcessManager::~UtilityProcessManager() {
// The Utility process should have already been shut down.
MOZ_ASSERT(!mProcess && !mProcessParent);
// The Utility process should ALL have already been shut down.
MOZ_ASSERT(NoMoreProcesses());
}
NS_IMPL_ISUPPORTS(UtilityProcessManager::Observer, nsIObserver);
@ -80,16 +80,15 @@ void UtilityProcessManager::OnXPCOMShutdown() {
MOZ_ASSERT(NS_IsMainThread());
sXPCOMShutdown = true;
nsContentUtils::UnregisterShutdownObserver(mObserver);
CleanShutdown();
CleanShutdownAllProcesses();
}
void UtilityProcessManager::OnPreferenceChange(const char16_t* aData) {
MOZ_ASSERT(NS_IsMainThread());
if (!mProcess) {
if (NoMoreProcesses()) {
// Process hasn't been launched yet
return;
}
// We know prefs are ASCII here.
NS_LossyConvertUTF16toASCII strData(aData);
@ -100,14 +99,29 @@ void UtilityProcessManager::OnPreferenceChange(const char16_t* aData) {
mozilla::dom::Pref pref(strData, /* isLocked */ false, Nothing(), Nothing());
Preferences::GetPreference(&pref);
if (bool(mProcessParent)) {
MOZ_ASSERT(mQueuedPrefs.IsEmpty());
Unused << mProcessParent->SendPreferenceUpdate(pref);
} else if (IsProcessLaunching()) {
mQueuedPrefs.AppendElement(pref);
for (auto& p : mProcesses) {
if (!p) {
continue;
}
if (p->mProcessParent) {
Unused << p->mProcessParent->SendPreferenceUpdate(pref);
} else if (IsProcessLaunching(p->mSandbox)) {
p->mQueuedPrefs.AppendElement(pref);
}
}
}
RefPtr<UtilityProcessManager::ProcessFields> UtilityProcessManager::GetProcess(
SandboxingKind aSandbox) {
if (!mProcesses[aSandbox]) {
return nullptr;
}
return mProcesses[aSandbox];
}
RefPtr<GenericNonExclusivePromise> UtilityProcessManager::LaunchProcess(
SandboxingKind aSandbox) {
MOZ_ASSERT(NS_IsMainThread());
@ -117,14 +131,20 @@ RefPtr<GenericNonExclusivePromise> UtilityProcessManager::LaunchProcess(
__func__);
}
if (mNumProcessAttempts) {
RefPtr<ProcessFields> p = GetProcess(aSandbox);
if (p && p->mNumProcessAttempts) {
// We failed to start the Utility process earlier, abort now.
return GenericNonExclusivePromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
__func__);
}
if (mLaunchPromise && mProcess) {
return mLaunchPromise;
if (p && p->mLaunchPromise && p->mProcess) {
return p->mLaunchPromise;
}
if (!p) {
p = new ProcessFields(aSandbox);
mProcesses[aSandbox] = p;
}
std::vector<std::string> extraArgs;
@ -133,38 +153,37 @@ RefPtr<GenericNonExclusivePromise> UtilityProcessManager::LaunchProcess(
// The subprocess is launched asynchronously, so we
// wait for the promise to be resolved to acquire the IPDL actor.
mProcess = new UtilityProcessHost(aSandbox, this);
if (!mProcess->Launch(extraArgs)) {
mNumProcessAttempts++;
DestroyProcess();
p->mProcess = new UtilityProcessHost(aSandbox, this);
if (!p->mProcess->Launch(extraArgs)) {
p->mNumProcessAttempts++;
DestroyProcess(aSandbox);
return GenericNonExclusivePromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
__func__);
}
RefPtr<UtilityProcessManager> self = this;
mLaunchPromise = mProcess->LaunchPromise()->Then(
p->mLaunchPromise = p->mProcess->LaunchPromise()->Then(
GetMainThreadSerialEventTarget(), __func__,
[self, aSandbox](bool) {
[self, p, aSandbox](bool) {
if (self->IsShutdown()) {
return GenericNonExclusivePromise::CreateAndReject(
NS_ERROR_NOT_AVAILABLE, __func__);
}
if (self->IsProcessDestroyed()) {
if (self->IsProcessDestroyed(aSandbox)) {
return GenericNonExclusivePromise::CreateAndReject(
NS_ERROR_NOT_AVAILABLE, __func__);
}
self->mProcessParent = self->mProcess->GetActor();
p->mProcessParent = p->mProcess->GetActor();
// Flush any pref updates that happened during
// launch and weren't included in the blobs set
// up in LaunchUtilityProcess.
for (const mozilla::dom::Pref& pref : self->mQueuedPrefs) {
Unused << NS_WARN_IF(
!self->mProcessParent->SendPreferenceUpdate(pref));
for (const mozilla::dom::Pref& pref : p->mQueuedPrefs) {
Unused << NS_WARN_IF(!p->mProcessParent->SendPreferenceUpdate(pref));
}
self->mQueuedPrefs.Clear();
p->mQueuedPrefs.Clear();
CrashReporter::AnnotateCrashReport(
CrashReporter::Annotation::UtilityProcessStatus, "Running"_ns);
@ -175,65 +194,123 @@ RefPtr<GenericNonExclusivePromise> UtilityProcessManager::LaunchProcess(
return GenericNonExclusivePromise::CreateAndResolve(true, __func__);
},
[self](nsresult aError) {
[self, p, aSandbox](nsresult aError) {
if (GetSingleton()) {
self->mNumProcessAttempts++;
self->DestroyProcess();
p->mNumProcessAttempts++;
self->DestroyProcess(aSandbox);
}
return GenericNonExclusivePromise::CreateAndReject(aError, __func__);
});
return mLaunchPromise;
return p->mLaunchPromise;
}
bool UtilityProcessManager::IsProcessLaunching() {
bool UtilityProcessManager::IsProcessLaunching(SandboxingKind aSandbox) {
MOZ_ASSERT(NS_IsMainThread());
return mProcess && !mProcessParent;
RefPtr<ProcessFields> p = GetProcess(aSandbox);
if (!p) {
MOZ_CRASH("Cannot check process launching with no process");
return false;
}
return p->mProcess && !(p->mProcessParent);
}
bool UtilityProcessManager::IsProcessDestroyed() const {
bool UtilityProcessManager::IsProcessDestroyed(SandboxingKind aSandbox) {
MOZ_ASSERT(NS_IsMainThread());
return !mProcessParent && !mProcess;
RefPtr<ProcessFields> p = GetProcess(aSandbox);
if (!p) {
MOZ_CRASH("Cannot check process destroyed with no process");
return false;
}
return !p->mProcess && !p->mProcessParent;
}
void UtilityProcessManager::OnProcessUnexpectedShutdown(
UtilityProcessHost* aHost) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mProcess && mProcess == aHost);
mNumUnexpectedCrashes++;
DestroyProcess();
}
void UtilityProcessManager::CleanShutdown() { DestroyProcess(); }
void UtilityProcessManager::DestroyProcess() {
MOZ_RELEASE_ASSERT(NS_IsMainThread());
mQueuedPrefs.Clear();
if (mObserver) {
Preferences::RemoveObserver(mObserver, "");
for (auto& it : mProcesses) {
if (it && it->mProcess && it->mProcess == aHost) {
it->mNumUnexpectedCrashes++;
DestroyProcess(it->mSandbox);
return;
}
}
mObserver = nullptr;
mProcessParent = nullptr;
sSingleton = nullptr;
MOZ_CRASH(
"Called UtilityProcessManager::OnProcessUnexpectedShutdown with invalid "
"aHost");
}
if (!mProcess) {
void UtilityProcessManager::CleanShutdownAllProcesses() {
for (auto& it : mProcesses) {
if (it) {
DestroyProcess(it->mSandbox);
}
}
}
void UtilityProcessManager::CleanShutdown(SandboxingKind aSandbox) {
DestroyProcess(aSandbox);
}
uint16_t UtilityProcessManager::AliveProcesses() {
uint16_t alive = 0;
for (auto& p : mProcesses) {
if (p != nullptr) {
alive++;
}
}
return alive;
}
bool UtilityProcessManager::NoMoreProcesses() { return AliveProcesses() == 0; }
void UtilityProcessManager::DestroyProcess(SandboxingKind aSandbox) {
MOZ_RELEASE_ASSERT(NS_IsMainThread());
if (AliveProcesses() <= 1) {
if (mObserver) {
Preferences::RemoveObserver(mObserver, "");
}
mObserver = nullptr;
sSingleton = nullptr;
}
RefPtr<ProcessFields> p = GetProcess(aSandbox);
if (!p) {
MOZ_CRASH("Cannot get no ProcessFields");
return;
}
mProcess->Shutdown();
mProcess = nullptr;
p->mQueuedPrefs.Clear();
p->mProcessParent = nullptr;
if (!p->mProcess) {
return;
}
p->mProcess->Shutdown();
p->mProcess = nullptr;
mProcesses[aSandbox] = nullptr;
CrashReporter::AnnotateCrashReport(
CrashReporter::Annotation::UtilityProcessStatus, "Destroyed"_ns);
}
Maybe<base::ProcessId> UtilityProcessManager::ProcessPid() {
Maybe<base::ProcessId> UtilityProcessManager::ProcessPid(
SandboxingKind aSandbox) {
MOZ_ASSERT(NS_IsMainThread());
if (mProcessParent) {
return Some(mProcessParent->OtherPid());
RefPtr<ProcessFields> p = GetProcess(aSandbox);
if (!p) {
return Nothing();
}
if (p->mProcessParent) {
return Some(p->mProcessParent->OtherPid());
}
return Nothing();
}
@ -242,13 +319,17 @@ class UtilityMemoryReporter : public MemoryReportingProcess {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UtilityMemoryReporter, override)
explicit UtilityMemoryReporter(UtilityProcessParent* aParent) {
mParent = aParent;
}
bool IsAlive() const override { return bool(GetParent()); }
bool SendRequestMemoryReport(
const uint32_t& aGeneration, const bool& aAnonymize,
const bool& aMinimizeMemoryUsage,
const Maybe<ipc::FileDescriptor>& aDMDFile) override {
UtilityProcessParent* parent = GetParent();
RefPtr<UtilityProcessParent> parent = GetParent();
if (!parent) {
return false;
}
@ -258,33 +339,24 @@ class UtilityMemoryReporter : public MemoryReportingProcess {
}
int32_t Pid() const override {
if (UtilityProcessParent* parent = GetParent()) {
if (RefPtr<UtilityProcessParent> parent = GetParent()) {
return (int32_t)parent->OtherPid();
}
return 0;
}
private:
UtilityProcessParent* GetParent() const {
if (RefPtr<UtilityProcessManager> utilitypm =
UtilityProcessManager::GetSingleton()) {
if (UtilityProcessParent* parent = utilitypm->GetProcessParent()) {
return parent;
}
}
return nullptr;
}
RefPtr<UtilityProcessParent> GetParent() const { return mParent; }
RefPtr<UtilityProcessParent> mParent = nullptr;
protected:
~UtilityMemoryReporter() = default;
};
RefPtr<MemoryReportingProcess>
UtilityProcessManager::GetProcessMemoryReporter() {
if (!mProcess || !mProcess->IsConnected()) {
return nullptr;
}
return new UtilityMemoryReporter();
RefPtr<MemoryReportingProcess> UtilityProcessManager::GetProcessMemoryReporter(
UtilityProcessParent* parent) {
return new UtilityMemoryReporter(parent);
}
} // namespace mozilla::ipc

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

@ -7,7 +7,9 @@
#define _include_ipc_glue_UtilityProcessManager_h_
#include "mozilla/MozPromise.h"
#include "mozilla/ipc/UtilityProcessHost.h"
#include "mozilla/EnumeratedArray.h"
#include "nsIObserver.h"
#include "nsTArray.h"
namespace mozilla {
@ -36,27 +38,54 @@ class UtilityProcessManager final : public UtilityProcessHost::Listener {
void OnProcessUnexpectedShutdown(UtilityProcessHost* aHost);
// Returns the platform pid for the Utility process.
Maybe<base::ProcessId> ProcessPid();
// Returns the platform pid for this utility sandbox process.
Maybe<base::ProcessId> ProcessPid(SandboxingKind aSandbox);
// If a Utility process is present, create a MemoryReportingProcess object.
// Otherwise, return null.
RefPtr<MemoryReportingProcess> GetProcessMemoryReporter();
// Create a MemoryReportingProcess object for this utility process
RefPtr<MemoryReportingProcess> GetProcessMemoryReporter(
UtilityProcessParent* parent);
// Returns access to the PUtility protocol if a Utility process is present.
UtilityProcessParent* GetProcessParent() { return mProcessParent; }
// Returns access to the PUtility protocol if a Utility process for that
// sandbox is present.
RefPtr<UtilityProcessParent> GetProcessParent(SandboxingKind aSandbox) {
RefPtr<ProcessFields> p = GetProcess(aSandbox);
if (!p) {
return nullptr;
}
return p->mProcessParent;
}
// Returns the Utility Process
UtilityProcessHost* Process() { return mProcess; }
// Get a list of all valid utility process parent references
nsTArray<RefPtr<UtilityProcessParent>> GetAllProcessesProcessParent() {
nsTArray<RefPtr<UtilityProcessParent>> rv;
for (auto& p : mProcesses) {
if (p && p->mProcessParent) {
rv.AppendElement(p->mProcessParent);
}
}
return rv;
}
// Shutdown the Utility process.
void CleanShutdown();
// Returns the Utility Process for that sandbox
UtilityProcessHost* Process(SandboxingKind aSandbox) {
RefPtr<ProcessFields> p = GetProcess(aSandbox);
if (!p) {
return nullptr;
}
return p->mProcess;
}
// Shutdown the Utility process for that sandbox.
void CleanShutdown(SandboxingKind aSandbox);
// Shutdown all utility processes
void CleanShutdownAllProcesses();
private:
~UtilityProcessManager();
bool IsProcessLaunching();
bool IsProcessDestroyed() const;
bool IsProcessLaunching(SandboxingKind aSandbox);
bool IsProcessDestroyed(SandboxingKind aSandbox);
// Called from our xpcom-shutdown observer.
void OnXPCOMShutdown();
@ -64,7 +93,7 @@ class UtilityProcessManager final : public UtilityProcessHost::Listener {
UtilityProcessManager();
void DestroyProcess();
void DestroyProcess(SandboxingKind aSandbox);
bool IsShutdown() const;
@ -82,19 +111,41 @@ class UtilityProcessManager final : public UtilityProcessHost::Listener {
friend class Observer;
RefPtr<Observer> mObserver;
uint32_t mNumProcessAttempts = 0;
uint32_t mNumUnexpectedCrashes = 0;
// Fields that are associated with the current Utility process.
UtilityProcessHost* mProcess = nullptr;
UtilityProcessParent* mProcessParent = nullptr;
// Collects any pref changes that occur during process launch (after
// the initial map is passed in command-line arguments) to be sent
// when the process can receive IPC messages.
nsTArray<dom::Pref> mQueuedPrefs;
// Promise will be resolved when the Utility process has been fully started
// and VideoBridge configured. Only accessed on the main thread.
RefPtr<GenericNonExclusivePromise> mLaunchPromise;
class ProcessFields final {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ProcessFields);
explicit ProcessFields(SandboxingKind aSandbox) : mSandbox(aSandbox){};
// Promise will be resolved when this Utility process has been fully started
// and configured. Only accessed on the main thread.
RefPtr<GenericNonExclusivePromise> mLaunchPromise;
uint32_t mNumProcessAttempts = 0;
uint32_t mNumUnexpectedCrashes = 0;
// Fields that are associated with the current Utility process.
UtilityProcessHost* mProcess = nullptr;
RefPtr<UtilityProcessParent> mProcessParent = nullptr;
// Collects any pref changes that occur during process launch (after
// the initial map is passed in command-line arguments) to be sent
// when the process can receive IPC messages.
nsTArray<dom::Pref> mQueuedPrefs;
SandboxingKind mSandbox = SandboxingKind::COUNT;
protected:
~ProcessFields() = default;
};
EnumeratedArray<SandboxingKind, SandboxingKind::COUNT, RefPtr<ProcessFields>>
mProcesses;
RefPtr<ProcessFields> GetProcess(SandboxingKind);
bool NoMoreProcesses();
uint16_t AliveProcesses();
};
} // namespace ipc

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

@ -39,7 +39,8 @@ bool UtilityProcessParent::SendRequestMemoryReport(
[&](const uint32_t& aGeneration2) {
if (RefPtr<UtilityProcessManager> utilitypm =
UtilityProcessManager::GetSingleton()) {
if (UtilityProcessParent* parent = utilitypm->GetProcessParent()) {
for (RefPtr<UtilityProcessParent>& parent :
utilitypm->GetAllProcessesProcessParent()) {
if (parent->mMemoryReportRequest) {
parent->mMemoryReportRequest->Finish(aGeneration2);
parent->mMemoryReportRequest = nullptr;
@ -50,7 +51,8 @@ bool UtilityProcessParent::SendRequestMemoryReport(
[&](mozilla::ipc::ResponseRejectReason) {
if (RefPtr<UtilityProcessManager> utilitypm =
UtilityProcessManager::GetSingleton()) {
if (UtilityProcessParent* parent = utilitypm->GetProcessParent()) {
for (RefPtr<UtilityProcessParent>& parent :
utilitypm->GetAllProcessesProcessParent()) {
parent->mMemoryReportRequest = nullptr;
}
}

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

@ -23,7 +23,7 @@ add_task(async () => {
aAmount,
aDescription
) {
const expectedProcess = `Utility (pid ${utilityPid})`;
const expectedProcess = `Utility (pid: ${utilityPid}, sandboxingKind: ${kGenericUtility})`;
if (aProcess !== expectedProcess) {
return;
}

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

@ -20,8 +20,11 @@ add_task(async () => {
await TestUtils.waitForCondition(async () => {
profile = await Services.profiler.getProfileDataAsync();
return (
profile.processes.filter(ps => ps.threads[0].processType === "utility")
.length === 1
// Search for process name to not be disturbed by other types of utility
// e.g. Utility AudioDecoder
profile.processes.filter(
ps => ps.threads[0].processName === "Utility Process"
).length === 1
);
}, "Give time for the profiler to start and collect some samples");

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

@ -63,7 +63,8 @@ TEST_F(UtilityProcess, NoProcess) {
UtilityProcessManager::GetSingleton();
EXPECT_NE(utilityProc, nullptr);
Maybe<int32_t> noPid = utilityProc->ProcessPid();
Maybe<int32_t> noPid =
utilityProc->ProcessPid(SandboxingKind::GENERIC_UTILITY);
ASSERT_TRUE(noPid.isNothing());
}
@ -83,7 +84,8 @@ TEST_F(UtilityProcess, LaunchProcess) {
[&]() mutable {
EXPECT_TRUE(true);
Maybe<int32_t> utilityPid = utilityProc->ProcessPid();
Maybe<int32_t> utilityPid =
utilityProc->ProcessPid(SandboxingKind::GENERIC_UTILITY);
EXPECT_TRUE(utilityPid.isSome());
EXPECT_GE(*utilityPid, 1);
EXPECT_NE(*utilityPid, thisPid);
@ -110,13 +112,15 @@ TEST_F(UtilityProcess, DestroyProcess) {
->Then(
GetCurrentSerialEventTarget(), __func__,
[&]() {
Maybe<int32_t> utilityPid = utilityProc->ProcessPid();
Maybe<int32_t> utilityPid =
utilityProc->ProcessPid(SandboxingKind::GENERIC_UTILITY);
EXPECT_TRUE(utilityPid.isSome());
EXPECT_GE(*utilityPid, 1);
utilityProc->CleanShutdown();
utilityProc->CleanShutdown(SandboxingKind::GENERIC_UTILITY);
utilityPid = utilityProc->ProcessPid();
utilityPid =
utilityProc->ProcessPid(SandboxingKind::GENERIC_UTILITY);
EXPECT_TRUE(utilityPid.isNothing());
EXPECT_TRUE(true);

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

@ -35,7 +35,8 @@ UtilityProcessTest::StartProcess(JSContext* aCx,
->Then(
GetCurrentSerialEventTarget(), __func__,
[promise, utilityProc]() {
Maybe<int32_t> utilityPid = utilityProc->ProcessPid();
Maybe<int32_t> utilityPid =
utilityProc->ProcessPid(SandboxingKind::GENERIC_UTILITY);
if (utilityPid.isSome()) {
promise->MaybeResolve(*utilityPid);
} else {
@ -58,8 +59,9 @@ UtilityProcessTest::StopProcess() {
UtilityProcessManager::GetSingleton();
MOZ_ASSERT(utilityProc, "No UtilityprocessManager?");
utilityProc->CleanShutdown();
Maybe<int32_t> utilityPid = utilityProc->ProcessPid();
utilityProc->CleanShutdown(SandboxingKind::GENERIC_UTILITY);
Maybe<int32_t> utilityPid =
utilityProc->ProcessPid(SandboxingKind::GENERIC_UTILITY);
MOZ_RELEASE_ASSERT(utilityPid.isNothing(),
"Should not have a utility process PID anymore");

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

@ -258,11 +258,13 @@ SandboxTest::StartTests(const nsTArray<nsCString>& aProcessesList) {
utilityProc->LaunchProcess(sandboxingKind)
->Then(
GetMainThreadSerialEventTarget(), __func__,
[processPromise, utilityProc]() {
UtilityProcessParent* utilityParent =
utilityProc ? utilityProc->GetProcessParent() : nullptr;
[processPromise, utilityProc, sandboxingKind]() {
RefPtr<UtilityProcessParent> utilityParent =
utilityProc
? utilityProc->GetProcessParent(sandboxingKind)
: nullptr;
if (utilityParent) {
return InitializeSandboxTestingActors(utilityParent,
return InitializeSandboxTestingActors(utilityParent.get(),
processPromise);
}
return processPromise->Reject(NS_ERROR_FAILURE, __func__);

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

@ -25,6 +25,7 @@
#include "mozilla/ipc/UtilityProcessChild.h"
#include "mozilla/ipc/UtilityProcessManager.h"
#include "mozilla/ipc/UtilityProcessParent.h"
#include "mozilla/ipc/UtilityProcessSandboxing.h"
#include "mozilla/Unused.h"
#include "GMPPlatform.h"
#include "GMPServiceParent.h"
@ -233,9 +234,9 @@ void FlushAllChildData(
if (RefPtr<UtilityProcessManager> utilityManager =
UtilityProcessManager::GetIfExists()) {
if (UtilityProcessParent* utilityParent =
utilityManager->GetProcessParent()) {
promises.EmplaceBack(utilityParent->SendFlushFOGData());
for (RefPtr<UtilityProcessParent>& parent :
utilityManager->GetAllProcessesProcessParent()) {
promises.EmplaceBack(parent->SendFlushFOGData());
}
}
@ -362,7 +363,7 @@ void TestTriggerMetrics(uint32_t aProcessType,
break;
case nsIXULRuntime::PROCESS_TYPE_UTILITY:
Unused << ipc::UtilityProcessManager::GetSingleton()
->GetProcessParent()
->GetProcessParent(ipc::SandboxingKind::GENERIC_UTILITY)
->SendTestTriggerMetrics()
->Then(
GetCurrentSerialEventTarget(), __func__,

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

@ -1816,9 +1816,12 @@ nsresult nsMemoryReporterManager::StartGettingReports() {
if (RefPtr<UtilityProcessManager> utility =
UtilityProcessManager::GetIfExists()) {
if (RefPtr<MemoryReportingProcess> proc =
utility->GetProcessMemoryReporter()) {
s->mChildrenPending.AppendElement(proc.forget());
for (RefPtr<UtilityProcessParent>& parent :
utility->GetAllProcessesProcessParent()) {
if (RefPtr<MemoryReportingProcess> proc =
utility->GetProcessMemoryReporter(parent)) {
s->mChildrenPending.AppendElement(proc.forget());
}
}
}