mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-03 15:19:44 +00:00

Tests for about:memory doesn't know about utility processes. Make sure to hide the utility process reporter when needed. Differential Revision: https://phabricator.services.mozilla.com/D167662
233 lines
6.8 KiB
C++
233 lines
6.8 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
#ifndef _include_ipc_glue_UtilityProcessManager_h_
|
|
#define _include_ipc_glue_UtilityProcessManager_h_
|
|
#include "mozilla/MozPromise.h"
|
|
#include "mozilla/ipc/UtilityProcessHost.h"
|
|
#include "mozilla/EnumeratedArray.h"
|
|
#include "mozilla/ProcInfo.h"
|
|
#include "nsIObserver.h"
|
|
#include "nsTArray.h"
|
|
|
|
#include "mozilla/PRemoteDecoderManagerChild.h"
|
|
|
|
namespace mozilla {
|
|
|
|
class MemoryReportingProcess;
|
|
|
|
namespace dom {
|
|
class JSOracleParent;
|
|
class WindowsUtilsParent;
|
|
} // namespace dom
|
|
|
|
namespace ipc {
|
|
|
|
class UtilityProcessParent;
|
|
|
|
// The UtilityProcessManager is a singleton responsible for creating
|
|
// Utility-bound objects that may live in another process. Currently, it
|
|
// provides access to the Utility process via ContentParent.
|
|
class UtilityProcessManager final : public UtilityProcessHost::Listener {
|
|
friend class UtilityProcessParent;
|
|
|
|
public:
|
|
using StartRemoteDecodingUtilityPromise =
|
|
MozPromise<Endpoint<PRemoteDecoderManagerChild>, nsresult, true>;
|
|
using JSOraclePromise = GenericNonExclusivePromise;
|
|
|
|
using WindowsUtilsPromise =
|
|
MozPromise<RefPtr<dom::WindowsUtilsParent>, nsresult, true>;
|
|
|
|
static void Initialize();
|
|
static void Shutdown();
|
|
|
|
static RefPtr<UtilityProcessManager> GetSingleton();
|
|
|
|
static RefPtr<UtilityProcessManager> GetIfExists();
|
|
|
|
// Launch a new Utility process asynchronously
|
|
RefPtr<GenericNonExclusivePromise> LaunchProcess(SandboxingKind aSandbox);
|
|
|
|
template <typename Actor>
|
|
RefPtr<GenericNonExclusivePromise> StartUtility(RefPtr<Actor> aActor,
|
|
SandboxingKind aSandbox);
|
|
|
|
RefPtr<StartRemoteDecodingUtilityPromise> StartProcessForRemoteMediaDecoding(
|
|
base::ProcessId aOtherProcess, SandboxingKind aSandbox);
|
|
|
|
RefPtr<JSOraclePromise> StartJSOracle(mozilla::dom::JSOracleParent* aParent);
|
|
|
|
#ifdef XP_WIN
|
|
// Get the (possibly already resolved) promise for the Windows utility
|
|
// process actor. Creates the process if it is not running.
|
|
RefPtr<WindowsUtilsPromise> GetWindowsUtilsPromise();
|
|
// Releases the WindowsUtils actor so that it can be destroyed.
|
|
// Subsequent attempts to use WindowsUtils will create a new process.
|
|
void ReleaseWindowsUtils();
|
|
#endif
|
|
|
|
void OnProcessUnexpectedShutdown(UtilityProcessHost* aHost);
|
|
|
|
// Returns the platform pid for this utility sandbox process.
|
|
Maybe<base::ProcessId> ProcessPid(SandboxingKind aSandbox);
|
|
|
|
// Create a MemoryReportingProcess object for this utility process
|
|
RefPtr<MemoryReportingProcess> GetProcessMemoryReporter(
|
|
UtilityProcessParent* parent);
|
|
|
|
// 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;
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
// Returns the Utility Process for that sandbox
|
|
UtilityProcessHost* Process(SandboxingKind aSandbox) {
|
|
RefPtr<ProcessFields> p = GetProcess(aSandbox);
|
|
if (!p) {
|
|
return nullptr;
|
|
}
|
|
return p->mProcess;
|
|
}
|
|
|
|
void RegisterActor(const RefPtr<UtilityProcessParent>& aParent,
|
|
UtilityActorName aActorName) {
|
|
for (auto& p : mProcesses) {
|
|
if (p && p->mProcessParent && p->mProcessParent == aParent) {
|
|
p->mActors.AppendElement(aActorName);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
Span<const UtilityActorName> GetActors(
|
|
const RefPtr<UtilityProcessParent>& aParent) {
|
|
for (auto& p : mProcesses) {
|
|
if (p && p->mProcessParent && p->mProcessParent == aParent) {
|
|
return p->mActors;
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
|
|
Span<const UtilityActorName> GetActors(GeckoChildProcessHost* aHost) {
|
|
for (auto& p : mProcesses) {
|
|
if (p && p->mProcess == aHost) {
|
|
return p->mActors;
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
|
|
Span<const UtilityActorName> GetActors(SandboxingKind aSbKind) {
|
|
auto proc = GetProcess(aSbKind);
|
|
if (!proc) {
|
|
return {};
|
|
}
|
|
return proc->mActors;
|
|
}
|
|
|
|
// Shutdown the Utility process for that sandbox.
|
|
void CleanShutdown(SandboxingKind aSandbox);
|
|
|
|
// Shutdown all utility processes
|
|
void CleanShutdownAllProcesses();
|
|
|
|
uint16_t AliveProcesses();
|
|
|
|
private:
|
|
~UtilityProcessManager();
|
|
|
|
bool IsProcessLaunching(SandboxingKind aSandbox);
|
|
bool IsProcessDestroyed(SandboxingKind aSandbox);
|
|
|
|
// Called from our xpcom-shutdown observer.
|
|
void OnXPCOMShutdown();
|
|
void OnPreferenceChange(const char16_t* aData);
|
|
|
|
UtilityProcessManager();
|
|
|
|
void DestroyProcess(SandboxingKind aSandbox);
|
|
|
|
bool IsShutdown() const;
|
|
|
|
class Observer final : public nsIObserver {
|
|
public:
|
|
NS_DECL_ISUPPORTS
|
|
NS_DECL_NSIOBSERVER
|
|
explicit Observer(RefPtr<UtilityProcessManager> aManager);
|
|
|
|
protected:
|
|
~Observer() = default;
|
|
|
|
RefPtr<UtilityProcessManager> mManager;
|
|
};
|
|
friend class Observer;
|
|
|
|
RefPtr<Observer> mObserver;
|
|
|
|
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;
|
|
|
|
nsTArray<UtilityActorName> mActors;
|
|
|
|
SandboxingKind mSandbox = SandboxingKind::COUNT;
|
|
|
|
protected:
|
|
~ProcessFields() = default;
|
|
};
|
|
|
|
EnumeratedArray<SandboxingKind, SandboxingKind::COUNT, RefPtr<ProcessFields>>
|
|
mProcesses;
|
|
|
|
RefPtr<ProcessFields> GetProcess(SandboxingKind);
|
|
bool NoMoreProcesses();
|
|
|
|
#ifdef XP_WIN
|
|
RefPtr<dom::WindowsUtilsParent> mWindowsUtils;
|
|
#endif // XP_WIN
|
|
};
|
|
|
|
} // namespace ipc
|
|
|
|
} // namespace mozilla
|
|
|
|
#endif // _include_ipc_glue_UtilityProcessManager_h_
|