зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1753424 - Support running multiple UtilityProcess r=nika
Differential Revision: https://phabricator.services.mozilla.com/D139817
This commit is contained in:
Родитель
b927a14488
Коммит
94b46a0084
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче