2018-11-14 21:06:24 +03:00
|
|
|
/* -*- 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/. */
|
|
|
|
#include "RDDParent.h"
|
|
|
|
|
|
|
|
#if defined(XP_WIN)
|
2018-11-19 16:25:37 +03:00
|
|
|
#include <process.h>
|
|
|
|
#include <dwrite.h>
|
2018-11-14 21:06:24 +03:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "mozilla/Assertions.h"
|
|
|
|
#include "mozilla/HangDetails.h"
|
|
|
|
#include "mozilla/RemoteDecoderManagerChild.h"
|
|
|
|
#include "mozilla/RemoteDecoderManagerParent.h"
|
|
|
|
#include "mozilla/TimeStamp.h"
|
|
|
|
#include "mozilla/dom/MemoryReportRequest.h"
|
|
|
|
#include "mozilla/ipc/CrashReporterClient.h"
|
|
|
|
#include "mozilla/ipc/ProcessChild.h"
|
|
|
|
|
|
|
|
#ifdef MOZ_GECKO_PROFILER
|
|
|
|
#include "ChildProfilerController.h"
|
|
|
|
#endif
|
|
|
|
#include "nsDebugImpl.h"
|
|
|
|
#include "nsThreadManager.h"
|
|
|
|
#include "ProcessUtils.h"
|
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
|
|
|
|
using namespace ipc;
|
|
|
|
|
|
|
|
static RDDParent* sRDDParent;
|
|
|
|
|
2018-11-19 16:25:37 +03:00
|
|
|
RDDParent::RDDParent() : mLaunchTime(TimeStamp::Now()) { sRDDParent = this; }
|
2018-11-14 21:06:24 +03:00
|
|
|
|
2018-11-19 16:25:37 +03:00
|
|
|
RDDParent::~RDDParent() { sRDDParent = nullptr; }
|
2018-11-14 21:06:24 +03:00
|
|
|
|
2018-11-19 16:25:37 +03:00
|
|
|
/* static */ RDDParent* RDDParent::GetSingleton() { return sRDDParent; }
|
2018-11-14 21:06:24 +03:00
|
|
|
|
2018-11-19 16:25:37 +03:00
|
|
|
bool RDDParent::Init(base::ProcessId aParentPid, const char* aParentBuildID,
|
|
|
|
MessageLoop* aIOLoop, IPC::Channel* aChannel) {
|
2018-11-14 21:06:24 +03:00
|
|
|
// Initialize the thread manager before starting IPC. Otherwise, messages
|
|
|
|
// may be posted to the main thread and we won't be able to process them.
|
|
|
|
if (NS_WARN_IF(NS_FAILED(nsThreadManager::get().Init()))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now it's safe to start IPC.
|
|
|
|
if (NS_WARN_IF(!Open(aChannel, aParentPid, aIOLoop))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsDebugImpl::SetMultiprocessMode("RDD");
|
|
|
|
|
|
|
|
// This must be checked before any IPDL message, which may hit sentinel
|
|
|
|
// errors due to parent and content processes having different
|
|
|
|
// versions.
|
|
|
|
MessageChannel* channel = GetIPCChannel();
|
|
|
|
if (channel && !channel->SendBuildIDsMatchMessage(aParentBuildID)) {
|
|
|
|
// We need to quit this process if the buildID doesn't match the parent's.
|
|
|
|
// This can occur when an update occurred in the background.
|
|
|
|
ProcessChild::QuickExit();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Init crash reporter support.
|
|
|
|
CrashReporterClient::InitSingleton(this);
|
|
|
|
|
|
|
|
if (NS_FAILED(NS_InitMinimalXPCOM())) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::SetThisProcessName("RDD Process");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-11-19 16:25:37 +03:00
|
|
|
mozilla::ipc::IPCResult RDDParent::RecvInit() {
|
2018-11-14 21:06:24 +03:00
|
|
|
Unused << SendInitComplete();
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2018-11-19 16:25:37 +03:00
|
|
|
mozilla::ipc::IPCResult RDDParent::RecvInitProfiler(
|
|
|
|
Endpoint<PProfilerChild>&& aEndpoint) {
|
2018-11-14 21:06:24 +03:00
|
|
|
#ifdef MOZ_GECKO_PROFILER
|
|
|
|
mProfilerController = ChildProfilerController::Create(std::move(aEndpoint));
|
|
|
|
#endif
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2018-11-19 16:25:37 +03:00
|
|
|
mozilla::ipc::IPCResult RDDParent::RecvNewContentRemoteDecoderManager(
|
|
|
|
Endpoint<PRemoteDecoderManagerParent>&& aEndpoint) {
|
2018-11-14 21:06:24 +03:00
|
|
|
if (!RemoteDecoderManagerParent::CreateForContent(std::move(aEndpoint))) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2018-11-19 16:25:37 +03:00
|
|
|
mozilla::ipc::IPCResult RDDParent::RecvRequestMemoryReport(
|
|
|
|
const uint32_t& aGeneration, const bool& aAnonymize,
|
|
|
|
const bool& aMinimizeMemoryUsage, const MaybeFileDesc& aDMDFile) {
|
2018-11-14 21:06:24 +03:00
|
|
|
nsPrintfCString processName("RDD (pid %u)", (unsigned)getpid());
|
|
|
|
|
2018-11-19 16:25:37 +03:00
|
|
|
mozilla::dom::MemoryReportRequestClient::Start(
|
|
|
|
aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName);
|
2018-11-14 21:06:24 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2018-11-19 16:25:37 +03:00
|
|
|
void RDDParent::ActorDestroy(ActorDestroyReason aWhy) {
|
2018-11-14 21:06:24 +03:00
|
|
|
if (AbnormalShutdown == aWhy) {
|
|
|
|
NS_WARNING("Shutting down RDD process early due to a crash!");
|
|
|
|
ProcessChild::QuickExit();
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NS_FREE_PERMANENT_DATA
|
|
|
|
// No point in going through XPCOM shutdown because we don't keep persistent
|
|
|
|
// state.
|
|
|
|
ProcessChild::QuickExit();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef MOZ_GECKO_PROFILER
|
|
|
|
if (mProfilerController) {
|
|
|
|
mProfilerController->Shutdown();
|
|
|
|
mProfilerController = nullptr;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
CrashReporterClient::DestroySingleton();
|
|
|
|
XRE_ShutdownChildProcess();
|
|
|
|
}
|
|
|
|
|
2018-11-19 16:25:37 +03:00
|
|
|
} // namespace mozilla
|