Bug 1321052 - Convert ProcessHangMonitor to use endpoints. r=billm
MozReview-Commit-ID: Ixj2b3ONLcc
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1245,16 +1245,23 @@ ContentChild::AllocPGMPServiceChild(mozi
mozilla::ipc::IPCResult
ContentChild::RecvGMPsChanged(nsTArray<GMPCapabilityData>&& capabilities)
{
GeckoMediaPluginServiceChild::UpdateGMPCapabilities(Move(capabilities));
return IPC_OK();
}
mozilla::ipc::IPCResult
+ContentChild::RecvInitProcessHangMonitor(Endpoint<PProcessHangMonitorChild>&& aHangMonitor)
+{
+ CreateHangMonitorChild(Move(aHangMonitor));
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
ContentChild::RecvInitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
Endpoint<PVRManagerChild>&& aVRBridge,
Endpoint<PVideoDecoderManagerChild>&& aVideoManager)
{
if (!CompositorBridgeChild::InitForContent(Move(aCompositor))) {
return IPC_FAIL_NO_REASON(this);
}
@@ -1307,23 +1314,16 @@ ContentChild::RecvReinitRendering(Endpoi
PBackgroundChild*
ContentChild::AllocPBackgroundChild(Transport* aTransport,
ProcessId aOtherProcess)
{
return BackgroundChild::Alloc(aTransport, aOtherProcess);
}
-PProcessHangMonitorChild*
-ContentChild::AllocPProcessHangMonitorChild(Transport* aTransport,
- ProcessId aOtherProcess)
-{
- return CreateHangMonitorChild(aTransport, aOtherProcess);
-}
-
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
#include <stdlib.h>
static bool
GetAppPaths(nsCString &aAppPath, nsCString &aAppBinaryPath, nsCString &aAppDir)
{
nsAutoCString appPath;
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -161,33 +161,32 @@ public:
PGMPServiceChild*
AllocPGMPServiceChild(mozilla::ipc::Transport* transport,
base::ProcessId otherProcess) override;
mozilla::ipc::IPCResult
RecvGMPsChanged(nsTArray<GMPCapabilityData>&& capabilities) override;
mozilla::ipc::IPCResult
+ RecvInitProcessHangMonitor(Endpoint<PProcessHangMonitorChild>&& aHangMonitor) override;
+
+ mozilla::ipc::IPCResult
RecvInitRendering(
Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
Endpoint<PVRManagerChild>&& aVRBridge,
Endpoint<PVideoDecoderManagerChild>&& aVideoManager) override;
mozilla::ipc::IPCResult
RecvReinitRendering(
Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
Endpoint<PVRManagerChild>&& aVRBridge,
Endpoint<PVideoDecoderManagerChild>&& aVideoManager) override;
- PProcessHangMonitorChild*
- AllocPProcessHangMonitorChild(Transport* aTransport,
- ProcessId aOtherProcess) override;
-
virtual mozilla::ipc::IPCResult RecvSetProcessSandbox(const MaybeFileDesc& aBroker) override;
PBackgroundChild*
AllocPBackgroundChild(Transport* aTransport, ProcessId aOtherProcess)
override;
virtual PBrowserChild* AllocPBrowserChild(const TabId& aTabId,
const IPCTabContext& aContext,
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1772,17 +1772,17 @@ ContentParent::LaunchSubprocess(ProcessP
base::GetProcId(mSubprocess->GetChildProcessHandle()));
InitInternal(aInitialPriority,
true, /* Setup off-main thread compositing */
true /* Send registered chrome */);
ContentProcessManager::GetSingleton()->AddContentProcess(this);
- ProcessHangMonitor::AddProcess(this);
+ mHangMonitorActor = ProcessHangMonitor::AddProcess(this);
// Set a reply timeout for CPOWs.
SetReplyTimeoutMs(Preferences::GetInt("dom.ipc.cpow.timeout", 0));
return true;
}
ContentParent::ContentParent(ContentParent* aOpener,
@@ -2472,24 +2472,16 @@ ContentParent::AllocPGMPServiceParent(mo
PBackgroundParent*
ContentParent::AllocPBackgroundParent(Transport* aTransport,
ProcessId aOtherProcess)
{
return BackgroundParent::Alloc(this, aTransport, aOtherProcess);
}
-PProcessHangMonitorParent*
-ContentParent::AllocPProcessHangMonitorParent(Transport* aTransport,
- ProcessId aOtherProcess)
-{
- mHangMonitorActor = CreateHangMonitorParent(this, aTransport, aOtherProcess);
- return mHangMonitorActor;
-}
-
mozilla::ipc::IPCResult
ContentParent::RecvGetProcessAttributes(ContentParentId* aCpId,
bool* aIsForBrowser)
{
*aCpId = mChildID;
*aIsForBrowser = mIsForBrowser;
return IPC_OK();
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -705,20 +705,16 @@ private:
PGMPServiceParent*
AllocPGMPServiceParent(mozilla::ipc::Transport* aTransport,
base::ProcessId aOtherProcess) override;
PBackgroundParent*
AllocPBackgroundParent(Transport* aTransport, ProcessId aOtherProcess)
override;
- PProcessHangMonitorParent*
- AllocPProcessHangMonitorParent(Transport* aTransport,
- ProcessId aOtherProcess) override;
-
virtual mozilla::ipc::IPCResult RecvGetProcessAttributes(ContentParentId* aCpId,
bool* aIsForBrowser) override;
virtual mozilla::ipc::IPCResult
RecvGetXPCOMProcessAttributes(bool* aIsOffline,
bool* aIsConnected,
int32_t* aCaptivePortalState,
bool* aIsLangRTL,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -342,17 +342,16 @@ struct GMPCapabilityData
nsCString version;
GMPAPITags[] capabilities;
};
nested(upto inside_cpow) sync protocol PContent
{
parent spawns PPluginModule;
- parent opens PProcessHangMonitor;
parent opens PGMPService;
child opens PBackground;
manages PBlob;
manages PBrowser;
manages PContentPermissionRequest;
manages PCrashReporter;
manages PCycleCollectWithLogs;
@@ -410,16 +409,18 @@ both:
// For parent->child, aBrowser must be non-null; aOuterWindowID can
// be 0 to indicate the browser's current root document, or nonzero
// to persist a subdocument. For child->parent, arguments are
// ignored and should be null/zero.
async PWebBrowserPersistDocument(nullable PBrowser aBrowser,
uint64_t aOuterWindowID);
child:
+ async InitProcessHangMonitor(Endpoint<PProcessHangMonitorChild> hangMonitor);
+
// Give the content process its endpoints to the compositor.
async InitRendering(
Endpoint<PCompositorBridgeChild> compositor,
Endpoint<PImageBridgeChild> imageBridge,
Endpoint<PVRManagerChild> vr,
Endpoint<PVideoDecoderManagerChild> video);
// Re-create the rendering stack using the given endpoints. This is sent
--- a/dom/ipc/ProcessHangMonitor.cpp
+++ b/dom/ipc/ProcessHangMonitor.cpp
@@ -36,16 +36,17 @@
#ifdef XP_WIN
// For IsDebuggerPresent()
#include <windows.h>
#endif
using namespace mozilla;
using namespace mozilla::dom;
+using namespace mozilla::ipc;
/*
* Basic architecture:
*
* Each process has its own ProcessHangMonitor singleton. This singleton exists
* as long as there is at least one content process in the system. Each content
* process has a HangMonitorChild and the chrome process has one
* HangMonitorParent per process. Each process (including the chrome process)
@@ -73,18 +74,17 @@ namespace {
class HangMonitorChild
: public PProcessHangMonitorChild
{
public:
explicit HangMonitorChild(ProcessHangMonitor* aMonitor);
~HangMonitorChild() override;
- void Open(Transport* aTransport, ProcessId aOtherPid,
- MessageLoop* aIOLoop);
+ void Bind(Endpoint<PProcessHangMonitorChild>&& aEndpoint);
typedef ProcessHangMonitor::SlowScriptAction SlowScriptAction;
SlowScriptAction NotifySlowScript(nsITabChild* aTabChild,
const char* aFileName,
unsigned aLineNo);
void NotifySlowScriptAsync(TabId aTabId,
const nsCString& aFileName,
unsigned aLineNo);
@@ -206,17 +206,17 @@ private:
class HangMonitorParent
: public PProcessHangMonitorParent
{
public:
explicit HangMonitorParent(ProcessHangMonitor* aMonitor);
~HangMonitorParent() override;
- void Open(Transport* aTransport, ProcessId aPid, MessageLoop* aIOLoop);
+ void Bind(Endpoint<PProcessHangMonitorParent>&& aEndpoint);
mozilla::ipc::IPCResult RecvHangEvidence(const HangData& aHangData) override;
mozilla::ipc::IPCResult RecvClearHang() override;
void ActorDestroy(ActorDestroyReason aWhy) override;
void SetProcess(HangMonitoredProcess* aProcess) { mProcess = aProcess; }
@@ -411,25 +411,24 @@ HangMonitorChild::ClearForcePaint()
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(XRE_IsContentProcess());
mForcePaintMonitor->NotifyWait();
}
void
-HangMonitorChild::Open(Transport* aTransport, ProcessId aPid,
- MessageLoop* aIOLoop)
+HangMonitorChild::Bind(Endpoint<PProcessHangMonitorChild>&& aEndpoint)
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
MOZ_ASSERT(!sInstance);
sInstance = this;
- DebugOnly<bool> ok = PProcessHangMonitorChild::Open(aTransport, aPid, aIOLoop);
+ DebugOnly<bool> ok = aEndpoint.Bind(this);
MOZ_ASSERT(ok);
}
void
HangMonitorChild::NotifySlowScriptAsync(TabId aTabId,
const nsCString& aFileName,
unsigned aLineNo)
{
@@ -630,22 +629,21 @@ HangMonitorParent::ForcePaintOnThread(Ta
void
HangMonitorParent::ActorDestroy(ActorDestroyReason aWhy)
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
mIPCOpen = false;
}
void
-HangMonitorParent::Open(Transport* aTransport, ProcessId aPid,
- MessageLoop* aIOLoop)
+HangMonitorParent::Bind(Endpoint<PProcessHangMonitorParent>&& aEndpoint)
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
- DebugOnly<bool> ok = PProcessHangMonitorParent::Open(aTransport, aPid, aIOLoop);
+ DebugOnly<bool> ok = aEndpoint.Bind(this);
MOZ_ASSERT(ok);
}
class HangObserverNotifier final : public Runnable
{
public:
HangObserverNotifier(HangMonitoredProcess* aProcess,
HangMonitorParent *aParent,
@@ -1168,79 +1166,86 @@ ProcessHangMonitor::InitiateCPOWTimeout(
void
ProcessHangMonitor::NotifyPluginHang(uint32_t aPluginId)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
return HangMonitorChild::Get()->NotifyPluginHang(aPluginId);
}
-PProcessHangMonitorParent*
-mozilla::CreateHangMonitorParent(ContentParent* aContentParent,
- mozilla::ipc::Transport* aTransport,
- base::ProcessId aOtherPid)
+static PProcessHangMonitorParent*
+CreateHangMonitorParent(ContentParent* aContentParent,
+ Endpoint<PProcessHangMonitorParent>&& aEndpoint)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
ProcessHangMonitor* monitor = ProcessHangMonitor::GetOrCreate();
auto* parent = new HangMonitorParent(monitor);
auto* process = new HangMonitoredProcess(parent, aContentParent);
parent->SetProcess(process);
monitor->MonitorLoop()->PostTask(NewNonOwningRunnableMethod
- <mozilla::ipc::Transport*,
- base::ProcessId,
- MessageLoop*>(parent,
- &HangMonitorParent::Open,
- aTransport, aOtherPid,
- XRE_GetIOMessageLoop()));
+ <Endpoint<PProcessHangMonitorParent>&&>(parent,
+ &HangMonitorParent::Bind,
+ Move(aEndpoint)));
return parent;
}
-PProcessHangMonitorChild*
-mozilla::CreateHangMonitorChild(mozilla::ipc::Transport* aTransport,
- base::ProcessId aOtherPid)
+void
+mozilla::CreateHangMonitorChild(Endpoint<PProcessHangMonitorChild>&& aEndpoint)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
JSContext* cx = danger::GetJSContext();
JS_AddInterruptCallback(cx, InterruptCallback);
JS::AddGCInterruptCallback(cx, InterruptCallback);
ProcessHangMonitor* monitor = ProcessHangMonitor::GetOrCreate();
auto* child = new HangMonitorChild(monitor);
monitor->MonitorLoop()->PostTask(NewNonOwningRunnableMethod
- <mozilla::ipc::Transport*,
- base::ProcessId,
- MessageLoop*>(child,
- &HangMonitorChild::Open,
- aTransport, aOtherPid,
- XRE_GetIOMessageLoop()));
-
- return child;
+ <Endpoint<PProcessHangMonitorChild>&&>(child,
+ &HangMonitorChild::Bind,
+ Move(aEndpoint)));
}
MessageLoop*
ProcessHangMonitor::MonitorLoop()
{
return mThread->message_loop();
}
-/* static */ void
+/* static */ PProcessHangMonitorParent*
ProcessHangMonitor::AddProcess(ContentParent* aContentParent)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
- if (mozilla::Preferences::GetBool("dom.ipc.processHangMonitor", false)) {
- DebugOnly<bool> opened = PProcessHangMonitor::Open(aContentParent);
- MOZ_ASSERT(opened);
+ if (!mozilla::Preferences::GetBool("dom.ipc.processHangMonitor", false)) {
+ return nullptr;
}
+
+ Endpoint<PProcessHangMonitorParent> parent;
+ Endpoint<PProcessHangMonitorChild> child;
+ nsresult rv;
+ rv = PProcessHangMonitor::CreateEndpoints(base::GetCurrentProcId(),
+ aContentParent->OtherPid(),
+ &parent, &child);
+ if (NS_FAILED(rv)) {
+ MOZ_ASSERT(false, "PProcessHangMonitor::CreateEndpoints failed");
+ return nullptr;
+ }
+
+ if (!aContentParent->SendInitProcessHangMonitor(Move(child))) {
+ MOZ_ASSERT(false);
+ return nullptr;
+ }
+
+ return CreateHangMonitorParent(aContentParent, Move(parent));
}
/* static */ void
ProcessHangMonitor::RemoveProcess(PProcessHangMonitorParent* aParent)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
auto parent = static_cast<HangMonitorParent*>(aParent);
parent->Shutdown();
--- a/dom/ipc/ProcessHangMonitor.h
+++ b/dom/ipc/ProcessHangMonitor.h
@@ -36,17 +36,17 @@ class ProcessHangMonitor final
public:
static ProcessHangMonitor* Get() { return sInstance; }
static ProcessHangMonitor* GetOrCreate();
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
- static void AddProcess(dom::ContentParent* aContentParent);
+ static PProcessHangMonitorParent* AddProcess(dom::ContentParent* aContentParent);
static void RemoveProcess(PProcessHangMonitorParent* aParent);
static void ClearHang();
static void ForcePaint(PProcessHangMonitorParent* aParent,
dom::TabParent* aTab,
uint64_t aLayerObserverEpoch);
static void ClearForcePaint();
--- a/dom/ipc/ProcessHangMonitorIPC.h
+++ b/dom/ipc/ProcessHangMonitorIPC.h
@@ -15,20 +15,14 @@
#include "mozilla/PProcessHangMonitorChild.h"
namespace mozilla {
namespace dom {
class ContentParent;
} // namespace dom
-PProcessHangMonitorParent*
-CreateHangMonitorParent(mozilla::dom::ContentParent* aContentParent,
- mozilla::ipc::Transport* aTransport,
- base::ProcessId aOtherProcess);
-
-PProcessHangMonitorChild*
-CreateHangMonitorChild(mozilla::ipc::Transport* aTransport,
- base::ProcessId aOtherProcess);
+void
+CreateHangMonitorChild(ipc::Endpoint<PProcessHangMonitorChild>&& aEndpoint);
} // namespace mozilla
#endif // mozilla_ProcessHangMonitorIPC_h