mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-04 04:58:00 +00:00
Bug 1284674 - Remove NUWA r=cyu
MozReview-Commit-ID: GyMRNzOBKw6 --HG-- extra : rebase_source : 293af1cd55f2035ce6a99f4ebf144059c32a2b8f
This commit is contained in:
parent
3245c78fef
commit
0af5b943b6
@ -1,300 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=2 autoindent cindent expandtab: */
|
||||
/* 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 "nsXULAppAPI.h"
|
||||
#include "application.ini.h"
|
||||
#include "nsXPCOMGlue.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIFile.h"
|
||||
#include "BinaryPath.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#define ASSERT(x) if (!(x)) { MOZ_CRASH(); }
|
||||
|
||||
// Functions being loaded by XPCOMGlue
|
||||
XRE_ProcLoaderServiceRunType XRE_ProcLoaderServiceRun;
|
||||
XRE_ProcLoaderClientInitType XRE_ProcLoaderClientInit;
|
||||
XRE_ProcLoaderPreloadType XRE_ProcLoaderPreload;
|
||||
extern XRE_CreateAppDataType XRE_CreateAppData;
|
||||
extern XRE_GetFileFromPathType XRE_GetFileFromPath;
|
||||
|
||||
static const nsDynamicFunctionLoad kXULFuncs[] = {
|
||||
{ "XRE_ProcLoaderServiceRun", (NSFuncPtr*) &XRE_ProcLoaderServiceRun },
|
||||
{ "XRE_ProcLoaderClientInit", (NSFuncPtr*) &XRE_ProcLoaderClientInit },
|
||||
{ "XRE_ProcLoaderPreload", (NSFuncPtr*) &XRE_ProcLoaderPreload },
|
||||
{ "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
|
||||
{ "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
||||
typedef mozilla::Vector<int> FdArray;
|
||||
static const int kReservedFileDescriptors = 5;
|
||||
static const int kBeginReserveFileDescriptor = STDERR_FILENO + 1;
|
||||
|
||||
static int
|
||||
GetDirnameSlash(const char *aPath, char *aOutDir, int aMaxLen)
|
||||
{
|
||||
char *lastSlash = strrchr(aPath, XPCOM_FILE_PATH_SEPARATOR[0]);
|
||||
if (lastSlash == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
int cpsz = lastSlash - aPath + 1; // include slash
|
||||
if (aMaxLen <= cpsz) {
|
||||
return 0;
|
||||
}
|
||||
strncpy(aOutDir, aPath, cpsz);
|
||||
aOutDir[cpsz] = 0;
|
||||
return cpsz;
|
||||
}
|
||||
|
||||
static bool
|
||||
GetXPCOMPath(const char *aProgram, char *aOutPath, int aMaxLen)
|
||||
{
|
||||
auto progBuf = mozilla::MakeUnique<char[]>(aMaxLen);
|
||||
nsresult rv = mozilla::BinaryPath::Get(aProgram, progBuf.get());
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
int len = GetDirnameSlash(progBuf.get(), aOutPath, aMaxLen);
|
||||
NS_ENSURE_TRUE(!!len, false);
|
||||
|
||||
NS_ENSURE_TRUE((len + sizeof(XPCOM_DLL)) < (unsigned)aMaxLen, false);
|
||||
char *afterSlash = aOutPath + len;
|
||||
strcpy(afterSlash, XPCOM_DLL);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
LoadLibxul(const char *aXPCOMPath)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
XPCOMGlueEnablePreload();
|
||||
rv = XPCOMGlueStartup(aXPCOMPath);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if |arg| matches the given argument name.
|
||||
*/
|
||||
static bool
|
||||
IsArg(const char* arg, const char* s)
|
||||
{
|
||||
if (*arg == '-') {
|
||||
if (*++arg == '-') {
|
||||
++arg;
|
||||
}
|
||||
return !strcasecmp(arg, s);
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
if (*arg == '/') {
|
||||
return !strcasecmp(++arg, s);
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static already_AddRefed<nsIFile>
|
||||
GetAppIni(int argc, const char *argv[])
|
||||
{
|
||||
nsCOMPtr<nsIFile> appini;
|
||||
nsresult rv;
|
||||
|
||||
// Allow firefox.exe to launch XULRunner apps via -app <application.ini>
|
||||
// Note that -app must be the *first* argument.
|
||||
const char *appDataFile = getenv("XUL_APP_FILE");
|
||||
if (appDataFile && *appDataFile) {
|
||||
rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
} else if (argc > 1 && IsArg(argv[1], "app")) {
|
||||
if (argc == 2) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(appini));
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
char appEnv[MAXPATHLEN];
|
||||
snprintf(appEnv, MAXPATHLEN, "XUL_APP_FILE=%s", argv[2]);
|
||||
if (putenv(strdup(appEnv))) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return appini.forget();
|
||||
}
|
||||
|
||||
static bool
|
||||
LoadStaticData(int argc, const char *argv[])
|
||||
{
|
||||
char xpcomPath[MAXPATHLEN];
|
||||
bool ok = GetXPCOMPath(argv[0], xpcomPath, MAXPATHLEN);
|
||||
NS_ENSURE_TRUE(ok, false);
|
||||
|
||||
ok = LoadLibxul(xpcomPath);
|
||||
NS_ENSURE_TRUE(ok, false);
|
||||
|
||||
char progDir[MAXPATHLEN];
|
||||
ok = GetDirnameSlash(xpcomPath, progDir, MAXPATHLEN);
|
||||
NS_ENSURE_TRUE(ok, false);
|
||||
|
||||
nsCOMPtr<nsIFile> appini = GetAppIni(argc, argv);
|
||||
const nsXREAppData *appData;
|
||||
if (appini) {
|
||||
nsresult rv =
|
||||
XRE_CreateAppData(appini, const_cast<nsXREAppData**>(&appData));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
} else {
|
||||
appData = &sAppData;
|
||||
}
|
||||
|
||||
XRE_ProcLoaderPreload(progDir, appData);
|
||||
|
||||
if (appini) {
|
||||
XRE_FreeAppData(const_cast<nsXREAppData*>(appData));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fork and run parent and child process.
|
||||
*
|
||||
* The parent is the b2g process and child for Nuwa.
|
||||
*/
|
||||
static int
|
||||
RunProcesses(int argc, const char *argv[], FdArray& aReservedFds)
|
||||
{
|
||||
/*
|
||||
* The original main() of the b2g process. It is renamed to
|
||||
* b2g_main() for the b2g loader.
|
||||
*/
|
||||
int b2g_main(int argc, const char *argv[]);
|
||||
|
||||
int ipcSockets[2] = {-1, -1};
|
||||
int r = socketpair(AF_LOCAL, SOCK_STREAM, 0, ipcSockets);
|
||||
ASSERT(r == 0);
|
||||
int parentSock = ipcSockets[0];
|
||||
int childSock = ipcSockets[1];
|
||||
|
||||
r = fcntl(parentSock, F_SETFL, O_NONBLOCK);
|
||||
ASSERT(r != -1);
|
||||
r = fcntl(childSock, F_SETFL, O_NONBLOCK);
|
||||
ASSERT(r != -1);
|
||||
|
||||
pid_t pid = fork();
|
||||
ASSERT(pid >= 0);
|
||||
bool isChildProcess = pid == 0;
|
||||
|
||||
close(isChildProcess ? parentSock : childSock);
|
||||
|
||||
if (isChildProcess) {
|
||||
/* The Nuwa process */
|
||||
/* This provides the IPC service of loading Nuwa at the process.
|
||||
* The b2g process would send a IPC message of loading Nuwa
|
||||
* as the replacement of forking and executing plugin-container.
|
||||
*/
|
||||
return XRE_ProcLoaderServiceRun(getppid(), childSock, argc, argv,
|
||||
aReservedFds);
|
||||
}
|
||||
|
||||
// Reap zombie child process.
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
sigaction(SIGCHLD, &sa, nullptr);
|
||||
|
||||
// The b2g process
|
||||
int childPid = pid;
|
||||
XRE_ProcLoaderClientInit(childPid, parentSock, aReservedFds);
|
||||
return b2g_main(argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reserve the file descriptors that shouldn't be taken for other use for the
|
||||
* child process.
|
||||
*/
|
||||
static void
|
||||
ReserveFileDescriptors(FdArray& aReservedFds)
|
||||
{
|
||||
for (int i = 0; i < kReservedFileDescriptors; i++) {
|
||||
struct stat fileState;
|
||||
int target = kBeginReserveFileDescriptor + i;
|
||||
if (fstat(target, &fileState) == 0) {
|
||||
MOZ_CRASH("ProcLoader error: a magic file descriptor is occupied.");
|
||||
}
|
||||
|
||||
int fd = open("/dev/null", O_RDWR);
|
||||
if (fd == -1) {
|
||||
MOZ_CRASH("ProcLoader error: failed to reserve a magic file descriptor.");
|
||||
}
|
||||
|
||||
if (!aReservedFds.append(target)) {
|
||||
MOZ_CRASH("Failed to append to aReservedFds");
|
||||
}
|
||||
|
||||
if (fd == target) {
|
||||
// No need to call dup2(). We already occupy the desired file descriptor.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dup2(fd, target)) {
|
||||
MOZ_CRASH("ProcLoader error: failed to reserve a magic file descriptor.");
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* B2G Loader is responsible for loading the b2g process and the
|
||||
* Nuwa process. It forks into the parent process, for the b2g
|
||||
* process, and the child process, for the Nuwa process.
|
||||
*
|
||||
* The loader loads libxul and performs initialization of static data
|
||||
* before forking, so relocation of libxul and static data can be
|
||||
* shared between the b2g process, the Nuwa process, and the content
|
||||
* processes.
|
||||
*/
|
||||
int
|
||||
main(int argc, const char* argv[])
|
||||
{
|
||||
/**
|
||||
* Reserve file descriptors before loading static data.
|
||||
*/
|
||||
FdArray reservedFds;
|
||||
ReserveFileDescriptors(reservedFds);
|
||||
|
||||
/*
|
||||
* Before fork(), libxul and static data of Gecko are loaded for
|
||||
* sharing.
|
||||
*/
|
||||
bool ok = LoadStaticData(argc, argv);
|
||||
if (!ok) {
|
||||
return 255;
|
||||
}
|
||||
|
||||
return RunProcesses(argc, argv, reservedFds);
|
||||
}
|
@ -8,10 +8,6 @@ if CONFIG['GAIADIR']:
|
||||
GeckoProgram(CONFIG['MOZ_APP_NAME'] + "-bin")
|
||||
else:
|
||||
GeckoProgram(CONFIG['MOZ_APP_NAME'])
|
||||
if CONFIG['MOZ_B2G_LOADER']:
|
||||
SOURCES += [
|
||||
'B2GLoader.cpp',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'nsBrowserApp.cpp',
|
||||
|
@ -163,22 +163,9 @@ static int do_main(int argc, char* argv[])
|
||||
return XRE_main(argc, argv, &sAppData, 0);
|
||||
}
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
/*
|
||||
* The main() in B2GLoader.cpp is the new main function instead of the
|
||||
* main() here if it is enabled. So, rename it to b2g_man().
|
||||
*/
|
||||
#define main b2g_main
|
||||
#define _CONST const
|
||||
#else
|
||||
#define _CONST
|
||||
#endif
|
||||
|
||||
int main(int argc, _CONST char* argv[])
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
#ifndef MOZ_B2G_LOADER
|
||||
char exePath[MAXPATHLEN];
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// This creates a ThreadPool for binder ipc. A ThreadPool is necessary to
|
||||
@ -189,7 +176,6 @@ int main(int argc, _CONST char* argv[])
|
||||
#endif
|
||||
|
||||
nsresult rv;
|
||||
#ifndef MOZ_B2G_LOADER
|
||||
rv = mozilla::BinaryPath::Get(argv[0], exePath);
|
||||
if (NS_FAILED(rv)) {
|
||||
Output("Couldn't calculate the application directory.\n");
|
||||
@ -201,7 +187,6 @@ int main(int argc, _CONST char* argv[])
|
||||
return 255;
|
||||
|
||||
strcpy(++lastSlash, XPCOM_DLL);
|
||||
#endif // MOZ_B2G_LOADER
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
// If the b2g app is launched from adb shell, then the shell will wind
|
||||
@ -216,9 +201,6 @@ int main(int argc, _CONST char* argv[])
|
||||
DllBlocklist_Initialize();
|
||||
#endif
|
||||
|
||||
// B2G loader has already initialized Gecko so we can't initialize
|
||||
// it again here.
|
||||
#ifndef MOZ_B2G_LOADER
|
||||
// We do this because of data in bug 771745
|
||||
XPCOMGlueEnablePreload();
|
||||
|
||||
@ -229,7 +211,6 @@ int main(int argc, _CONST char* argv[])
|
||||
}
|
||||
// Reset exePath so that it is the directory name and not the xpcom dll name
|
||||
*lastSlash = 0;
|
||||
#endif // MOZ_B2G_LOADER
|
||||
|
||||
rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -53,8 +53,6 @@ MOZ_TOOLKIT_SEARCH=
|
||||
MOZ_B2G=1
|
||||
|
||||
if test "$OS_TARGET" = "Android"; then
|
||||
MOZ_NUWA_PROCESS=1
|
||||
MOZ_B2G_LOADER=1
|
||||
MOZ_ENABLE_WARNINGS_AS_ERRORS=1
|
||||
fi
|
||||
|
||||
|
@ -48,8 +48,6 @@ MOZ_PLACES=
|
||||
MOZ_B2G=1
|
||||
|
||||
if test "$OS_TARGET" = "Android"; then
|
||||
MOZ_NUWA_PROCESS=1
|
||||
MOZ_B2G_LOADER=1
|
||||
MOZ_ENABLE_WARNINGS_AS_ERRORS=1
|
||||
fi
|
||||
|
||||
|
@ -166,11 +166,6 @@
|
||||
#include "nsIAccessibilityService.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
#include "NuwaChild.h"
|
||||
|
||||
#ifndef MOZ_SIMPLEPUSH
|
||||
#include "mozilla/dom/PushNotifier.h"
|
||||
#endif
|
||||
@ -516,57 +511,6 @@ NS_IMPL_ISUPPORTS(BackgroundChildPrimer, nsIIPCBackgroundChildCreateCallback)
|
||||
|
||||
ContentChild* ContentChild::sSingleton;
|
||||
|
||||
// Performs initialization that is not fork-safe, i.e. that must be done after
|
||||
// forking from the Nuwa process.
|
||||
void
|
||||
InitOnContentProcessCreated()
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// Wait until we are forked from Nuwa
|
||||
if (IsNuwaProcess()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPermissionManager> permManager = services::GetPermissionManager();
|
||||
MOZ_ASSERT(permManager, "Unable to get permission manager");
|
||||
nsresult rv = permManager->RefreshPermission();
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_ASSERT(false, "Failed updating permission in child process");
|
||||
}
|
||||
#endif
|
||||
|
||||
// This will register cross-process observer.
|
||||
mozilla::dom::time::InitializeDateCacheCleaner();
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
static void
|
||||
ResetTransports(void* aUnused)
|
||||
{
|
||||
ContentChild* child = ContentChild::GetSingleton();
|
||||
mozilla::ipc::Transport* transport = child->GetTransport();
|
||||
int fd = transport->GetFileDescriptor();
|
||||
transport->ResetFileDescriptor(fd);
|
||||
|
||||
nsTArray<IToplevelProtocol*> actors;
|
||||
child->GetOpenedActors(actors);
|
||||
for (size_t i = 0; i < actors.Length(); i++) {
|
||||
IToplevelProtocol* toplevel = actors[i];
|
||||
transport = toplevel->GetTransport();
|
||||
fd = transport->GetFileDescriptor();
|
||||
transport->ResetFileDescriptor(fd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_TASK_TRACER) && defined(MOZ_NUWA_PROCESS)
|
||||
static void
|
||||
ReinitTaskTracer(void* /*aUnused*/)
|
||||
{
|
||||
mozilla::tasktracer::InitTaskTracer(mozilla::tasktracer::FORKED_AFTER_NUWA);
|
||||
}
|
||||
#endif
|
||||
|
||||
ContentChild::ContentChild()
|
||||
: mID(uint64_t(-1))
|
||||
, mCanOverrideProcessName(true)
|
||||
@ -642,11 +586,7 @@ ContentChild::Init(MessageLoop* aIOLoop,
|
||||
|
||||
// If communications with the parent have broken down, take the process
|
||||
// down so it's not hanging around.
|
||||
bool abortOnError = true;
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
abortOnError &= !IsNuwaProcess();
|
||||
#endif
|
||||
GetIPCChannel()->SetAbortOnError(abortOnError);
|
||||
GetIPCChannel()->SetAbortOnError(true);
|
||||
|
||||
#ifdef MOZ_X11
|
||||
// Send the parent our X socket to act as a proxy reference for our X
|
||||
@ -663,17 +603,6 @@ ContentChild::Init(MessageLoop* aIOLoop,
|
||||
SendGetProcessAttributes(&mID, &mIsForApp, &mIsForBrowser);
|
||||
InitProcessAttributes();
|
||||
|
||||
#if defined(MOZ_TASK_TRACER) && defined (MOZ_NUWA_PROCESS)
|
||||
if (IsNuwaProcess()) {
|
||||
NuwaAddConstructor(ReinitTaskTracer, nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
NuwaAddConstructor(ResetTransports, nullptr);
|
||||
}
|
||||
#endif
|
||||
#ifdef NS_PRINTING
|
||||
// Force the creation of the nsPrintingProxy so that it's IPC counterpart,
|
||||
// PrintingParent, is always available for printing initiated from the parent.
|
||||
@ -687,12 +616,6 @@ void
|
||||
ContentChild::InitProcessAttributes()
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
SetProcessName(NS_LITERAL_STRING("(Nuwa)"), false);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (mIsForApp && !mIsForBrowser) {
|
||||
SetProcessName(NS_LITERAL_STRING("(Preallocated app)"), false);
|
||||
} else {
|
||||
@ -1037,7 +960,8 @@ ContentChild::InitXPCOM()
|
||||
global->SetInitialProcessData(data);
|
||||
}
|
||||
|
||||
InitOnContentProcessCreated();
|
||||
// This will register cross-process observer.
|
||||
mozilla::dom::time::InitializeDateCacheCleaner();
|
||||
}
|
||||
|
||||
PMemoryReportRequestChild*
|
||||
@ -2282,14 +2206,6 @@ ContentChild::ActorDestroy(ActorDestroyReason why)
|
||||
}
|
||||
mIsAlive = false;
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
// The Nuwa cannot go through the full XPCOM shutdown path or deadlock
|
||||
// will result.
|
||||
ProcessChild::QuickExit();
|
||||
}
|
||||
#endif
|
||||
|
||||
XRE_ShutdownChildProcess();
|
||||
#endif // NS_FREE_PERMANENT_DATA
|
||||
}
|
||||
@ -2528,9 +2444,6 @@ ContentChild::RecvAddPermission(const IPC::Permission& permission)
|
||||
bool
|
||||
ContentChild::RecvFlushMemory(const nsString& reason)
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
MOZ_ASSERT(!IsNuwaProcess() || !IsNuwaReady());
|
||||
#endif
|
||||
nsCOMPtr<nsIObserverService> os =
|
||||
mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
@ -2575,31 +2488,6 @@ ContentChild::RecvCycleCollect()
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
static void
|
||||
OnFinishNuwaPreparation()
|
||||
{
|
||||
// We want to ensure that the PBackground actor gets cloned in the Nuwa
|
||||
// process before we freeze. Also, we have to do this to avoid deadlock.
|
||||
// Protocols that are "opened" (e.g. PBackground, PCompositorBridge) block
|
||||
// the main thread to wait for the IPC thread during the open operation.
|
||||
// NuwaSpawnWait() blocks the IPC thread to wait for the main thread when
|
||||
// the Nuwa process is forked. Unless we ensure that the two cannot happen
|
||||
// at the same time then we risk deadlock. Spinning the event loop here
|
||||
// guarantees the ordering is safe for PBackground.
|
||||
while (!BackgroundChild::GetForCurrentThread()) {
|
||||
if (NS_WARN_IF(!NS_ProcessNextEvent())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// This will create the actor.
|
||||
Unused << mozilla::dom::NuwaChild::GetSingleton();
|
||||
|
||||
MakeNuwaProcess();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
PreloadSlowThings()
|
||||
{
|
||||
@ -2644,13 +2532,6 @@ ContentChild::RecvAppInit()
|
||||
PreloadSlowThings();
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
ContentChild::GetSingleton()->RecvGarbageCollect();
|
||||
MessageLoop::current()->PostTask(NewRunnableFunction(OnFinishNuwaPreparation));
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2796,9 +2677,6 @@ ContentChild::RecvNotifyProcessPriorityChanged(
|
||||
bool
|
||||
ContentChild::RecvMinimizeMemoryUsage()
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
MOZ_ASSERT(!IsNuwaProcess() || !IsNuwaReady());
|
||||
#endif
|
||||
nsCOMPtr<nsIMemoryReporterManager> mgr =
|
||||
do_GetService("@mozilla.org/memory-reporter-manager;1");
|
||||
NS_ENSURE_TRUE(mgr, true);
|
||||
|
@ -689,9 +689,6 @@ private:
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ContentChild);
|
||||
};
|
||||
|
||||
void
|
||||
InitOnContentProcessCreated();
|
||||
|
||||
uint64_t
|
||||
NextWindowID();
|
||||
|
||||
|
@ -52,7 +52,6 @@
|
||||
#include "mozilla/dom/MediaKeySystemAccess.h"
|
||||
#endif
|
||||
#include "mozilla/dom/Notification.h"
|
||||
#include "mozilla/dom/NuwaParent.h"
|
||||
#include "mozilla/dom/PContentBridgeParent.h"
|
||||
#include "mozilla/dom/PContentPermissionRequestParent.h"
|
||||
#include "mozilla/dom/PCycleCollectWithLogsParent.h"
|
||||
@ -326,11 +325,6 @@ const nsIID nsIConsoleService::COMTypeInfo<nsConsoleService, void>::kIID = NS_IC
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
int32_t ContentParent::sNuwaPid = 0;
|
||||
bool ContentParent::sNuwaReady = false;
|
||||
#endif
|
||||
|
||||
#define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
|
||||
#define NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC "ipc:network:set-connectivity"
|
||||
|
||||
@ -549,11 +543,6 @@ StaticAutoPtr<LinkedList<ContentParent> > ContentParent::sContentParents;
|
||||
UniquePtr<SandboxBrokerPolicyFactory> ContentParent::sSandboxBrokerPolicyFactory;
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// The pref updates sent to the Nuwa process.
|
||||
static nsTArray<PrefSetting>* sNuwaPrefUpdates;
|
||||
#endif
|
||||
|
||||
// This is true when subprocess launching is enabled. This is the
|
||||
// case between StartUp() and ShutDown() or JoinAllSubprocesses().
|
||||
static bool sCanLaunchSubprocesses;
|
||||
@ -601,45 +590,6 @@ static const char* sObserverTopics[] = {
|
||||
"gmp-changed",
|
||||
};
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// Contains the observer topics that can be sent to the Nuwa process after it
|
||||
// becomes ready. The ContentParent instance will unregister sObserverTopics
|
||||
// if not listed in sNuwaSafeObserverTopics.
|
||||
static const char* sNuwaSafeObserverTopics[] = {
|
||||
"xpcom-shutdown",
|
||||
"profile-before-change",
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
"phone-state-changed",
|
||||
#endif
|
||||
#ifdef ACCESSIBILITY
|
||||
"a11y-init-or-shutdown",
|
||||
#endif
|
||||
"nsPref:Changed"
|
||||
};
|
||||
#endif
|
||||
/* static */ already_AddRefed<ContentParent>
|
||||
ContentParent::RunNuwaProcess()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RefPtr<ContentParent> nuwaProcess =
|
||||
new ContentParent(/* aApp = */ nullptr,
|
||||
/* aOpener = */ nullptr,
|
||||
/* aIsForBrowser = */ false,
|
||||
/* aIsForPreallocated = */ true,
|
||||
/* aIsNuwaProcess = */ true);
|
||||
|
||||
if (!nuwaProcess->LaunchSubprocess(PROCESS_PRIORITY_BACKGROUND)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nuwaProcess->Init();
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
sNuwaPid = nuwaProcess->Pid();
|
||||
sNuwaReady = false;
|
||||
#endif
|
||||
return nuwaProcess.forget();
|
||||
}
|
||||
|
||||
// PreallocateAppProcess is called by the PreallocatedProcessManager.
|
||||
// ContentParent then takes this process back within
|
||||
// GetNewOrPreallocatedAppProcess.
|
||||
@ -691,8 +641,6 @@ ContentParent::GetNewOrPreallocatedAppProcess(mozIApplication* aApp,
|
||||
}
|
||||
}
|
||||
|
||||
// XXXkhuey Nuwa wants the frame loader to try again later, but the
|
||||
// frame loader is really not set up to do that ...
|
||||
NS_WARNING("Unable to use pre-allocated app process");
|
||||
process = new ContentParent(aApp,
|
||||
/* aOpener = */ aOpener,
|
||||
@ -912,11 +860,7 @@ ContentParent::SendAsyncUpdate(nsIWidget* aWidget)
|
||||
bool
|
||||
ContentParent::PreallocatedProcessReady()
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
return PreallocatedProcessManager::PreallocatedProcessReady();
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1534,10 +1478,7 @@ ContentParent::SetPriorityAndCheckIsAlive(ProcessPriority aPriority)
|
||||
//
|
||||
// Bug 943174: use waitid() with WNOWAIT so that, if the process
|
||||
// did exit, we won't consume its zombie and confuse the
|
||||
// GeckoChildProcessHost dtor. Also, if the process isn't a
|
||||
// direct child because of Nuwa this will fail with ECHILD, and we
|
||||
// need to assume the child is alive in that case rather than
|
||||
// assuming it's dead (as is otherwise a reasonable fallback).
|
||||
// GeckoChildProcessHost dtor.
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
siginfo_t info;
|
||||
info.si_pid = 0;
|
||||
@ -1598,14 +1539,6 @@ ContentParent::TransformPreallocatedIntoBrowser(ContentParent* aOpener)
|
||||
void
|
||||
ContentParent::ShutDownProcess(ShutDownMethod aMethod)
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (aMethod == SEND_SHUTDOWN_MESSAGE && IsNuwaProcess()) {
|
||||
// We shouldn't send shutdown messages to frozen Nuwa processes,
|
||||
// so just close the channel.
|
||||
aMethod = CLOSE_CHANNEL;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Shutting down by sending a shutdown message works differently than the
|
||||
// other methods. We first call Shutdown() in the child. After the child is
|
||||
// ready, it calls FinishShutdown() on us. Then we close the channel.
|
||||
@ -1635,13 +1568,6 @@ ContentParent::ShutDownProcess(ShutDownMethod aMethod)
|
||||
// sequence.
|
||||
mCalledClose = true;
|
||||
Close();
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// Kill Nuwa process forcibly to break its IPC channels and finalize
|
||||
// corresponding parents.
|
||||
if (IsNuwaProcess()) {
|
||||
KillHard("ShutDownProcess");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
const ManagedContainer<POfflineCacheUpdateParent>& ocuParents =
|
||||
@ -1724,10 +1650,6 @@ void
|
||||
ContentParent::OnChannelError()
|
||||
{
|
||||
RefPtr<ContentParent> content(this);
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// Handle app or Nuwa process exit before normal channel error handling.
|
||||
PreallocatedProcessManager::MaybeForgetSpare(this);
|
||||
#endif
|
||||
PContentParent::OnChannelError();
|
||||
}
|
||||
|
||||
@ -1929,14 +1851,6 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
||||
// remove the global remote preferences observers
|
||||
Preferences::RemoveObserver(this, "");
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// Remove the pref update requests.
|
||||
if (IsNuwaProcess() && sNuwaPrefUpdates) {
|
||||
delete sNuwaPrefUpdates;
|
||||
sNuwaPrefUpdates = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
RecvRemoveGeolocationListener();
|
||||
|
||||
mConsoleService = nullptr;
|
||||
@ -2198,10 +2112,6 @@ ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PR
|
||||
PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
|
||||
|
||||
std::vector<std::string> extraArgs;
|
||||
if (mIsNuwaProcess) {
|
||||
extraArgs.push_back("-nuwa");
|
||||
}
|
||||
|
||||
if (!mSubprocess->LaunchAndWaitForProcessHandle(extraArgs)) {
|
||||
MarkAsDead();
|
||||
return false;
|
||||
@ -2227,12 +2137,10 @@ ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PR
|
||||
ContentParent::ContentParent(mozIApplication* aApp,
|
||||
ContentParent* aOpener,
|
||||
bool aIsForBrowser,
|
||||
bool aIsForPreallocated,
|
||||
bool aIsNuwaProcess /* = false */)
|
||||
bool aIsForPreallocated)
|
||||
: nsIContentParent()
|
||||
, mOpener(aOpener)
|
||||
, mIsForBrowser(aIsForBrowser)
|
||||
, mIsNuwaProcess(aIsNuwaProcess)
|
||||
{
|
||||
InitializeMembers(); // Perform common initialization.
|
||||
|
||||
@ -2240,20 +2148,13 @@ ContentParent::ContentParent(mozIApplication* aApp,
|
||||
// true.
|
||||
MOZ_ASSERT(!!aApp + aIsForBrowser + aIsForPreallocated <= 1);
|
||||
|
||||
// Only the preallocated process uses Nuwa.
|
||||
MOZ_ASSERT_IF(aIsNuwaProcess, aIsForPreallocated);
|
||||
|
||||
if (!aIsNuwaProcess && !aIsForPreallocated) {
|
||||
mMetamorphosed = true;
|
||||
}
|
||||
mMetamorphosed = true;
|
||||
|
||||
// Insert ourselves into the global linked list of ContentParent objects.
|
||||
if (!sContentParents) {
|
||||
sContentParents = new LinkedList<ContentParent>();
|
||||
}
|
||||
if (!aIsNuwaProcess) {
|
||||
sContentParents->insertBack(this);
|
||||
}
|
||||
sContentParents->insertBack(this);
|
||||
|
||||
if (aApp) {
|
||||
aApp->GetManifestURL(mAppManifestURL);
|
||||
@ -2274,83 +2175,10 @@ ContentParent::ContentParent(mozIApplication* aApp,
|
||||
#endif
|
||||
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
ChildPrivileges privs = aIsNuwaProcess
|
||||
? base::PRIVILEGES_INHERIT
|
||||
: base::PRIVILEGES_DEFAULT;
|
||||
ChildPrivileges privs = base::PRIVILEGES_DEFAULT;
|
||||
mSubprocess = new GeckoChildProcessHost(GeckoProcessType_Content, privs);
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
static const mozilla::ipc::FileDescriptor*
|
||||
FindFdProtocolFdMapping(const nsTArray<ProtocolFdMapping>& aFds,
|
||||
ProtocolId aProtoId)
|
||||
{
|
||||
for (unsigned int i = 0; i < aFds.Length(); i++) {
|
||||
if (aFds[i].protocolId() == aProtoId) {
|
||||
return &aFds[i].fd();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor is used for new content process cloned from a template.
|
||||
*
|
||||
* For Nuwa.
|
||||
*/
|
||||
ContentParent::ContentParent(ContentParent* aTemplate,
|
||||
const nsAString& aAppManifestURL,
|
||||
base::ProcessHandle aPid,
|
||||
InfallibleTArray<ProtocolFdMapping>&& aFds)
|
||||
: mAppManifestURL(aAppManifestURL)
|
||||
, mIsForBrowser(false)
|
||||
, mIsNuwaProcess(false)
|
||||
{
|
||||
InitializeMembers(); // Perform common initialization.
|
||||
|
||||
sContentParents->insertBack(this);
|
||||
|
||||
// From this point on, NS_WARNING, NS_ASSERTION, etc. should print out the
|
||||
// PID along with the warning.
|
||||
nsDebugImpl::SetMultiprocessMode("Parent");
|
||||
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
const FileDescriptor* fd = FindFdProtocolFdMapping(aFds, GetProtocolId());
|
||||
|
||||
NS_ASSERTION(fd != nullptr, "IPC Channel for PContent is necessary!");
|
||||
mSubprocess = new GeckoExistingProcessHost(GeckoProcessType_Content,
|
||||
aPid, *fd);
|
||||
|
||||
mSubprocess->LaunchAndWaitForProcessHandle();
|
||||
|
||||
// Clone actors routed by aTemplate for this instance.
|
||||
ProtocolCloneContext cloneContext;
|
||||
cloneContext.SetContentParent(this);
|
||||
CloneManagees(aTemplate, &cloneContext);
|
||||
CloneOpenedToplevels(aTemplate, aFds, aPid, &cloneContext);
|
||||
|
||||
Open(mSubprocess->GetChannel(),
|
||||
base::GetProcId(mSubprocess->GetChildProcessHandle()));
|
||||
|
||||
// Set the subprocess's priority (bg if we're a preallocated process, fg
|
||||
// otherwise). We do this first because we're likely /lowering/ its CPU and
|
||||
// memory priority, which it has inherited from this process.
|
||||
ProcessPriority priority;
|
||||
if (IsPreallocated()) {
|
||||
priority = PROCESS_PRIORITY_PREALLOC;
|
||||
} else {
|
||||
priority = PROCESS_PRIORITY_FOREGROUND;
|
||||
}
|
||||
|
||||
InitInternal(priority,
|
||||
false, /* Setup Off-main thread compositing */
|
||||
false /* Send registered chrome */);
|
||||
|
||||
ContentProcessManager::GetSingleton()->AddContentProcess(this);
|
||||
}
|
||||
#endif // MOZ_NUWA_PROCESS
|
||||
|
||||
ContentParent::~ContentParent()
|
||||
{
|
||||
if (mForceKillTimer) {
|
||||
@ -2372,13 +2200,6 @@ ContentParent::~ContentParent()
|
||||
MOZ_ASSERT(!sAppContentParents ||
|
||||
sAppContentParents->Get(mAppManifestURL) != this);
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
sNuwaReady = false;
|
||||
sNuwaPid = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -2491,11 +2312,6 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
|
||||
|
||||
#ifdef MOZ_CONTENT_SANDBOX
|
||||
bool shouldSandbox = true;
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
shouldSandbox = false;
|
||||
}
|
||||
#endif
|
||||
MaybeFileDesc brokerFd = void_t();
|
||||
#ifdef XP_LINUX
|
||||
// XXX: Checking the pref here makes it possible to enable/disable sandboxing
|
||||
@ -2566,14 +2382,6 @@ ContentParent::IsForApp() const
|
||||
return !mAppManifestURL.IsEmpty();
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
bool
|
||||
ContentParent::IsNuwaProcess() const
|
||||
{
|
||||
return mIsNuwaProcess;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t
|
||||
ContentParent::Pid() const
|
||||
{
|
||||
@ -2880,125 +2688,6 @@ ContentParent::RecvAudioChannelServiceStatus(
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::ForkNewProcess(bool aBlocking)
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
uint32_t pid;
|
||||
auto fds = MakeUnique<nsTArray<ProtocolFdMapping>>();
|
||||
|
||||
MOZ_ASSERT(IsNuwaProcess() && mNuwaParent);
|
||||
|
||||
if (mNuwaParent->ForkNewProcess(pid, mozilla::Move(fds), aBlocking)) {
|
||||
OnNewProcessCreated(pid, mozilla::Move(fds));
|
||||
}
|
||||
#else
|
||||
NS_ERROR("ContentParent::ForkNewProcess() not implemented!");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// Keep only observer topics listed in sNuwaSafeObserverTopics and unregister
|
||||
// all the other registered topics.
|
||||
static void
|
||||
KeepNuwaSafeObserverTopics(ContentParent* aNuwaContentParent)
|
||||
{
|
||||
MOZ_ASSERT(aNuwaContentParent && aNuwaContentParent->IsNuwaProcess());
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (!obs) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t topicLength = ArrayLength(sObserverTopics);
|
||||
for (size_t i = 0; i < topicLength; ++i) {
|
||||
bool nuwaSafe = false;
|
||||
size_t safeTopicLength = ArrayLength(sNuwaSafeObserverTopics);
|
||||
|
||||
for (size_t j = 0; j < safeTopicLength; j++) {
|
||||
if (!nsCRT::strcmp(sObserverTopics[i],
|
||||
sNuwaSafeObserverTopics[j])) {
|
||||
// In the whitelist: don't need to unregister.
|
||||
nuwaSafe = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nuwaSafe) {
|
||||
obs->RemoveObserver(aNuwaContentParent, sObserverTopics[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
ContentParent::OnNuwaReady()
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// Protection from unauthorized IPC message is done in PNuwa protocol.
|
||||
// Just assert that this actor is really for the Nuwa process.
|
||||
MOZ_ASSERT(IsNuwaProcess());
|
||||
|
||||
sNuwaReady = true;
|
||||
KeepNuwaSafeObserverTopics(this);
|
||||
|
||||
PreallocatedProcessManager::OnNuwaReady();
|
||||
return;
|
||||
#else
|
||||
NS_ERROR("ContentParent::OnNuwaReady() not implemented!");
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::OnNewProcessCreated(uint32_t aPid,
|
||||
UniquePtr<nsTArray<ProtocolFdMapping>>&& aFds)
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// Protection from unauthorized IPC message is done in PNuwa protocol.
|
||||
// Just assert that this actor is really for the Nuwa process.
|
||||
MOZ_ASSERT(IsNuwaProcess());
|
||||
|
||||
RefPtr<ContentParent> content;
|
||||
content = new ContentParent(this,
|
||||
MAGIC_PREALLOCATED_APP_MANIFEST_URL,
|
||||
aPid,
|
||||
Move(*aFds.get()));
|
||||
content->Init();
|
||||
|
||||
size_t numNuwaPrefUpdates = sNuwaPrefUpdates ?
|
||||
sNuwaPrefUpdates->Length() : 0;
|
||||
// Resend pref updates to the forked child.
|
||||
for (size_t i = 0; i < numNuwaPrefUpdates; i++) {
|
||||
mozilla::Unused << content->SendPreferenceUpdate(sNuwaPrefUpdates->ElementAt(i));
|
||||
}
|
||||
|
||||
// Update offline settings.
|
||||
bool isOffline, isLangRTL, haveBidiKeyboards;
|
||||
bool isConnected;
|
||||
InfallibleTArray<nsString> unusedDictionaries;
|
||||
ClipboardCapabilities clipboardCaps;
|
||||
DomainPolicyClone domainPolicy;
|
||||
StructuredCloneData initialData;
|
||||
|
||||
RecvGetXPCOMProcessAttributes(&isOffline, &isConnected,
|
||||
&isLangRTL, &haveBidiKeyboards,
|
||||
&unusedDictionaries,
|
||||
&clipboardCaps, &domainPolicy, &initialData);
|
||||
mozilla::Unused << content->SendSetOffline(isOffline);
|
||||
mozilla::Unused << content->SendSetConnectivity(isConnected);
|
||||
MOZ_ASSERT(!clipboardCaps.supportsSelectionClipboard() &&
|
||||
!clipboardCaps.supportsFindClipboard(),
|
||||
"Unexpected values");
|
||||
|
||||
PreallocatedProcessManager::PublishSpareProcess(content);
|
||||
return;
|
||||
#else
|
||||
NS_ERROR("ContentParent::OnNewProcessCreated() not implemented!");
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
// We want ContentParent to show up in CC logs for debugging purposes, but we
|
||||
// don't actually cycle collect it.
|
||||
NS_IMPL_CYCLE_COLLECTION_0(ContentParent)
|
||||
@ -3057,16 +2746,6 @@ ContentParent::Observe(nsISupports* aSubject,
|
||||
if (!mIsAlive || !mSubprocess)
|
||||
return NS_OK;
|
||||
|
||||
// The Nuwa process unregisters the topics after it becomes ready except for
|
||||
// the ones listed in sNuwaSafeObserverTopics. If the topic needs to be
|
||||
// observed by the Nuwa process, either for:
|
||||
// 1. The topic is safe for the Nuwa process, either:
|
||||
// 1.1 The state can safely happen (only run on the main thread) in the Nuwa
|
||||
// process (e.g. "a11y-init-or-shutdown"), or
|
||||
// 1.2 The topic doesn't send an IPC message (e.g. "xpcom-shutdown").
|
||||
// 2. The topic needs special handling (e.g. nsPref:Changed),
|
||||
// add the topic to sNuwaSafeObserverTopics and then handle it if necessary.
|
||||
|
||||
// listening for memory pressure event
|
||||
if (!strcmp(aTopic, "memory-pressure") &&
|
||||
!StringEndsWith(nsDependentString(aData),
|
||||
@ -3080,22 +2759,9 @@ ContentParent::Observe(nsISupports* aSubject,
|
||||
|
||||
PrefSetting pref(strData, null_t(), null_t());
|
||||
Preferences::GetPreference(&pref);
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsReadyNuwaProcess()) {
|
||||
// Don't send the pref update to the Nuwa process. Save the update
|
||||
// to send to the forked child.
|
||||
if (!sNuwaPrefUpdates) {
|
||||
sNuwaPrefUpdates = new nsTArray<PrefSetting>();
|
||||
}
|
||||
sNuwaPrefUpdates->AppendElement(pref);
|
||||
} else if (!SendPreferenceUpdate(pref)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
#else
|
||||
if (!SendPreferenceUpdate(pref)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC)) {
|
||||
NS_ConvertUTF16toUTF8 dataStr(aData);
|
||||
@ -3524,11 +3190,6 @@ void
|
||||
ContentParent::FriendlyName(nsAString& aName, bool aAnonymize)
|
||||
{
|
||||
aName.Truncate();
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
aName.AssignLiteral("(Nuwa)");
|
||||
} else
|
||||
#endif
|
||||
if (IsPreallocated()) {
|
||||
aName.AssignLiteral("(Preallocated)");
|
||||
} else if (mIsForBrowser) {
|
||||
@ -4642,10 +4303,6 @@ ContentParent::DoSendAsyncMessage(JSContext* aCx,
|
||||
if (aCpows && (!mgr || !mgr->Wrap(aCx, aCpows, &cpows))) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
if (IsReadyNuwaProcess()) {
|
||||
// Nuwa won't receive frame messages after it is frozen.
|
||||
return NS_OK;
|
||||
}
|
||||
if (!SendAsyncMessage(nsString(aMessage), cpows, Principal(aPrincipal), data)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
#ifndef mozilla_dom_ContentParent_h
|
||||
#define mozilla_dom_ContentParent_h
|
||||
|
||||
#include "mozilla/dom/NuwaParent.h"
|
||||
#include "mozilla/dom/PContentParent.h"
|
||||
#include "mozilla/dom/nsIContentParent.h"
|
||||
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
||||
@ -101,17 +100,6 @@ class ContentParent final : public PContentParent
|
||||
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
|
||||
|
||||
public:
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
static int32_t NuwaPid()
|
||||
{
|
||||
return sNuwaPid;
|
||||
}
|
||||
|
||||
static bool IsNuwaReady()
|
||||
{
|
||||
return sNuwaReady;
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual bool IsContentParent() const override { return true; }
|
||||
|
||||
@ -151,8 +139,6 @@ public:
|
||||
*/
|
||||
static already_AddRefed<ContentParent> PreallocateAppProcess();
|
||||
|
||||
static already_AddRefed<ContentParent> RunNuwaProcess();
|
||||
|
||||
/**
|
||||
* Get or create a content process for the given TabContext. aFrameElement
|
||||
* should be the frame/iframe element with which this process will
|
||||
@ -367,20 +353,6 @@ public:
|
||||
return mIsForBrowser;
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
bool IsNuwaProcess() const;
|
||||
#endif
|
||||
|
||||
// A shorthand for checking if the Nuwa process is ready.
|
||||
bool IsReadyNuwaProcess() const
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
return IsNuwaProcess() && IsNuwaReady();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
GeckoChildProcessHost* Process() const
|
||||
{
|
||||
return mSubprocess;
|
||||
@ -547,8 +519,6 @@ public:
|
||||
|
||||
virtual bool HandleWindowsMessages(const Message& aMsg) const override;
|
||||
|
||||
void SetNuwaParent(NuwaParent* aNuwaParent) { mNuwaParent = aNuwaParent; }
|
||||
|
||||
void ForkNewProcess(bool aBlocking);
|
||||
|
||||
virtual bool RecvCreateWindow(PBrowserParent* aThisTabParent,
|
||||
@ -596,8 +566,6 @@ protected:
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) override;
|
||||
|
||||
void OnNuwaForkTimeout();
|
||||
|
||||
bool ShouldContinueFromReplyTimeout() override;
|
||||
|
||||
private:
|
||||
@ -644,15 +612,7 @@ private:
|
||||
ContentParent(mozIApplication* aApp,
|
||||
ContentParent* aOpener,
|
||||
bool aIsForBrowser,
|
||||
bool aIsForPreallocated,
|
||||
bool aIsNuwaProcess = false);
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
ContentParent(ContentParent* aTemplate,
|
||||
const nsAString& aAppManifestURL,
|
||||
base::ProcessHandle aPid,
|
||||
InfallibleTArray<ProtocolFdMapping>&& aFds);
|
||||
#endif
|
||||
bool aIsForPreallocated);
|
||||
|
||||
// The common initialization for the constructors.
|
||||
void InitializeMembers();
|
||||
@ -1061,11 +1021,6 @@ private:
|
||||
|
||||
virtual bool RecvSpeakerManagerForceSpeaker(const bool& aEnable) override;
|
||||
|
||||
// Callbacks from NuwaParent.
|
||||
void OnNuwaReady();
|
||||
void OnNewProcessCreated(uint32_t aPid,
|
||||
UniquePtr<nsTArray<ProtocolFdMapping>>&& aFds);
|
||||
|
||||
virtual bool RecvCreateFakeVolume(const nsString& aFsName,
|
||||
const nsString& aMountPoint) override;
|
||||
|
||||
@ -1229,7 +1184,6 @@ private:
|
||||
|
||||
bool mSendPermissionUpdates;
|
||||
bool mIsForBrowser;
|
||||
bool mIsNuwaProcess;
|
||||
|
||||
// These variables track whether we've called Close() and KillHard() on our
|
||||
// channel.
|
||||
@ -1241,9 +1195,6 @@ private:
|
||||
|
||||
friend class CrashReporterParent;
|
||||
|
||||
// Allows NuwaParent to access OnNuwaReady() and OnNewProcessCreated().
|
||||
friend class NuwaParent;
|
||||
|
||||
RefPtr<nsConsoleService> mConsoleService;
|
||||
nsConsoleService* GetConsoleService();
|
||||
|
||||
@ -1255,17 +1206,8 @@ private:
|
||||
ScopedClose mChildXSocketFdDup;
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
static int32_t sNuwaPid;
|
||||
static bool sNuwaReady;
|
||||
#endif
|
||||
|
||||
PProcessHangMonitorParent* mHangMonitorActor;
|
||||
|
||||
// NuwaParent and ContentParent hold strong references to each other. The
|
||||
// cycle will be broken when either actor is destroyed.
|
||||
RefPtr<NuwaParent> mNuwaParent;
|
||||
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
RefPtr<mozilla::ProfileGatherer> mGatherer;
|
||||
#endif
|
||||
|
@ -1,256 +0,0 @@
|
||||
/* -*- 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 "ContentChild.h"
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
#if defined(XP_LINUX)
|
||||
#include "mozilla/Sandbox.h"
|
||||
#include "mozilla/SandboxInfo.h"
|
||||
#elif defined(XP_MACOSX)
|
||||
#include "mozilla/Sandbox.h"
|
||||
#endif
|
||||
#endif
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "NuwaChild.h"
|
||||
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
|
||||
namespace {
|
||||
|
||||
class CallNuwaSpawn: public Runnable
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
NuwaSpawn();
|
||||
if (IsNuwaProcess()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// In the new process.
|
||||
ContentChild* child = ContentChild::GetSingleton();
|
||||
child->InitProcessAttributes();
|
||||
|
||||
// Perform other after-fork initializations.
|
||||
InitOnContentProcessCreated();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
static void
|
||||
DoNuwaFork()
|
||||
{
|
||||
NuwaSpawnPrepare(); // NuwaSpawn will be blocked.
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> callSpawn(new CallNuwaSpawn());
|
||||
NS_DispatchToMainThread(callSpawn);
|
||||
}
|
||||
|
||||
// IOThread should be blocked here for waiting NuwaSpawn().
|
||||
NuwaSpawnWait(); // Now! NuwaSpawn can go.
|
||||
// Here, we can make sure the spawning was finished.
|
||||
}
|
||||
|
||||
/**
|
||||
* This function should keep IO thread in a stable state and freeze it
|
||||
* until the spawning is finished.
|
||||
*/
|
||||
static void
|
||||
RunNuwaFork()
|
||||
{
|
||||
if (NuwaCheckpointCurrentThread()) {
|
||||
DoNuwaFork();
|
||||
}
|
||||
}
|
||||
|
||||
static bool sNuwaForking = false;
|
||||
|
||||
void
|
||||
NuwaFork()
|
||||
{
|
||||
if (sNuwaForking) { // No reentry.
|
||||
return;
|
||||
}
|
||||
sNuwaForking = true;
|
||||
|
||||
MessageLoop* ioloop = XRE_GetIOMessageLoop();
|
||||
ioloop->PostTask(NewRunnableFunction(RunNuwaFork));
|
||||
}
|
||||
|
||||
} // Anonymous namespace.
|
||||
|
||||
#endif
|
||||
|
||||
NuwaChild* NuwaChild::sSingleton;
|
||||
|
||||
NuwaChild*
|
||||
NuwaChild::GetSingleton()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!sSingleton) {
|
||||
PNuwaChild* nuwaChild =
|
||||
BackgroundChild::GetForCurrentThread()->SendPNuwaConstructor();
|
||||
MOZ_ASSERT(nuwaChild);
|
||||
|
||||
sSingleton = static_cast<NuwaChild*>(nuwaChild);
|
||||
}
|
||||
|
||||
return sSingleton;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
NuwaChild::RecvFork()
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (!IsNuwaProcess()) {
|
||||
NS_ERROR(
|
||||
nsPrintfCString(
|
||||
"Terminating child process %d for unauthorized IPC message: "
|
||||
"RecvFork(%d)", getpid()).get());
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
NS_NewRunnableFunction(&NuwaFork);
|
||||
MOZ_ASSERT(runnable);
|
||||
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
|
||||
|
||||
return true;
|
||||
#else
|
||||
NS_ERROR("NuwaChild::RecvFork() not implemented!");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
#if defined(MOZ_NUWA_PROCESS)
|
||||
NS_EXPORT void
|
||||
GetProtoFdInfos(NuwaProtoFdInfo* aInfoList,
|
||||
size_t aInfoListSize,
|
||||
size_t* aInfoSize)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
mozilla::dom::ContentChild* content =
|
||||
mozilla::dom::ContentChild::GetSingleton();
|
||||
aInfoList[i].protoId = content->GetProtocolId();
|
||||
aInfoList[i].originFd =
|
||||
content->GetTransport()->GetFileDescriptor();
|
||||
i++;
|
||||
|
||||
IToplevelProtocol* actors[NUWA_TOPLEVEL_MAX];
|
||||
size_t count = content->GetOpenedActorsUnsafe(actors, ArrayLength(actors));
|
||||
for (size_t j = 0; j < count; j++) {
|
||||
IToplevelProtocol* actor = actors[j];
|
||||
if (i >= aInfoListSize) {
|
||||
NS_RUNTIMEABORT("Too many top level protocols!");
|
||||
}
|
||||
|
||||
aInfoList[i].protoId = actor->GetProtocolId();
|
||||
aInfoList[i].originFd =
|
||||
actor->GetTransport()->GetFileDescriptor();
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i > NUWA_TOPLEVEL_MAX) {
|
||||
NS_RUNTIMEABORT("Too many top level protocols!");
|
||||
}
|
||||
*aInfoSize = i;
|
||||
}
|
||||
|
||||
class RunAddNewIPCProcess : public mozilla::Runnable
|
||||
{
|
||||
public:
|
||||
RunAddNewIPCProcess(pid_t aPid,
|
||||
nsTArray<mozilla::ipc::ProtocolFdMapping>& aMaps)
|
||||
: mPid(aPid)
|
||||
{
|
||||
mMaps.SwapElements(aMaps);
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
NuwaChild::GetSingleton()->SendAddNewProcess(mPid, mMaps);
|
||||
|
||||
MOZ_ASSERT(sNuwaForking);
|
||||
sNuwaForking = false;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
pid_t mPid;
|
||||
nsTArray<mozilla::ipc::ProtocolFdMapping> mMaps;
|
||||
};
|
||||
|
||||
/**
|
||||
* AddNewIPCProcess() is called by Nuwa process to tell the parent
|
||||
* process that a new process is created.
|
||||
*
|
||||
* In the newly created process, ResetContentChildTransport() is called to
|
||||
* reset fd for the IPC Channel and the session.
|
||||
*/
|
||||
NS_EXPORT void
|
||||
AddNewIPCProcess(pid_t aPid, NuwaProtoFdInfo* aInfoList, size_t aInfoListSize)
|
||||
{
|
||||
nsTArray<mozilla::ipc::ProtocolFdMapping> maps;
|
||||
|
||||
for (size_t i = 0; i < aInfoListSize; i++) {
|
||||
int _fd = aInfoList[i].newFds[NUWA_NEWFD_PARENT];
|
||||
mozilla::ipc::FileDescriptor fd(_fd);
|
||||
mozilla::ipc::ProtocolFdMapping map(aInfoList[i].protoId, fd);
|
||||
maps.AppendElement(map);
|
||||
}
|
||||
|
||||
RefPtr<RunAddNewIPCProcess> runner = new RunAddNewIPCProcess(aPid, maps);
|
||||
NS_DispatchToMainThread(runner);
|
||||
}
|
||||
|
||||
NS_EXPORT void
|
||||
OnNuwaProcessReady()
|
||||
{
|
||||
NuwaChild* nuwaChild = NuwaChild::GetSingleton();
|
||||
MOZ_ASSERT(nuwaChild);
|
||||
|
||||
mozilla::Unused << nuwaChild->SendNotifyReady();
|
||||
}
|
||||
|
||||
NS_EXPORT void
|
||||
AfterNuwaFork()
|
||||
{
|
||||
SetCurrentProcessPrivileges(base::PRIVILEGES_DEFAULT);
|
||||
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
|
||||
mozilla::SandboxEarlyInit(XRE_GetProcessType(), /* isNuwa: */ false);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // MOZ_NUWA_PROCESS
|
||||
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
/* -*- 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 mozilla_dom_NuwaChild_h
|
||||
#define mozilla_dom_NuwaChild_h
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/dom/PNuwaChild.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class NuwaChild: public mozilla::dom::PNuwaChild
|
||||
{
|
||||
public:
|
||||
virtual bool RecvFork() override;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override
|
||||
{ }
|
||||
|
||||
static NuwaChild* GetSingleton();
|
||||
|
||||
private:
|
||||
static NuwaChild* sSingleton;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_NuwaChild_h
|
@ -1,260 +0,0 @@
|
||||
/* -*- 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 "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "mozilla/ipc/PBackgroundParent.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "NuwaParent.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::dom;
|
||||
using namespace IPC;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/*static*/ NuwaParent*
|
||||
NuwaParent::Alloc() {
|
||||
RefPtr<NuwaParent> actor = new NuwaParent();
|
||||
return actor.forget().take();
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
NuwaParent::ActorConstructed(mozilla::dom::PNuwaParent *aActor)
|
||||
{
|
||||
NuwaParent* actor = static_cast<NuwaParent*>(aActor);
|
||||
actor->ActorConstructed();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
NuwaParent::Dealloc(mozilla::dom::PNuwaParent *aActor)
|
||||
{
|
||||
RefPtr<NuwaParent> actor = dont_AddRef(static_cast<NuwaParent*>(aActor));
|
||||
return true;
|
||||
}
|
||||
|
||||
NuwaParent::NuwaParent()
|
||||
: mBlocked(false)
|
||||
, mMonitor("NuwaParent")
|
||||
, mClonedActor(nullptr)
|
||||
, mWorkerThread(do_GetCurrentThread())
|
||||
, mNewProcessPid(0)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
|
||||
NuwaParent::~NuwaParent()
|
||||
{
|
||||
// Both the worker thread and the main thread (ContentParent) hold a ref to
|
||||
// this. The instance may be destroyed on either thread.
|
||||
MOZ_ASSERT(!mContentParent);
|
||||
}
|
||||
|
||||
inline void
|
||||
NuwaParent::AssertIsOnWorkerThread()
|
||||
{
|
||||
nsCOMPtr<nsIThread> currentThread = do_GetCurrentThread();
|
||||
MOZ_ASSERT(currentThread == mWorkerThread);
|
||||
}
|
||||
|
||||
bool
|
||||
NuwaParent::ActorConstructed()
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
MOZ_ASSERT(Manager());
|
||||
MOZ_ASSERT(!mContentParent);
|
||||
|
||||
mContentParent = BackgroundParent::GetContentParent(Manager());
|
||||
if (!mContentParent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// mContentParent is guaranteed to be alive. It's safe to set its backward ref
|
||||
// to this.
|
||||
mContentParent->SetNuwaParent(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IProtocol*
|
||||
NuwaParent::CloneProtocol(Channel* aChannel,
|
||||
ProtocolCloneContext* aCtx)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RefPtr<NuwaParent> self = this;
|
||||
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
// Alloc NuwaParent on the worker thread.
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([self] () -> void
|
||||
{
|
||||
MonitorAutoLock lock(self->mMonitor);
|
||||
// XXX Calling NuwaParent::Alloc() leads to a compilation error. Use
|
||||
// self->Alloc() as a workaround.
|
||||
self->mClonedActor = self->Alloc();
|
||||
lock.Notify();
|
||||
});
|
||||
MOZ_ASSERT(runnable);
|
||||
MOZ_ALWAYS_SUCCEEDS(mWorkerThread->Dispatch(runnable, NS_DISPATCH_NORMAL));
|
||||
|
||||
while (!mClonedActor) {
|
||||
lock.Wait();
|
||||
}
|
||||
RefPtr<NuwaParent> actor = mClonedActor;
|
||||
mClonedActor = nullptr;
|
||||
|
||||
// mManager of the cloned actor is assigned after returning from this method.
|
||||
// We can't call ActorConstructed() right after Alloc() in the above runnable.
|
||||
// To be safe we dispatch a runnable to the current thread to do it.
|
||||
runnable = NS_NewRunnableFunction([actor] () -> void
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIRunnable> nested = NS_NewRunnableFunction([actor] () -> void
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
// Call NuwaParent::ActorConstructed() on the worker thread.
|
||||
actor->ActorConstructed();
|
||||
|
||||
// The actor can finally be deleted after fully constructed.
|
||||
mozilla::Unused << actor->Send__delete__(actor);
|
||||
});
|
||||
MOZ_ASSERT(nested);
|
||||
MOZ_ALWAYS_SUCCEEDS(actor->mWorkerThread->Dispatch(nested, NS_DISPATCH_NORMAL));
|
||||
});
|
||||
|
||||
MOZ_ASSERT(runnable);
|
||||
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
||||
void
|
||||
NuwaParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
|
||||
RefPtr<NuwaParent> self = this;
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([self] () -> void
|
||||
{
|
||||
// These extra nsRefPtr serve as kungFuDeathGrip to keep both objects from
|
||||
// deletion in breaking the ref cycle.
|
||||
RefPtr<ContentParent> contentParent = self->mContentParent;
|
||||
|
||||
contentParent->SetNuwaParent(nullptr);
|
||||
// Need to clear the ref to ContentParent on the main thread.
|
||||
self->mContentParent = nullptr;
|
||||
});
|
||||
MOZ_ASSERT(runnable);
|
||||
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
|
||||
}
|
||||
|
||||
bool
|
||||
NuwaParent::RecvNotifyReady()
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (!mContentParent || !mContentParent->IsNuwaProcess()) {
|
||||
NS_ERROR("Received NotifyReady() message from a non-Nuwa process.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Creating a NonOwningRunnableMethod here is safe because refcount changes of
|
||||
// mContentParent have to go the the main thread. The mContentParent will
|
||||
// be alive when the runnable runs.
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
NewNonOwningRunnableMethod(mContentParent.get(),
|
||||
&ContentParent::OnNuwaReady);
|
||||
MOZ_ASSERT(runnable);
|
||||
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
|
||||
|
||||
return true;
|
||||
#else
|
||||
NS_ERROR("NuwaParent::RecvNotifyReady() not implemented!");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
NuwaParent::RecvAddNewProcess(const uint32_t& aPid,
|
||||
nsTArray<ProtocolFdMapping>&& aFds)
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (!mContentParent || !mContentParent->IsNuwaProcess()) {
|
||||
NS_ERROR("Received AddNewProcess() message from a non-Nuwa process.");
|
||||
return false;
|
||||
}
|
||||
|
||||
mNewProcessPid = aPid;
|
||||
mNewProcessFds->SwapElements(aFds);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (mBlocked) {
|
||||
// Unblock ForkNewProcess().
|
||||
mMonitor.Notify();
|
||||
mBlocked = false;
|
||||
} else {
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
NewNonOwningRunnableMethod<
|
||||
uint32_t,
|
||||
UniquePtr<nsTArray<ProtocolFdMapping>>&& >(
|
||||
mContentParent.get(),
|
||||
&ContentParent::OnNewProcessCreated,
|
||||
mNewProcessPid,
|
||||
Move(mNewProcessFds));
|
||||
MOZ_ASSERT(runnable);
|
||||
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
NS_ERROR("NuwaParent::RecvAddNewProcess() not implemented!");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
NuwaParent::ForkNewProcess(uint32_t& aPid,
|
||||
UniquePtr<nsTArray<ProtocolFdMapping>>&& aFds,
|
||||
bool aBlocking)
|
||||
{
|
||||
MOZ_ASSERT(mWorkerThread);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mNewProcessFds = Move(aFds);
|
||||
|
||||
RefPtr<NuwaParent> self = this;
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([self] () -> void
|
||||
{
|
||||
mozilla::Unused << self->SendFork();
|
||||
});
|
||||
MOZ_ASSERT(runnable);
|
||||
MOZ_ALWAYS_SUCCEEDS(mWorkerThread->Dispatch(runnable, NS_DISPATCH_NORMAL));
|
||||
if (!aBlocking) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mBlocked = true;
|
||||
while (mBlocked) {
|
||||
// This will be notified in NuwaParent::RecvAddNewProcess().
|
||||
lock.Wait();
|
||||
}
|
||||
|
||||
if (!mNewProcessPid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aPid = mNewProcessPid;
|
||||
aFds = Move(mNewProcessFds);
|
||||
|
||||
mNewProcessPid = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
@ -1,73 +0,0 @@
|
||||
/* -*- 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 mozilla_dom_NuwaParent_h
|
||||
#define mozilla_dom_NuwaParent_h
|
||||
|
||||
#include "base/message_loop.h"
|
||||
#include "mozilla/dom/PNuwaParent.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ContentParent;
|
||||
|
||||
class NuwaParent : public mozilla::dom::PNuwaParent
|
||||
{
|
||||
public:
|
||||
explicit NuwaParent();
|
||||
|
||||
// Called on the main thread.
|
||||
bool ForkNewProcess(uint32_t& aPid,
|
||||
UniquePtr<nsTArray<ProtocolFdMapping>>&& aFds,
|
||||
bool aBlocking);
|
||||
|
||||
// Called on the background thread.
|
||||
bool ActorConstructed();
|
||||
|
||||
// Both the worker thread and the main thread hold a ref to this.
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NuwaParent)
|
||||
|
||||
// Functions to be invoked by the manager of this actor to alloc/dealloc the
|
||||
// actor.
|
||||
static NuwaParent* Alloc();
|
||||
static bool ActorConstructed(mozilla::dom::PNuwaParent *aActor);
|
||||
static bool Dealloc(mozilla::dom::PNuwaParent *aActor);
|
||||
|
||||
protected:
|
||||
virtual ~NuwaParent();
|
||||
|
||||
virtual bool RecvNotifyReady() override;
|
||||
virtual bool RecvAddNewProcess(const uint32_t& aPid,
|
||||
nsTArray<ProtocolFdMapping>&& aFds) override;
|
||||
virtual mozilla::ipc::IProtocol*
|
||||
CloneProtocol(Channel* aChannel,
|
||||
ProtocolCloneContext* aCtx) override;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
private:
|
||||
void AssertIsOnWorkerThread();
|
||||
|
||||
bool mBlocked;
|
||||
mozilla::Monitor mMonitor;
|
||||
NuwaParent* mClonedActor;
|
||||
|
||||
nsCOMPtr<nsIThread> mWorkerThread;
|
||||
|
||||
uint32_t mNewProcessPid;
|
||||
UniquePtr<nsTArray<ProtocolFdMapping>> mNewProcessFds;
|
||||
|
||||
// The mutual reference will be broken on the main thread.
|
||||
RefPtr<ContentParent> mContentParent;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_NuwaParent_h
|
@ -1,31 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 protocol PBackground;
|
||||
include ProtocolTypes;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
sync protocol PNuwa
|
||||
{
|
||||
manager PBackground;
|
||||
|
||||
child:
|
||||
// Ask the Nuwa process to create a new child process.
|
||||
async Fork();
|
||||
|
||||
// This message will be sent to non-Nuwa process, or to Nuwa process during
|
||||
// test.
|
||||
async __delete__();
|
||||
|
||||
parent:
|
||||
async NotifyReady();
|
||||
sync AddNewProcess(uint32_t pid, ProtocolFdMapping[] aFds);
|
||||
};
|
||||
|
||||
} // namespace layout
|
||||
} // namespace mozilla
|
||||
|
@ -14,19 +14,10 @@
|
||||
#include "ProcessPriorityManager.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
#include "ProcessUtils.h"
|
||||
#endif
|
||||
|
||||
// This number is fairly arbitrary ... the intention is to put off
|
||||
// launching another app process until the last one has finished
|
||||
// loading its content, to reduce CPU/memory/IO contention.
|
||||
#define DEFAULT_ALLOCATE_DELAY 1000
|
||||
#define NUWA_FORK_WAIT_DURATION_MS 2000 // 2 seconds.
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::hal;
|
||||
@ -53,31 +44,6 @@ public:
|
||||
void AllocateNow();
|
||||
already_AddRefed<ContentParent> Take();
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
public:
|
||||
void ScheduleDelayedNuwaFork();
|
||||
void DelayedNuwaFork();
|
||||
void PublishSpareProcess(ContentParent* aContent);
|
||||
void MaybeForgetSpare(ContentParent* aContent);
|
||||
bool IsNuwaReady();
|
||||
void OnNuwaReady();
|
||||
bool PreallocatedProcessReady();
|
||||
already_AddRefed<ContentParent> GetSpareProcess();
|
||||
|
||||
private:
|
||||
void NuwaFork();
|
||||
|
||||
// initialization off the critical path of app startup.
|
||||
CancelableRunnable* mPreallocateAppProcessTask;
|
||||
|
||||
// The array containing the preallocated processes. 4 as the inline storage size
|
||||
// should be enough so we don't need to grow the AutoTArray.
|
||||
AutoTArray<RefPtr<ContentParent>, 4> mSpareProcesses;
|
||||
|
||||
// Nuwa process is ready for creating new process.
|
||||
bool mIsNuwaReady;
|
||||
#endif
|
||||
|
||||
private:
|
||||
static mozilla::StaticRefPtr<PreallocatedProcessManagerImpl> sSingleton;
|
||||
|
||||
@ -117,11 +83,6 @@ NS_IMPL_ISUPPORTS(PreallocatedProcessManagerImpl, nsIObserver)
|
||||
|
||||
PreallocatedProcessManagerImpl::PreallocatedProcessManagerImpl()
|
||||
:
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
mPreallocateAppProcessTask(nullptr)
|
||||
, mIsNuwaReady(false)
|
||||
,
|
||||
#endif
|
||||
mEnabled(false)
|
||||
, mShutdown(false)
|
||||
{}
|
||||
@ -137,11 +98,6 @@ PreallocatedProcessManagerImpl::Init()
|
||||
os->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
|
||||
/* weakRef = */ false);
|
||||
}
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
if (!mozilla::ipc::ProcLoaderIsInitialized()) {
|
||||
Disable();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
RereadPrefs();
|
||||
}
|
||||
@ -190,11 +146,7 @@ PreallocatedProcessManagerImpl::Enable()
|
||||
}
|
||||
|
||||
mEnabled = true;
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
ScheduleDelayedNuwaFork();
|
||||
#else
|
||||
AllocateAfterDelay();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -230,174 +182,6 @@ PreallocatedProcessManagerImpl::AllocateNow()
|
||||
mPreallocatedAppProcess = ContentParent::PreallocateAppProcess();
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
|
||||
void
|
||||
PreallocatedProcessManagerImpl::ScheduleDelayedNuwaFork()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mPreallocateAppProcessTask) {
|
||||
// Make sure there is only one request running.
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<CancelableRunnable> task = NewCancelableRunnableMethod(
|
||||
this, &PreallocatedProcessManagerImpl::DelayedNuwaFork);
|
||||
mPreallocateAppProcessTask = task;
|
||||
MessageLoop::current()->PostDelayedTask(task.forget(),
|
||||
Preferences::GetUint("dom.ipc.processPrelaunch.delayMs",
|
||||
DEFAULT_ALLOCATE_DELAY));
|
||||
}
|
||||
|
||||
void
|
||||
PreallocatedProcessManagerImpl::DelayedNuwaFork()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mPreallocateAppProcessTask = nullptr;
|
||||
|
||||
if (!mIsNuwaReady) {
|
||||
if (!mPreallocatedAppProcess && !mShutdown && mEnabled) {
|
||||
mPreallocatedAppProcess = ContentParent::RunNuwaProcess();
|
||||
}
|
||||
// else mPreallocatedAppProcess is starting. It will NuwaFork() when ready.
|
||||
} else if (mSpareProcesses.IsEmpty()) {
|
||||
NuwaFork();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a spare ContentParent from mSpareProcesses list.
|
||||
*/
|
||||
already_AddRefed<ContentParent>
|
||||
PreallocatedProcessManagerImpl::GetSpareProcess()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mIsNuwaReady) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mSpareProcesses.IsEmpty()) {
|
||||
// After this call, there should be a spare process.
|
||||
mPreallocatedAppProcess->ForkNewProcess(true);
|
||||
}
|
||||
|
||||
RefPtr<ContentParent> process = mSpareProcesses.LastElement();
|
||||
mSpareProcesses.RemoveElementAt(mSpareProcesses.Length() - 1);
|
||||
|
||||
if (mSpareProcesses.IsEmpty() && mIsNuwaReady) {
|
||||
NS_ASSERTION(mPreallocatedAppProcess != nullptr,
|
||||
"Nuwa process is not present!");
|
||||
ScheduleDelayedNuwaFork();
|
||||
}
|
||||
|
||||
return process.forget();
|
||||
}
|
||||
|
||||
static bool
|
||||
TestCaseEnabled()
|
||||
{
|
||||
return Preferences::GetBool("dom.ipc.preallocatedProcessManager.testMode");
|
||||
}
|
||||
|
||||
static void
|
||||
SendTestOnlyNotification(const char* aMessage)
|
||||
{
|
||||
if (!TestCaseEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
nsString message;
|
||||
message.AppendPrintf("%s", aMessage);
|
||||
|
||||
nsCOMPtr<nsIMessageBroadcaster> ppmm =
|
||||
do_GetService("@mozilla.org/parentprocessmessagemanager;1");
|
||||
|
||||
mozilla::Unused << ppmm->BroadcastAsyncMessage(
|
||||
message, JS::NullHandleValue, JS::NullHandleValue, cx, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
KillOrCloseProcess(ContentParent* aProcess)
|
||||
{
|
||||
if (TestCaseEnabled()) {
|
||||
// KillHard() the process because we don't want the process to abort when we
|
||||
// close the IPC channel while it's still running and creating actors.
|
||||
aProcess->KillHard("Killed by test case.");
|
||||
}
|
||||
else {
|
||||
aProcess->Close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a ContentParent to spare process list.
|
||||
*/
|
||||
void
|
||||
PreallocatedProcessManagerImpl::PublishSpareProcess(ContentParent* aContent)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
SendTestOnlyNotification("TEST-ONLY:nuwa-add-new-process");
|
||||
|
||||
mSpareProcesses.AppendElement(aContent);
|
||||
}
|
||||
|
||||
void
|
||||
PreallocatedProcessManagerImpl::MaybeForgetSpare(ContentParent* aContent)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mSpareProcesses.RemoveElement(aContent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aContent == mPreallocatedAppProcess) {
|
||||
mPreallocatedAppProcess = nullptr;
|
||||
mIsNuwaReady = false;
|
||||
while (mSpareProcesses.Length() > 0) {
|
||||
RefPtr<ContentParent> process = mSpareProcesses[mSpareProcesses.Length() - 1];
|
||||
KillOrCloseProcess(aContent);
|
||||
mSpareProcesses.RemoveElementAt(mSpareProcesses.Length() - 1);
|
||||
}
|
||||
ScheduleDelayedNuwaFork();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
PreallocatedProcessManagerImpl::IsNuwaReady()
|
||||
{
|
||||
return mIsNuwaReady;
|
||||
}
|
||||
|
||||
void
|
||||
PreallocatedProcessManagerImpl::OnNuwaReady()
|
||||
{
|
||||
NS_ASSERTION(!mIsNuwaReady, "Multiple Nuwa processes created!");
|
||||
ProcessPriorityManager::SetProcessPriority(mPreallocatedAppProcess,
|
||||
hal::PROCESS_PRIORITY_MASTER);
|
||||
mIsNuwaReady = true;
|
||||
SendTestOnlyNotification("TEST-ONLY:nuwa-ready");
|
||||
|
||||
NuwaFork();
|
||||
}
|
||||
|
||||
bool
|
||||
PreallocatedProcessManagerImpl::PreallocatedProcessReady()
|
||||
{
|
||||
return !mSpareProcesses.IsEmpty();
|
||||
}
|
||||
|
||||
void
|
||||
PreallocatedProcessManagerImpl::NuwaFork()
|
||||
{
|
||||
mPreallocatedAppProcess->ForkNewProcess(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
PreallocatedProcessManagerImpl::Disable()
|
||||
{
|
||||
@ -407,23 +191,7 @@ PreallocatedProcessManagerImpl::Disable()
|
||||
|
||||
mEnabled = false;
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// Cancel pending fork.
|
||||
if (mPreallocateAppProcessTask) {
|
||||
mPreallocateAppProcessTask->Cancel();
|
||||
mPreallocateAppProcessTask = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mPreallocatedAppProcess) {
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
while (mSpareProcesses.Length() > 0){
|
||||
RefPtr<ContentParent> process = mSpareProcesses[0];
|
||||
KillOrCloseProcess(process);
|
||||
mSpareProcesses.RemoveElementAt(0);
|
||||
}
|
||||
mIsNuwaReady = false;
|
||||
#endif
|
||||
mPreallocatedAppProcess->Close();
|
||||
mPreallocatedAppProcess = nullptr;
|
||||
}
|
||||
@ -460,11 +228,7 @@ namespace mozilla {
|
||||
/* static */ void
|
||||
PreallocatedProcessManager::AllocateAfterDelay()
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
GetPPMImpl()->ScheduleDelayedNuwaFork();
|
||||
#else
|
||||
GetPPMImpl()->AllocateAfterDelay();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
@ -482,44 +246,7 @@ PreallocatedProcessManager::AllocateNow()
|
||||
/* static */ already_AddRefed<ContentParent>
|
||||
PreallocatedProcessManager::Take()
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
return GetPPMImpl()->GetSpareProcess();
|
||||
#else
|
||||
return GetPPMImpl()->Take();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
/* static */ void
|
||||
PreallocatedProcessManager::PublishSpareProcess(ContentParent* aContent)
|
||||
{
|
||||
GetPPMImpl()->PublishSpareProcess(aContent);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
PreallocatedProcessManager::MaybeForgetSpare(ContentParent* aContent)
|
||||
{
|
||||
GetPPMImpl()->MaybeForgetSpare(aContent);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
PreallocatedProcessManager::OnNuwaReady()
|
||||
{
|
||||
GetPPMImpl()->OnNuwaReady();
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
PreallocatedProcessManager::IsNuwaReady()
|
||||
{
|
||||
return GetPPMImpl()->IsNuwaReady();
|
||||
}
|
||||
|
||||
/*static */ bool
|
||||
PreallocatedProcessManager::PreallocatedProcessReady()
|
||||
{
|
||||
return GetPPMImpl()->PreallocatedProcessReady();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -78,14 +78,6 @@ public:
|
||||
*/
|
||||
static already_AddRefed<ContentParent> Take();
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
static void PublishSpareProcess(ContentParent* aContent);
|
||||
static void MaybeForgetSpare(ContentParent* aContent);
|
||||
static bool IsNuwaReady();
|
||||
static void OnNuwaReady();
|
||||
static bool PreallocatedProcessReady();
|
||||
#endif
|
||||
|
||||
private:
|
||||
PreallocatedProcessManager();
|
||||
DISALLOW_EVIL_CONSTRUCTORS(PreallocatedProcessManager);
|
||||
|
@ -526,13 +526,6 @@ already_AddRefed<ParticularProcessPriorityManager>
|
||||
ProcessPriorityManagerImpl::GetParticularProcessPriorityManager(
|
||||
ContentParent* aContentParent)
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// Do not attempt to change the priority of the Nuwa process
|
||||
if (aContentParent->IsNuwaProcess()) {
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
RefPtr<ParticularProcessPriorityManager> pppm;
|
||||
uint64_t cpId = aContentParent->ChildID();
|
||||
mParticularManagers.Get(cpId, &pppm);
|
||||
|
@ -24,9 +24,6 @@
|
||||
#include "mozilla/IMEStateManager.h"
|
||||
#include "mozilla/ipc/DocumentRendererChild.h"
|
||||
#include "mozilla/ipc/URIUtils.h"
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
#include "mozilla/ipc/FileDescriptorUtils.h"
|
||||
#include "mozilla/layers/APZChild.h"
|
||||
#include "mozilla/layers/APZCCallbackHelper.h"
|
||||
@ -456,41 +453,6 @@ PreloadSlowThingsPostFork(void* aUnused)
|
||||
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
class MessageChannelAutoBlock MOZ_STACK_CLASS
|
||||
{
|
||||
public:
|
||||
MessageChannelAutoBlock()
|
||||
{
|
||||
SetMessageChannelBlocked(true);
|
||||
}
|
||||
|
||||
~MessageChannelAutoBlock()
|
||||
{
|
||||
SetMessageChannelBlocked(false);
|
||||
}
|
||||
|
||||
private:
|
||||
void SetMessageChannelBlocked(bool aBlock)
|
||||
{
|
||||
if (!IsNuwaProcess()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mozilla::dom::ContentChild* content =
|
||||
mozilla::dom::ContentChild::GetSingleton();
|
||||
if (aBlock) {
|
||||
content->GetIPCChannel()->Block();
|
||||
} else {
|
||||
content->GetIPCChannel()->Unblock();
|
||||
}
|
||||
|
||||
// Other IPC channels do not perform the checks through Block() and
|
||||
// Unblock().
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
static bool sPreloaded = false;
|
||||
|
||||
/*static*/ void
|
||||
@ -513,12 +475,6 @@ TabChild::PreloadSlowThings()
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// Temporarily block the IPC channels to the chrome process when we are
|
||||
// preloading.
|
||||
MessageChannelAutoBlock autoblock;
|
||||
#endif
|
||||
|
||||
// Just load and compile these scripts, but don't run them.
|
||||
tab->TryCacheLoadAndCompileScript(BROWSER_ELEMENT_CHILD_SCRIPT, true);
|
||||
// Load, compile, and run these scripts.
|
||||
@ -529,15 +485,7 @@ TabChild::PreloadSlowThings()
|
||||
sPreallocatedTab = tab;
|
||||
ClearOnShutdown(&sPreallocatedTab);
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
NuwaAddFinalConstructor(PreloadSlowThingsPostFork, nullptr);
|
||||
} else {
|
||||
PreloadSlowThingsPostFork(nullptr);
|
||||
}
|
||||
#else
|
||||
PreloadSlowThingsPostFork(nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*static*/ already_AddRefed<TabChild>
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mozIApplication.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsPIWindowRoot.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "nsPrincipal.h"
|
||||
#include "nsIPromptFactory.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsIXULBrowserWindow.h"
|
||||
#include "nsIXULWindow.h"
|
||||
@ -108,6 +109,8 @@ using namespace mozilla::widget;
|
||||
using namespace mozilla::jsipc;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
using mozilla::Unused;
|
||||
|
||||
// The flags passed by the webProgress notifications are 16 bits shifted
|
||||
// from the ones registered by webProgressListeners.
|
||||
#define NOTIFY_FLAG_SHIFT 16
|
||||
|
@ -35,8 +35,6 @@ EXPORTS.mozilla.dom += [
|
||||
'FilePickerParent.h',
|
||||
'nsIContentChild.h',
|
||||
'nsIContentParent.h',
|
||||
'NuwaChild.h',
|
||||
'NuwaParent.h',
|
||||
'PermissionMessageUtils.h',
|
||||
'TabChild.h',
|
||||
'TabContext.h',
|
||||
@ -65,8 +63,6 @@ UNIFIED_SOURCES += [
|
||||
'FilePickerParent.cpp',
|
||||
'nsIContentChild.cpp',
|
||||
'nsIContentParent.cpp',
|
||||
'NuwaChild.cpp',
|
||||
'NuwaParent.cpp',
|
||||
'PermissionMessageUtils.cpp',
|
||||
'PreallocatedProcessManager.cpp',
|
||||
'ProcessPriorityManager.cpp',
|
||||
@ -107,7 +103,6 @@ IPDL_SOURCES += [
|
||||
'PDocumentRenderer.ipdl',
|
||||
'PFilePicker.ipdl',
|
||||
'PMemoryReportRequest.ipdl',
|
||||
'PNuwa.ipdl',
|
||||
'PPluginWidget.ipdl',
|
||||
'PProcessHangMonitor.ipdl',
|
||||
'PScreenManager.ipdl',
|
||||
|
@ -13,10 +13,6 @@ skip-if = buildapp == 'b2g' || buildapp == 'mulet' || e10s
|
||||
skip-if = buildapp == 'b2g' || e10s || toolkit == 'android'
|
||||
[test_cpow_cookies.html]
|
||||
skip-if = buildapp == 'b2g' || buildapp == 'mulet'
|
||||
[test_NuwaProcessCreation.html]
|
||||
skip-if = toolkit != 'gonk'
|
||||
[test_NuwaProcessDeadlock.html]
|
||||
skip-if = toolkit != 'gonk'
|
||||
[test_child_docshell.html]
|
||||
skip-if = toolkit == 'cocoa' # disabled due to hangs, see changeset 6852e7c47edf
|
||||
[test_CrashService_crash.html]
|
||||
|
@ -1,68 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test if Nuwa process created successfully.
|
||||
-->
|
||||
<head>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="setup()">
|
||||
|
||||
<script type="application/javascript;version=1.7">
|
||||
"use strict";
|
||||
|
||||
function runTest()
|
||||
{
|
||||
info("Shut down processes by disabling process prelaunch");
|
||||
SpecialPowers.setBoolPref('dom.ipc.processPrelaunch.enabled', false);
|
||||
|
||||
info("Launch the Nuwa process");
|
||||
let cpmm = SpecialPowers.Cc["@mozilla.org/childprocessmessagemanager;1"]
|
||||
.getService(SpecialPowers.Ci.nsISyncMessageSender);
|
||||
let seenNuwaReady = false;
|
||||
let msgHandler = {
|
||||
receiveMessage: function receiveMessage(msg) {
|
||||
msg = SpecialPowers.wrap(msg);
|
||||
if (msg.name == 'TEST-ONLY:nuwa-ready') {
|
||||
is(seenNuwaReady, false, "The Nuwa process is launched");
|
||||
seenNuwaReady = true;
|
||||
} else if (msg.name == 'TEST-ONLY:nuwa-add-new-process') {
|
||||
ok(true, "Got nuwa-add-new-process");
|
||||
is(seenNuwaReady, true, "The preallocated process is launched from the Nuwa process");
|
||||
shutdown();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function shutdown() {
|
||||
info("Shut down the test case");
|
||||
cpmm.removeMessageListener("TEST-ONLY:nuwa-ready", msgHandler);
|
||||
cpmm.removeMessageListener("TEST-ONLY:nuwa-add-new-process", msgHandler);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
cpmm.addMessageListener("TEST-ONLY:nuwa-ready", msgHandler);
|
||||
cpmm.addMessageListener("TEST-ONLY:nuwa-add-new-process", msgHandler);
|
||||
|
||||
|
||||
// Setting this pref to true should cause us to prelaunch a process.
|
||||
SpecialPowers.setBoolPref('dom.ipc.processPrelaunch.enabled', true);
|
||||
}
|
||||
|
||||
function setup()
|
||||
{
|
||||
info("Set up preferences for testing the Nuwa process.");
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv({
|
||||
'set': [
|
||||
['dom.ipc.preallocatedProcessManager.testMode', true]
|
||||
]
|
||||
}, runTest);
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,69 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test if Nuwa process created successfully.
|
||||
-->
|
||||
<head>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="setup()">
|
||||
|
||||
<script type="application/javascript;version=1.7">
|
||||
"use strict";
|
||||
|
||||
function runTest()
|
||||
{
|
||||
info("Shut down processes by disabling process prelaunch");
|
||||
SpecialPowers.setBoolPref('dom.ipc.processPrelaunch.enabled', false);
|
||||
|
||||
info("Launch the Nuwa process");
|
||||
let cpmm = SpecialPowers.Cc["@mozilla.org/childprocessmessagemanager;1"]
|
||||
.getService(SpecialPowers.Ci.nsISyncMessageSender);
|
||||
let seenNuwaReady = false;
|
||||
let msgHandler = {
|
||||
receiveMessage: function receiveMessage(msg) {
|
||||
msg = SpecialPowers.wrap(msg);
|
||||
if (msg.name == 'TEST-ONLY:nuwa-ready') {
|
||||
is(seenNuwaReady, false, "The Nuwa process is launched");
|
||||
seenNuwaReady = true;
|
||||
} else if (msg.name == 'TEST-ONLY:nuwa-add-new-process') {
|
||||
ok(true, "Got nuwa-add-new-process");
|
||||
is(seenNuwaReady, true, "The preallocated process is launched from the Nuwa process");
|
||||
shutdown();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function shutdown() {
|
||||
info("Shut down the test case");
|
||||
cpmm.removeMessageListener("TEST-ONLY:nuwa-ready", msgHandler);
|
||||
cpmm.removeMessageListener("TEST-ONLY:nuwa-add-new-process", msgHandler);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
cpmm.addMessageListener("TEST-ONLY:nuwa-ready", msgHandler);
|
||||
cpmm.addMessageListener("TEST-ONLY:nuwa-add-new-process", msgHandler);
|
||||
|
||||
|
||||
// Setting this pref to true should cause us to prelaunch a process.
|
||||
SpecialPowers.setBoolPref('dom.ipc.processPrelaunch.enabled', true);
|
||||
}
|
||||
|
||||
function setup()
|
||||
{
|
||||
info("Set up preferences for testing the Nuwa process.");
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv({
|
||||
'set': [
|
||||
['dom.ipc.preallocatedProcessManager.testMode', true],
|
||||
['dom.ipc.processPrelaunch.testMode', true] // For testing deadlock
|
||||
]
|
||||
}, runTest);
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -615,16 +615,9 @@ DOMStorageDBParent::Observe(const char* aTopic,
|
||||
const nsACString& aOriginScope)
|
||||
{
|
||||
if (mIPCOpen) {
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (!(static_cast<ContentParent*>(Manager())->IsNuwaProcess() &&
|
||||
ContentParent::IsNuwaReady())) {
|
||||
#endif
|
||||
mozilla::Unused << SendObserve(nsDependentCString(aTopic),
|
||||
nsString(aOriginAttributesPattern),
|
||||
nsCString(aOriginScope));
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -59,10 +59,6 @@
|
||||
#include "OSFileConstants.h"
|
||||
#include "xpcpublic.h"
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
#include "Principal.h"
|
||||
#include "SharedWorker.h"
|
||||
#include "WorkerDebuggerManager.h"
|
||||
@ -2494,13 +2490,6 @@ WorkerThreadPrimaryRunnable::Run()
|
||||
{
|
||||
using mozilla::ipc::BackgroundChild;
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
NuwaMarkCurrentThread(nullptr, nullptr);
|
||||
NuwaFreezeCurrentThread();
|
||||
}
|
||||
#endif
|
||||
|
||||
char stackBaseGuess;
|
||||
|
||||
PR_SetCurrentThreadName("DOM Worker");
|
||||
|
@ -564,10 +564,6 @@ bool ImageBridgeChild::IsCreated()
|
||||
return GetSingleton() != nullptr;
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
static void ReleaseImageClientNow(ImageClient* aClient,
|
||||
PImageContainerChild* aChild)
|
||||
{
|
||||
|
@ -14,10 +14,6 @@
|
||||
#include "mozilla/ReentrantMonitor.h" // for ReentrantMonitor, etc
|
||||
#include "nsThreadUtils.h" // fo NS_IsMainThread
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "SBMChild", ## args)
|
||||
#endif
|
||||
@ -103,14 +99,6 @@ ConnectSharedBufferManagerInChildProcess(mozilla::ipc::Transport* aTransport,
|
||||
XRE_GetIOMessageLoop(),
|
||||
ipc::ChildSide);
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
SharedBufferManagerChild::sSharedBufferManagerChildThread
|
||||
->message_loop()->PostTask(NewRunnableFunction(NuwaMarkCurrentThread,
|
||||
(void (*)(void *))nullptr,
|
||||
(void *)nullptr));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
PSharedBufferManagerChild*
|
||||
|
@ -17,10 +17,6 @@
|
||||
#include "nsXPCOMCIDInternal.h"
|
||||
#include "prsystem.h"
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
#include "gfxPrefs.h"
|
||||
|
||||
#include "Decoder.h"
|
||||
@ -69,12 +65,6 @@ public:
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
mThreadNaming.SetThreadPoolName(NS_LITERAL_CSTRING("ImgDecoder"));
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
NuwaMarkCurrentThread(static_cast<void(*)(void*)>(nullptr), nullptr);
|
||||
}
|
||||
#endif // MOZ_NUWA_PROCESS
|
||||
}
|
||||
|
||||
/// Shut down the provided decode pool thread.
|
||||
@ -271,15 +261,6 @@ DecodePool::DecodePool()
|
||||
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv) && mIOThread,
|
||||
"Should successfully create image I/O thread");
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
rv = mIOThread->Dispatch(NS_NewRunnableFunction([]() -> void {
|
||||
NuwaMarkCurrentThread(static_cast<void(*)(void*)>(nullptr), nullptr);
|
||||
}), NS_DISPATCH_NORMAL);
|
||||
|
||||
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv),
|
||||
"Should register decode IO thread with Nuwa process");
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
|
||||
if (obsSvc) {
|
||||
obsSvc->AddObserver(this, "xpcom-shutdown-threads", false);
|
||||
|
@ -24,12 +24,6 @@
|
||||
#include "prenv.h"
|
||||
#include "prmem.h"
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
#include "ProcessUtils.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
#endif // MOZ_B2G_LOADER
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
/*
|
||||
* AID_APP is the first application UID used by Android. We're using
|
||||
@ -160,71 +154,12 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
||||
wait, process_handle);
|
||||
}
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
/**
|
||||
* Launch an app using B2g Loader.
|
||||
*/
|
||||
static bool
|
||||
LaunchAppProcLoader(const std::vector<std::string>& argv,
|
||||
const file_handle_mapping_vector& fds_to_remap,
|
||||
const environment_map& env_vars_to_set,
|
||||
ChildPrivileges privs,
|
||||
ProcessHandle* process_handle) {
|
||||
size_t i;
|
||||
mozilla::UniquePtr<char*[]> argv_cstr(new char*[argv.size() + 1]);
|
||||
for (i = 0; i < argv.size(); i++) {
|
||||
argv_cstr[i] = const_cast<char*>(argv[i].c_str());
|
||||
}
|
||||
argv_cstr[argv.size()] = nullptr;
|
||||
|
||||
mozilla::UniquePtr<char*[]> env_cstr(new char*[env_vars_to_set.size() + 1]);
|
||||
i = 0;
|
||||
for (environment_map::const_iterator it = env_vars_to_set.begin();
|
||||
it != env_vars_to_set.end(); ++it) {
|
||||
env_cstr[i++] = strdup((it->first + "=" + it->second).c_str());
|
||||
}
|
||||
env_cstr[env_vars_to_set.size()] = nullptr;
|
||||
|
||||
bool ok = ProcLoaderLoad((const char **)argv_cstr.get(),
|
||||
(const char **)env_cstr.get(),
|
||||
fds_to_remap, privs,
|
||||
process_handle);
|
||||
MOZ_ASSERT(ok, "ProcLoaderLoad() failed");
|
||||
|
||||
for (size_t i = 0; i < env_vars_to_set.size(); i++) {
|
||||
free(env_cstr[i]);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsLaunchingNuwa(const std::vector<std::string>& argv) {
|
||||
std::vector<std::string>::const_iterator it;
|
||||
for (it = argv.begin(); it != argv.end(); ++it) {
|
||||
if (*it == std::string("-nuwa")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif // MOZ_B2G_LOADER
|
||||
|
||||
bool LaunchApp(const std::vector<std::string>& argv,
|
||||
const file_handle_mapping_vector& fds_to_remap,
|
||||
const environment_map& env_vars_to_set,
|
||||
ChildPrivileges privs,
|
||||
bool wait, ProcessHandle* process_handle,
|
||||
ProcessArchitecture arch) {
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
static bool beforeFirstNuwaLaunch = true;
|
||||
if (!wait && beforeFirstNuwaLaunch && IsLaunchingNuwa(argv)) {
|
||||
beforeFirstNuwaLaunch = false;
|
||||
return LaunchAppProcLoader(argv, fds_to_remap, env_vars_to_set,
|
||||
privs, process_handle);
|
||||
}
|
||||
#endif // MOZ_B2G_LOADER
|
||||
|
||||
mozilla::UniquePtr<char*[]> argv_cstr(new char*[argv.size() + 1]);
|
||||
// Illegal to allocate memory after fork and before execvp
|
||||
InjectiveMultimap fd_shuffle1, fd_shuffle2;
|
||||
|
@ -23,17 +23,8 @@ ChildThread::ChildThread(Thread::Options options)
|
||||
ChildThread::~ChildThread() {
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
bool ChildThread::Run() {
|
||||
bool r = StartWithOptions(options_);
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
message_loop()->PostTask(NewRunnableFunction(&ChildThread::MarkThread));
|
||||
}
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -42,15 +33,6 @@ void ChildThread::OnChannelError() {
|
||||
owner_loop_->PostTask(task.forget());
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
void ChildThread::MarkThread() {
|
||||
NuwaMarkCurrentThread(nullptr, nullptr);
|
||||
if (!NuwaCheckpointCurrentThread()) {
|
||||
NS_RUNTIMEABORT("Should not be here!");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void ChildThread::OnMessageReceived(IPC::Message&& msg) {
|
||||
}
|
||||
|
||||
|
@ -42,10 +42,6 @@ class ChildThread : public IPC::Channel::Listener,
|
||||
virtual void OnMessageReceived(IPC::Message&& msg);
|
||||
virtual void OnChannelError();
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
static void MarkThread();
|
||||
#endif
|
||||
|
||||
// The message loop used to run tasks on the thread that started this thread.
|
||||
MessageLoop* owner_loop_;
|
||||
|
||||
|
@ -5,8 +5,6 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
Library('plugin-container')
|
||||
if CONFIG['MOZ_B2G_LOADER']:
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
SOURCES += [
|
||||
'plugin-container.cpp',
|
||||
|
@ -55,11 +55,6 @@
|
||||
|
||||
#endif // MOZ_WIDGET_GONK
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include <binder/ProcessState.h>
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
static void
|
||||
InitializeBinder(void *aDummy) {
|
||||
@ -150,11 +145,6 @@ content_process_main(int argc, char* argv[])
|
||||
return 3;
|
||||
}
|
||||
|
||||
bool isNuwa = false;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
isNuwa |= strcmp(argv[i], "-nuwa") == 0;
|
||||
}
|
||||
|
||||
XREChildData childData;
|
||||
|
||||
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
||||
@ -171,20 +161,11 @@ content_process_main(int argc, char* argv[])
|
||||
|
||||
XRE_SetProcessType(argv[--argc]);
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (isNuwa) {
|
||||
PrepareNuwaProcess();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
|
||||
// This has to happen while we're still single-threaded, and on
|
||||
// B2G that means before the Android Binder library is
|
||||
// initialized. Additional special handling is needed for Nuwa:
|
||||
// the Nuwa process itself needs to be unsandboxed, and the same
|
||||
// single-threadedness condition applies to its children; see also
|
||||
// AfterNuwaFork().
|
||||
mozilla::SandboxEarlyInit(XRE_GetProcessType(), isNuwa);
|
||||
// initialized.
|
||||
mozilla::SandboxEarlyInit(XRE_GetProcessType());
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
@ -193,16 +174,8 @@ content_process_main(int argc, char* argv[])
|
||||
// ProcessState::Self() also needs to be called once on the main thread to
|
||||
// register the main thread with the binder driver.
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (!isNuwa) {
|
||||
InitializeBinder(nullptr);
|
||||
} else {
|
||||
NuwaAddFinalConstructor(&InitializeBinder, nullptr);
|
||||
}
|
||||
#else
|
||||
InitializeBinder(nullptr);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
// For plugins, this is done in PluginProcessChild::Init, as we need to
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "mozilla/dom/GamepadTestChannelChild.h"
|
||||
#endif
|
||||
#include "mozilla/dom/MessagePortChild.h"
|
||||
#include "mozilla/dom/NuwaChild.h"
|
||||
#include "mozilla/ipc/PBackgroundTestChild.h"
|
||||
#include "mozilla/ipc/PSendStreamChild.h"
|
||||
#include "mozilla/layout/VsyncChild.h"
|
||||
@ -75,7 +74,6 @@ using mozilla::dom::asmjscache::PAsmJSCacheEntryChild;
|
||||
using mozilla::dom::cache::PCacheChild;
|
||||
using mozilla::dom::cache::PCacheStorageChild;
|
||||
using mozilla::dom::cache::PCacheStreamControlChild;
|
||||
using mozilla::dom::PNuwaChild;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// BackgroundChildImpl::ThreadLocal
|
||||
@ -409,21 +407,6 @@ BackgroundChildImpl::DeallocPMessagePortChild(PMessagePortChild* aActor)
|
||||
return true;
|
||||
}
|
||||
|
||||
PNuwaChild*
|
||||
BackgroundChildImpl::AllocPNuwaChild()
|
||||
{
|
||||
return new mozilla::dom::NuwaChild();
|
||||
}
|
||||
|
||||
bool
|
||||
BackgroundChildImpl::DeallocPNuwaChild(PNuwaChild* aActor)
|
||||
{
|
||||
MOZ_ASSERT(aActor);
|
||||
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
PSendStreamChild*
|
||||
BackgroundChildImpl::AllocPSendStreamChild()
|
||||
{
|
||||
|
@ -140,12 +140,6 @@ protected:
|
||||
virtual bool
|
||||
DeallocPMessagePortChild(PMessagePortChild* aActor) override;
|
||||
|
||||
virtual PNuwaChild*
|
||||
AllocPNuwaChild() override;
|
||||
|
||||
virtual bool
|
||||
DeallocPNuwaChild(PNuwaChild* aActor) override;
|
||||
|
||||
virtual PSendStreamChild*
|
||||
AllocPSendStreamChild() override;
|
||||
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "mozilla/dom/GamepadEventChannelParent.h"
|
||||
#include "mozilla/dom/GamepadTestChannelParent.h"
|
||||
#endif
|
||||
#include "mozilla/dom/NuwaParent.h"
|
||||
#include "mozilla/dom/PBlobParent.h"
|
||||
#include "mozilla/dom/PGamepadEventChannelParent.h"
|
||||
#include "mozilla/dom/PGamepadTestChannelParent.h"
|
||||
@ -66,9 +65,7 @@ using mozilla::dom::cache::PCacheStreamControlParent;
|
||||
using mozilla::dom::FileSystemBase;
|
||||
using mozilla::dom::FileSystemRequestParent;
|
||||
using mozilla::dom::MessagePortParent;
|
||||
using mozilla::dom::NuwaParent;
|
||||
using mozilla::dom::PMessagePortParent;
|
||||
using mozilla::dom::PNuwaParent;
|
||||
using mozilla::dom::UDPSocketParent;
|
||||
|
||||
namespace {
|
||||
@ -297,24 +294,6 @@ BackgroundParentImpl::DeallocPFileDescriptorSetParent(
|
||||
return true;
|
||||
}
|
||||
|
||||
PNuwaParent*
|
||||
BackgroundParentImpl::AllocPNuwaParent()
|
||||
{
|
||||
return mozilla::dom::NuwaParent::Alloc();
|
||||
}
|
||||
|
||||
bool
|
||||
BackgroundParentImpl::RecvPNuwaConstructor(PNuwaParent* aActor)
|
||||
{
|
||||
return mozilla::dom::NuwaParent::ActorConstructed(aActor);
|
||||
}
|
||||
|
||||
bool
|
||||
BackgroundParentImpl::DeallocPNuwaParent(PNuwaParent *aActor)
|
||||
{
|
||||
return mozilla::dom::NuwaParent::Dealloc(aActor);
|
||||
}
|
||||
|
||||
PSendStreamParent*
|
||||
BackgroundParentImpl::AllocPSendStreamParent()
|
||||
{
|
||||
|
@ -101,15 +101,6 @@ protected:
|
||||
virtual bool
|
||||
DeallocPBroadcastChannelParent(PBroadcastChannelParent* aActor) override;
|
||||
|
||||
virtual PNuwaParent*
|
||||
AllocPNuwaParent() override;
|
||||
|
||||
virtual bool
|
||||
RecvPNuwaConstructor(PNuwaParent* aActor) override;
|
||||
|
||||
virtual bool
|
||||
DeallocPNuwaParent(PNuwaParent* aActor) override;
|
||||
|
||||
virtual PSendStreamParent*
|
||||
AllocPSendStreamParent() override;
|
||||
|
||||
|
@ -1227,56 +1227,3 @@ GeckoChildProcessHost::GetQueuedMessages(std::queue<IPC::Message>& queue)
|
||||
}
|
||||
|
||||
bool GeckoChildProcessHost::sRunSelfAsContentProc(false);
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
|
||||
using mozilla::ipc::GeckoExistingProcessHost;
|
||||
using mozilla::ipc::FileDescriptor;
|
||||
|
||||
GeckoExistingProcessHost::
|
||||
GeckoExistingProcessHost(GeckoProcessType aProcessType,
|
||||
base::ProcessHandle aProcess,
|
||||
const FileDescriptor& aFileDescriptor,
|
||||
ChildPrivileges aPrivileges)
|
||||
: GeckoChildProcessHost(aProcessType, aPrivileges)
|
||||
, mExistingProcessHandle(aProcess)
|
||||
, mExistingFileDescriptor(aFileDescriptor)
|
||||
{
|
||||
NS_ASSERTION(aFileDescriptor.IsValid(),
|
||||
"Expected file descriptor to be valid");
|
||||
}
|
||||
|
||||
GeckoExistingProcessHost::~GeckoExistingProcessHost()
|
||||
{
|
||||
// Bug 943174: If we don't do this, ~GeckoChildProcessHost will try
|
||||
// to wait on a process that isn't a direct child, and bad things
|
||||
// will happen.
|
||||
SetAlreadyDead();
|
||||
}
|
||||
|
||||
bool
|
||||
GeckoExistingProcessHost::PerformAsyncLaunch(StringVector aExtraOpts,
|
||||
base::ProcessArchitecture aArch)
|
||||
{
|
||||
if (!OpenPrivilegedHandle(base::GetProcId(mExistingProcessHandle))) {
|
||||
NS_RUNTIMEABORT("can't open handle to child process");
|
||||
}
|
||||
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mProcessState = PROCESS_CREATED;
|
||||
lock.Notify();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GeckoExistingProcessHost::InitializeChannel()
|
||||
{
|
||||
CreateChannel(mExistingFileDescriptor);
|
||||
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mProcessState = CHANNEL_INITIALIZED;
|
||||
lock.Notify();
|
||||
}
|
||||
|
||||
#endif /* MOZ_NUWA_PROCESS */
|
||||
|
@ -212,28 +212,6 @@ private:
|
||||
static bool sRunSelfAsContentProc;
|
||||
};
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
class GeckoExistingProcessHost final : public GeckoChildProcessHost
|
||||
{
|
||||
public:
|
||||
GeckoExistingProcessHost(GeckoProcessType aProcessType,
|
||||
base::ProcessHandle aProcess,
|
||||
const FileDescriptor& aFileDescriptor,
|
||||
ChildPrivileges aPrivileges=base::PRIVILEGES_DEFAULT);
|
||||
|
||||
~GeckoExistingProcessHost();
|
||||
|
||||
virtual bool PerformAsyncLaunch(StringVector aExtraOpts=StringVector(),
|
||||
base::ProcessArchitecture aArch=base::GetCurrentProcessArchitecture()) override;
|
||||
|
||||
virtual void InitializeChannel() override;
|
||||
|
||||
private:
|
||||
base::ProcessHandle mExistingProcessHandle;
|
||||
mozilla::ipc::FileDescriptor mExistingFileDescriptor;
|
||||
};
|
||||
#endif /* MOZ_NUWA_PROCESS */
|
||||
|
||||
} /* namespace ipc */
|
||||
} /* namespace mozilla */
|
||||
|
||||
|
@ -201,18 +201,6 @@ class MessageChannel : HasResultCodes
|
||||
sIsPumpingMessages = aIsPumping;
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
void Block() {
|
||||
MOZ_ASSERT(mLink);
|
||||
mLink->Block();
|
||||
}
|
||||
|
||||
void Unblock() {
|
||||
MOZ_ASSERT(mLink);
|
||||
mLink->Unblock();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OS_WIN
|
||||
struct MOZ_STACK_CLASS SyncStackFrame
|
||||
{
|
||||
|
@ -11,18 +11,6 @@
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
#include "chrome/common/ipc_channel.h"
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/PNuwa.h"
|
||||
#include "mozilla/hal_sandbox/PHal.h"
|
||||
#ifdef DEBUG
|
||||
#include "jsprf.h"
|
||||
extern "C" char* PrintJSStack();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "nsDebug.h"
|
||||
@ -68,10 +56,6 @@ ProcessLink::ProcessLink(MessageChannel *aChan)
|
||||
, mTransport(nullptr)
|
||||
, mIOLoop(nullptr)
|
||||
, mExistingListener(nullptr)
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
, mIsToNuwaProcess(false)
|
||||
, mIsBlocked(false)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
@ -130,17 +114,6 @@ ProcessLink::Open(mozilla::ipc::Transport* aTransport, MessageLoop *aIOLoop, Sid
|
||||
mIOLoop->PostTask(NewNonOwningRunnableMethod(this, &ProcessLink::OnTakeConnectedChannel));
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess() && NS_IsMainThread() &&
|
||||
Preferences::GetBool("dom.ipc.processPrelaunch.testMode")) {
|
||||
// The pref value is turned on in a deadlock test against the Nuwa
|
||||
// process. The sleep here makes it easy to trigger the deadlock
|
||||
// that an IPC channel is still opening but the worker loop is
|
||||
// already frozen.
|
||||
sleep(5);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Should not wait here if something goes wrong with the channel.
|
||||
while (!mChan->Connected() && mChan->mChannelState != ChannelError) {
|
||||
mChan->mMonitor->Wait();
|
||||
@ -172,42 +145,6 @@ ProcessLink::SendMessage(Message *msg)
|
||||
mChan->AssertWorkerThread();
|
||||
mChan->mMonitor->AssertCurrentThreadOwns();
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// Parent to child: check whether we are sending some unexpected message to
|
||||
// the Nuwa process.
|
||||
if (mIsToNuwaProcess && mozilla::dom::ContentParent::IsNuwaReady()) {
|
||||
switch (msg->type()) {
|
||||
case mozilla::dom::PNuwa::Msg_Fork__ID:
|
||||
case mozilla::dom::PNuwa::Reply_AddNewProcess__ID:
|
||||
case mozilla::dom::PContent::Msg_NotifyPhoneStateChange__ID:
|
||||
case mozilla::dom::PContent::Msg_ActivateA11y__ID:
|
||||
case mozilla::hal_sandbox::PHal::Msg_NotifyNetworkChange__ID:
|
||||
case GOODBYE_MESSAGE_TYPE:
|
||||
break;
|
||||
default:
|
||||
#ifdef DEBUG
|
||||
MOZ_CRASH();
|
||||
#else
|
||||
// In optimized build, message will be dropped.
|
||||
printf_stderr("Sending message to frozen Nuwa");
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DEBUG)
|
||||
// Nuwa to parent: check whether we are currently blocked.
|
||||
if (IsNuwaProcess() && mIsBlocked) {
|
||||
char* jsstack = PrintJSStack();
|
||||
printf_stderr("Fatal error: sending a message to the chrome process"
|
||||
"with a blocked IPC channel from \n%s",
|
||||
jsstack ? jsstack : "<no JS stack>");
|
||||
JS_smprintf_free(jsstack);
|
||||
MOZ_CRASH();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
mIOLoop->PostTask(NewNonOwningRunnableMethod<Message*>(mTransport, &Transport::Send, msg));
|
||||
}
|
||||
|
||||
@ -397,10 +334,6 @@ ProcessLink::OnChannelConnected(int32_t peer_pid)
|
||||
if (mExistingListener)
|
||||
mExistingListener->OnChannelConnected(peer_pid);
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
mIsToNuwaProcess = (peer_pid == mozilla::dom::ContentParent::NuwaPid());
|
||||
#endif
|
||||
|
||||
if (notifyChannel) {
|
||||
mChan->OnChannelConnected(peer_pid);
|
||||
}
|
||||
|
@ -163,12 +163,6 @@ class MessageLink
|
||||
virtual bool Unsound_IsClosed() const = 0;
|
||||
virtual uint32_t Unsound_NumQueuedMessages() const = 0;
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// To be overridden by ProcessLink.
|
||||
virtual void Block() {}
|
||||
virtual void Unblock() {}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
MessageChannel *mChan;
|
||||
};
|
||||
@ -216,23 +210,10 @@ class ProcessLink
|
||||
virtual bool Unsound_IsClosed() const override;
|
||||
virtual uint32_t Unsound_NumQueuedMessages() const override;
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
void Block() override {
|
||||
mIsBlocked = true;
|
||||
}
|
||||
void Unblock() override {
|
||||
mIsBlocked = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
Transport* mTransport;
|
||||
MessageLoop* mIOLoop; // thread where IO happens
|
||||
Transport::Listener* mExistingListener; // channel's previous listener
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
bool mIsToNuwaProcess;
|
||||
bool mIsBlocked;
|
||||
#endif
|
||||
};
|
||||
|
||||
class ThreadLink : public MessageLink
|
||||
|
@ -25,10 +25,6 @@
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "prthread.h"
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
using base::TimeTicks;
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
@ -108,11 +104,7 @@ MessagePump::Run(MessagePump::Delegate* aDelegate)
|
||||
|
||||
did_work |= aDelegate->DoDelayedWork(&delayed_work_time_);
|
||||
|
||||
if (did_work && delayed_work_time_.is_null()
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
&& (!IsNuwaReady() || !IsNuwaProcess())
|
||||
#endif
|
||||
)
|
||||
if (did_work && delayed_work_time_.is_null())
|
||||
mDelayedWorkTimer->Cancel();
|
||||
|
||||
if (!keep_running_)
|
||||
@ -132,9 +124,6 @@ if (did_work && delayed_work_time_.is_null()
|
||||
NS_ProcessNextEvent(thisThread, true);
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (!IsNuwaReady() || !IsNuwaProcess())
|
||||
#endif
|
||||
mDelayedWorkTimer->Cancel();
|
||||
|
||||
keep_running_ = true;
|
||||
@ -166,11 +155,6 @@ MessagePump::ScheduleWorkForNestedLoop()
|
||||
void
|
||||
MessagePump::ScheduleDelayedWork(const base::TimeTicks& aDelayedTime)
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaReady() && IsNuwaProcess())
|
||||
return;
|
||||
#endif
|
||||
|
||||
// To avoid racing on mDelayedWorkTimer, we need to be on the same thread as
|
||||
// ::Run().
|
||||
MOZ_RELEASE_ASSERT(NS_GetCurrentThread() == mThread ||
|
||||
|
@ -17,7 +17,6 @@ include protocol PGamepadEventChannel;
|
||||
include protocol PGamepadTestChannel;
|
||||
include protocol PMessagePort;
|
||||
include protocol PCameras;
|
||||
include protocol PNuwa;
|
||||
include protocol PQuota;
|
||||
include protocol PSendStream;
|
||||
include protocol PServiceWorkerManager;
|
||||
@ -61,7 +60,6 @@ sync protocol PBackground
|
||||
manages PGamepadTestChannel;
|
||||
manages PMessagePort;
|
||||
manages PCameras;
|
||||
manages PNuwa;
|
||||
manages PQuota;
|
||||
manages PSendStream;
|
||||
manages PServiceWorkerManager;
|
||||
@ -94,8 +92,6 @@ parent:
|
||||
|
||||
async PMessagePort(nsID uuid, nsID destinationUuid, uint32_t sequenceId);
|
||||
|
||||
async PNuwa();
|
||||
|
||||
async PSendStream();
|
||||
|
||||
async MessagePortForceClose(nsID uuid, nsID destinationUuid, uint32_t sequenceId);
|
||||
|
@ -7,10 +7,6 @@
|
||||
#ifndef mozilla_ipc_ProcessUtils_h
|
||||
#define mozilla_ipc_ProcessUtils_h
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
#include "base/process_util.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
@ -18,17 +14,6 @@ namespace ipc {
|
||||
// this directly.
|
||||
void SetThisProcessName(const char *aName);
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
// see ProcessUtils_linux.cpp for explaination.
|
||||
void ProcLoaderClientGeckoInit();
|
||||
bool ProcLoaderIsInitialized();
|
||||
bool ProcLoaderLoad(const char *aArgv[],
|
||||
const char *aEnvp[],
|
||||
const base::file_handle_mapping_vector &aFdsRemap,
|
||||
const base::ChildPrivileges aPrivs,
|
||||
base::ProcessHandle *aProcessHandle);
|
||||
#endif /* MOZ_B2G_LOADER */
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -10,41 +10,6 @@
|
||||
|
||||
#include <sys/prctl.h>
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/ipc/PProcLoaderParent.h"
|
||||
#include "mozilla/ipc/PProcLoaderChild.h"
|
||||
#include "mozilla/ipc/Transport.h"
|
||||
#include "mozilla/ipc/FileDescriptorUtils.h"
|
||||
#include "mozilla/ipc/IOThreadChild.h"
|
||||
#include "mozilla/dom/ContentProcess.h"
|
||||
#include "base/file_descriptor_shuffle.h"
|
||||
#include "mozilla/BackgroundHangMonitor.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "base/process_util.h"
|
||||
#include "base/eintr_wrapper.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
#include "prenv.h"
|
||||
|
||||
#include "nsXULAppAPI.h" // export XRE_* functions
|
||||
|
||||
#include "nsAppRunner.h"
|
||||
|
||||
int content_process_main(int argc, char *argv[]);
|
||||
|
||||
typedef mozilla::Vector<int> FdArray;
|
||||
|
||||
#endif /* MOZ_B2G_LOADER */
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace ipc {
|
||||
@ -54,574 +19,6 @@ void SetThisProcessName(const char *aName)
|
||||
prctl(PR_SET_NAME, (unsigned long)aName, 0uL, 0uL, 0uL);
|
||||
}
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
/**
|
||||
* How does B2G Loader Work?
|
||||
*
|
||||
* <<parent process>> <<child process>>
|
||||
* ProcLoaderParent -----> ProcLoaderChild
|
||||
* ^ |
|
||||
* | load() | content_process_main()
|
||||
* | V
|
||||
* ProcLoaderClient Nuwa/plugin-container
|
||||
* ^
|
||||
* | ProcLoaderLoad()
|
||||
* ...
|
||||
* ContentParent
|
||||
*
|
||||
*
|
||||
* B2G loader includes an IPC protocol PProcLoader for communication
|
||||
* between client (parent) and server (child). The b2g process is the
|
||||
* client. It requests the server to load/start the Nuwa process with
|
||||
* the given arguments, env variables, and file descriptors.
|
||||
*
|
||||
* ProcLoaderClientInit() is called by B2G loader to initialize the
|
||||
* client side, the b2g process. Then the b2g_main() is called to
|
||||
* start b2g process.
|
||||
*
|
||||
* ProcLoaderClientGeckoInit() is called by XRE_main() to create the
|
||||
* parent actor, |ProcLoaderParent|, of PProcLoader for servicing the
|
||||
* request to run Nuwa process later once Gecko has been initialized.
|
||||
*
|
||||
* ProcLoaderServiceRun() is called by the server process. It starts
|
||||
* an IOThread and event loop to serve the |ProcLoaderChild|
|
||||
* implmentation of PProcLoader protocol as the child actor. Once it
|
||||
* recieves a load() request, it stops the IOThread and event loop,
|
||||
* then starts running the main function of the content process with
|
||||
* the given arguments.
|
||||
*
|
||||
* NOTE: The server process serves at most one load() request.
|
||||
*/
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
using base::ChildPrivileges;
|
||||
using base::InjectionArc;
|
||||
using base::InjectiveMultimap;
|
||||
using base::ProcessHandle;
|
||||
using base::ProcessId;
|
||||
using base::SetCurrentProcessPrivileges;
|
||||
using base::ShuffleFileDescriptors;
|
||||
using base::file_handle_mapping_vector;
|
||||
|
||||
static bool sProcLoaderClientOnDeinit = false;
|
||||
static DebugOnly<bool> sProcLoaderClientInitialized = false;
|
||||
static DebugOnly<bool> sProcLoaderClientGeckoInitialized = false;
|
||||
static pid_t sProcLoaderPid = 0;
|
||||
static int sProcLoaderChannelFd = -1;
|
||||
static PProcLoaderParent *sProcLoaderParent = nullptr;
|
||||
static MessageLoop *sProcLoaderLoop = nullptr;
|
||||
static mozilla::UniquePtr<FdArray> sReservedFds;
|
||||
|
||||
static void ProcLoaderClientDeinit();
|
||||
|
||||
/**
|
||||
* Some file descriptors, like the child IPC channel FD, must be opened at
|
||||
* specific numbers. To ensure this, we pre-reserve kReservedFileDescriptors FDs
|
||||
* starting from kBeginReserveFileDescriptor so that operations like
|
||||
* __android_log_print() won't take these magic FDs.
|
||||
*/
|
||||
static const size_t kReservedFileDescriptors = 5;
|
||||
static const int kBeginReserveFileDescriptor = STDERR_FILENO + 1;
|
||||
|
||||
class ProcLoaderParent : public PProcLoaderParent
|
||||
{
|
||||
public:
|
||||
ProcLoaderParent() {}
|
||||
virtual ~ProcLoaderParent() {}
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
virtual bool RecvLoadComplete(const int32_t &aPid,
|
||||
const int32_t &aCookie) override;
|
||||
};
|
||||
|
||||
void
|
||||
ProcLoaderParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
if (aWhy == AbnormalShutdown) {
|
||||
NS_WARNING("ProcLoaderParent is destroyed abnormally.");
|
||||
}
|
||||
|
||||
if (sProcLoaderClientOnDeinit) {
|
||||
// Get error for closing while the channel is already error.
|
||||
return;
|
||||
}
|
||||
|
||||
// Destroy self asynchronously.
|
||||
ProcLoaderClientDeinit();
|
||||
}
|
||||
|
||||
static void
|
||||
_ProcLoaderParentDestroy(PProcLoaderParent *aLoader)
|
||||
{
|
||||
delete aLoader;
|
||||
sProcLoaderClientOnDeinit = false;
|
||||
}
|
||||
|
||||
bool
|
||||
ProcLoaderParent::RecvLoadComplete(const int32_t &aPid,
|
||||
const int32_t &aCookie)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
CloseFileDescriptors(FdArray& aFds)
|
||||
{
|
||||
for (size_t i = 0; i < aFds.length(); i++) {
|
||||
Unused << HANDLE_EINTR(close(aFds[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the client of B2G loader for loader itself.
|
||||
*
|
||||
* The initialization of B2G loader are divided into two stages. First
|
||||
* stage is to collect child info passed from the main program of the
|
||||
* loader. Second stage is to initialize Gecko according to info from the
|
||||
* first stage and make the client of loader service ready.
|
||||
*
|
||||
* \param aPeerPid is the pid of the child.
|
||||
* \param aChannelFd is the file descriptor of the socket used for IPC.
|
||||
*/
|
||||
static void
|
||||
ProcLoaderClientInit(pid_t aPeerPid, int aChannelFd)
|
||||
{
|
||||
MOZ_ASSERT(!sProcLoaderClientInitialized, "call ProcLoaderClientInit() more than once");
|
||||
MOZ_ASSERT(aPeerPid != 0 && aChannelFd != -1, "invalid argument");
|
||||
sProcLoaderPid = aPeerPid;
|
||||
sProcLoaderChannelFd = aChannelFd;
|
||||
sProcLoaderClientInitialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the client of B2G loader for Gecko.
|
||||
*/
|
||||
void
|
||||
ProcLoaderClientGeckoInit()
|
||||
{
|
||||
MOZ_ASSERT(sProcLoaderClientInitialized, "call ProcLoaderClientInit() at first");
|
||||
MOZ_ASSERT(!sProcLoaderClientGeckoInitialized,
|
||||
"call ProcLoaderClientGeckoInit() more than once");
|
||||
|
||||
if (!Preferences::GetBool("dom.ipc.processPrelaunch.enabled", false)) {
|
||||
kill(sProcLoaderPid, SIGKILL);
|
||||
sProcLoaderPid = 0;
|
||||
close(sProcLoaderChannelFd);
|
||||
sProcLoaderChannelFd = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
sProcLoaderClientGeckoInitialized = true;
|
||||
|
||||
TransportDescriptor fd;
|
||||
fd.mFd = base::FileDescriptor(sProcLoaderChannelFd, /*auto_close=*/ false);
|
||||
sProcLoaderChannelFd = -1;
|
||||
UniquePtr<Transport> transport = OpenDescriptor(fd, Transport::MODE_CLIENT);
|
||||
sProcLoaderParent = new ProcLoaderParent();
|
||||
sProcLoaderParent->Open(transport.get(),
|
||||
sProcLoaderPid,
|
||||
XRE_GetIOMessageLoop(),
|
||||
ParentSide);
|
||||
sProcLoaderLoop = MessageLoop::current();
|
||||
}
|
||||
|
||||
bool ProcLoaderIsInitialized()
|
||||
{
|
||||
return sProcLoaderPid != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown and destroy the client of B2G loader service.
|
||||
*/
|
||||
static void
|
||||
ProcLoaderClientDeinit()
|
||||
{
|
||||
MOZ_ASSERT(sProcLoaderClientGeckoInitialized && sProcLoaderClientInitialized);
|
||||
sProcLoaderClientGeckoInitialized = false;
|
||||
sProcLoaderClientInitialized = false;
|
||||
|
||||
sProcLoaderClientOnDeinit = true;
|
||||
|
||||
MOZ_ASSERT(sProcLoaderParent != nullptr);
|
||||
PProcLoaderParent *procLoaderParent = sProcLoaderParent;
|
||||
sProcLoaderParent = nullptr;
|
||||
sProcLoaderLoop = nullptr;
|
||||
|
||||
MessageLoop::current()->
|
||||
PostTask(NewRunnableFunction(&_ProcLoaderParentDestroy,
|
||||
procLoaderParent));
|
||||
}
|
||||
|
||||
struct AsyncSendLoadData
|
||||
{
|
||||
nsTArray<nsCString> mArgv;
|
||||
nsTArray<nsCString> mEnv;
|
||||
nsTArray<FDRemap> mFdsremap;
|
||||
ChildPrivileges mPrivs;
|
||||
int mCookie;
|
||||
};
|
||||
|
||||
static void
|
||||
AsyncSendLoad(AsyncSendLoadData *aLoad)
|
||||
{
|
||||
PProcLoaderParent *loader = sProcLoaderParent;
|
||||
DebugOnly<bool> ok =
|
||||
loader->SendLoad(aLoad->mArgv, aLoad->mEnv, aLoad->mFdsremap,
|
||||
aLoad->mPrivs, aLoad->mCookie);
|
||||
MOZ_ASSERT(ok);
|
||||
delete aLoad;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the loader service, the server, to load Nuwa.
|
||||
*/
|
||||
bool
|
||||
ProcLoaderLoad(const char *aArgv[],
|
||||
const char *aEnvp[],
|
||||
const file_handle_mapping_vector &aFdsRemap,
|
||||
const ChildPrivileges aPrivs,
|
||||
ProcessHandle *aProcessHandle)
|
||||
{
|
||||
static int cookie=0;
|
||||
int i;
|
||||
|
||||
if (sProcLoaderParent == nullptr || sProcLoaderPid == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AsyncSendLoadData *load = new AsyncSendLoadData();
|
||||
nsTArray<nsCString> &argv = load->mArgv;
|
||||
for (i = 0; aArgv[i] != nullptr; i++) {
|
||||
argv.AppendElement(nsCString(aArgv[i]));
|
||||
}
|
||||
nsTArray<nsCString> &env = load->mEnv;
|
||||
for (i = 0; aEnvp[i] != nullptr; i++) {
|
||||
env.AppendElement(nsCString(aEnvp[i]));
|
||||
}
|
||||
nsTArray<FDRemap> &fdsremap = load->mFdsremap;
|
||||
for (file_handle_mapping_vector::const_iterator fdmap =
|
||||
aFdsRemap.begin();
|
||||
fdmap != aFdsRemap.end();
|
||||
fdmap++) {
|
||||
fdsremap.AppendElement(FDRemap(FileDescriptor(fdmap->first), fdmap->second));
|
||||
}
|
||||
load->mPrivs = aPrivs;
|
||||
load->mCookie = cookie++;
|
||||
|
||||
*aProcessHandle = sProcLoaderPid;
|
||||
sProcLoaderPid = 0;
|
||||
|
||||
sProcLoaderLoop->PostTask(NewRunnableFunction(AsyncSendLoad, load));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
class ProcLoaderRunnerBase;
|
||||
|
||||
static bool sProcLoaderServing = false;
|
||||
static ProcLoaderRunnerBase *sProcLoaderDispatchedTask = nullptr;
|
||||
|
||||
class ProcLoaderRunnerBase
|
||||
{
|
||||
public:
|
||||
virtual int DoWork() = 0;
|
||||
virtual ~ProcLoaderRunnerBase() {}
|
||||
};
|
||||
|
||||
|
||||
class ProcLoaderNoopRunner : public ProcLoaderRunnerBase {
|
||||
public:
|
||||
virtual int DoWork();
|
||||
};
|
||||
|
||||
int
|
||||
ProcLoaderNoopRunner::DoWork() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The runner to load Nuwa at the current process.
|
||||
*/
|
||||
class ProcLoaderLoadRunner : public ProcLoaderRunnerBase {
|
||||
private:
|
||||
const nsTArray<nsCString> mArgv;
|
||||
const nsTArray<nsCString> mEnv;
|
||||
const nsTArray<FDRemap> mFdsRemap;
|
||||
const ChildPrivileges mPrivs;
|
||||
|
||||
void ShuffleFds();
|
||||
|
||||
public:
|
||||
ProcLoaderLoadRunner(const InfallibleTArray<nsCString>& aArgv,
|
||||
const InfallibleTArray<nsCString>& aEnv,
|
||||
const InfallibleTArray<FDRemap>& aFdsRemap,
|
||||
const ChildPrivileges aPrivs)
|
||||
: mArgv(aArgv)
|
||||
, mEnv(aEnv)
|
||||
, mFdsRemap(aFdsRemap)
|
||||
, mPrivs(aPrivs) {}
|
||||
|
||||
int DoWork();
|
||||
};
|
||||
|
||||
void
|
||||
ProcLoaderLoadRunner::ShuffleFds()
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
MOZ_ASSERT(mFdsRemap.Length() <= kReservedFileDescriptors);
|
||||
|
||||
InjectiveMultimap fd_shuffle;
|
||||
fd_shuffle.reserve(mFdsRemap.Length());
|
||||
|
||||
for (i = 0; i < mFdsRemap.Length(); i++) {
|
||||
const FDRemap *map = &mFdsRemap[i];
|
||||
auto rawFD = map->fd().ClonePlatformHandle();
|
||||
int tofd = map->mapto();
|
||||
|
||||
// The FD that is dup2()'d from needs to be closed after shuffling.
|
||||
fd_shuffle.push_back(InjectionArc(rawFD.get(), tofd, /*in_close=*/true));
|
||||
|
||||
// Erase from sReservedFds we will use.
|
||||
for (int* toErase = sReservedFds->begin();
|
||||
toErase < sReservedFds->end();
|
||||
toErase++) {
|
||||
if (tofd == *toErase) {
|
||||
sReservedFds->erase(toErase);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DebugOnly<bool> ok = ShuffleFileDescriptors(&fd_shuffle);
|
||||
|
||||
// Close the FDs that are reserved but not used after
|
||||
// ShuffleFileDescriptors().
|
||||
MOZ_ASSERT(sReservedFds);
|
||||
CloseFileDescriptors(*sReservedFds);
|
||||
sReservedFds = nullptr;
|
||||
|
||||
// Note that we don'e call ::base::CloseSuperfluousFds() here, assuming that
|
||||
// The file descriptor inherited from the parent are also necessary for us.
|
||||
}
|
||||
|
||||
int
|
||||
ProcLoaderLoadRunner::DoWork()
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
ShuffleFds();
|
||||
|
||||
unsigned int argc = mArgv.Length();
|
||||
char **argv = new char *[argc + 1];
|
||||
for (i = 0; i < argc; i++) {
|
||||
argv[i] = ::strdup(mArgv[i].get());
|
||||
}
|
||||
argv[argc] = nullptr;
|
||||
|
||||
unsigned int envc = mEnv.Length();
|
||||
for (i = 0; i < envc; i++) {
|
||||
PR_SetEnv(mEnv[i].get());
|
||||
}
|
||||
|
||||
SetCurrentProcessPrivileges(mPrivs);
|
||||
|
||||
// Start Nuwa (main function)
|
||||
int ret = content_process_main(argc, argv);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
free(argv[i]);
|
||||
}
|
||||
delete[] argv;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
class ProcLoaderChild : public PProcLoaderChild
|
||||
{
|
||||
pid_t mPeerPid;
|
||||
|
||||
public:
|
||||
ProcLoaderChild(pid_t aPeerPid) : mPeerPid(aPeerPid) {}
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
virtual bool RecvLoad(InfallibleTArray<nsCString>&& aArgv,
|
||||
InfallibleTArray<nsCString>&& aEnv,
|
||||
InfallibleTArray<FDRemap>&& aFdsremap,
|
||||
const uint32_t& aPrivs,
|
||||
const int32_t& aCookie);
|
||||
|
||||
virtual void OnChannelError();
|
||||
};
|
||||
|
||||
void
|
||||
ProcLoaderChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
_ProcLoaderChildDestroy(ProcLoaderChild *aChild)
|
||||
{
|
||||
aChild->Close();
|
||||
delete aChild;
|
||||
MessageLoop::current()->Quit();
|
||||
}
|
||||
|
||||
bool
|
||||
ProcLoaderChild::RecvLoad(InfallibleTArray<nsCString>&& aArgv,
|
||||
InfallibleTArray<nsCString>&& aEnv,
|
||||
InfallibleTArray<FDRemap>&& aFdsRemap,
|
||||
const uint32_t& aPrivs,
|
||||
const int32_t& aCookie) {
|
||||
if (!sProcLoaderServing) {
|
||||
return true;
|
||||
}
|
||||
sProcLoaderServing = false;
|
||||
|
||||
MOZ_ASSERT(sProcLoaderDispatchedTask == nullptr);
|
||||
ChildPrivileges privs = static_cast<ChildPrivileges>(aPrivs);
|
||||
sProcLoaderDispatchedTask =
|
||||
new ProcLoaderLoadRunner(aArgv, aEnv, aFdsRemap, privs);
|
||||
|
||||
SendLoadComplete(mPeerPid, aCookie);
|
||||
|
||||
MessageLoop::current()->PostTask(
|
||||
NewRunnableFunction(_ProcLoaderChildDestroy, this));
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ProcLoaderChild::OnChannelError()
|
||||
{
|
||||
if (!sProcLoaderServing) {
|
||||
return;
|
||||
}
|
||||
sProcLoaderServing = false;
|
||||
|
||||
PProcLoaderChild::OnChannelError();
|
||||
|
||||
MOZ_ASSERT(sProcLoaderDispatchedTask == nullptr);
|
||||
sProcLoaderDispatchedTask = new ProcLoaderNoopRunner();
|
||||
|
||||
MessageLoop::current()->PostTask(
|
||||
NewRunnableFunction(_ProcLoaderChildDestroy, this));
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper class which calls NS_LogInit/NS_LogTerm in its scope.
|
||||
*/
|
||||
class ScopedLogging
|
||||
{
|
||||
public:
|
||||
ScopedLogging() { NS_LogInit(); }
|
||||
~ScopedLogging() { NS_LogTerm(); }
|
||||
};
|
||||
|
||||
/**
|
||||
* Run service of ProcLoader.
|
||||
*
|
||||
* \param aPeerPid is the pid of the parent.
|
||||
* \param aFd is the file descriptor of the socket for IPC.
|
||||
*
|
||||
* See the comment near the head of this file.
|
||||
*/
|
||||
static int
|
||||
ProcLoaderServiceRun(pid_t aPeerPid, int aFd,
|
||||
int aArgc, const char *aArgv[],
|
||||
FdArray& aReservedFds)
|
||||
{
|
||||
// Make a copy of aReservedFds. It will be used when we dup() the magic file
|
||||
// descriptors when ProcLoaderChild::RecvLoad() runs.
|
||||
sReservedFds = MakeUnique<FdArray>(mozilla::Move(aReservedFds));
|
||||
|
||||
ScopedLogging logging;
|
||||
|
||||
char **_argv;
|
||||
_argv = new char *[aArgc + 1];
|
||||
for (int i = 0; i < aArgc; i++) {
|
||||
_argv[i] = ::strdup(aArgv[i]);
|
||||
MOZ_ASSERT(_argv[i] != nullptr);
|
||||
}
|
||||
_argv[aArgc] = nullptr;
|
||||
|
||||
gArgv = _argv;
|
||||
gArgc = aArgc;
|
||||
|
||||
{
|
||||
nsresult rv = XRE_InitCommandLine(aArgc, _argv);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
mozilla::LogModule::Init();
|
||||
|
||||
TransportDescriptor fd;
|
||||
fd.mFd = base::FileDescriptor(aFd, /*auto_close =*/false);
|
||||
|
||||
MOZ_ASSERT(!sProcLoaderServing);
|
||||
MessageLoop loop;
|
||||
|
||||
nsAutoPtr<ContentProcess> process;
|
||||
process = new ContentProcess(aPeerPid);
|
||||
ChildThread *iothread = process->child_thread();
|
||||
|
||||
UniquePtr<Transport> transport = OpenDescriptor(fd, Transport::MODE_CLIENT);
|
||||
ProcLoaderChild *loaderChild = new ProcLoaderChild(aPeerPid);
|
||||
// Pass a message loop to initialize (connect) the channel
|
||||
// (connection).
|
||||
loaderChild->Open(transport.get(), aPeerPid, iothread->message_loop());
|
||||
|
||||
BackgroundHangMonitor::Prohibit();
|
||||
|
||||
sProcLoaderServing = true;
|
||||
loop.Run();
|
||||
|
||||
BackgroundHangMonitor::Allow();
|
||||
|
||||
XRE_DeinitCommandLine();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(sProcLoaderDispatchedTask != nullptr);
|
||||
ProcLoaderRunnerBase *task = sProcLoaderDispatchedTask;
|
||||
sProcLoaderDispatchedTask = nullptr;
|
||||
int ret = task->DoWork();
|
||||
delete task;
|
||||
|
||||
for (int i = 0; i < aArgc; i++) {
|
||||
free(_argv[i]);
|
||||
}
|
||||
delete[] _argv;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* MOZ_B2G_LOADER */
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
void
|
||||
XRE_ProcLoaderClientInit(pid_t aPeerPid, int aChannelFd, FdArray& aReservedFds)
|
||||
{
|
||||
// We already performed fork(). It's safe to free the "danger zone" of file
|
||||
// descriptors .
|
||||
mozilla::ipc::CloseFileDescriptors(aReservedFds);
|
||||
|
||||
mozilla::ipc::ProcLoaderClientInit(aPeerPid, aChannelFd);
|
||||
}
|
||||
|
||||
int
|
||||
XRE_ProcLoaderServiceRun(pid_t aPeerPid, int aFd,
|
||||
int aArgc, const char *aArgv[],
|
||||
FdArray& aReservedFds)
|
||||
{
|
||||
return mozilla::ipc::ProcLoaderServiceRun(aPeerPid, aFd,
|
||||
aArgc, aArgv,
|
||||
aReservedFds);
|
||||
}
|
||||
#endif /* MOZ_B2G_LOADER */
|
||||
|
@ -2357,10 +2357,6 @@ HOST_CXXFLAGS=`echo \
|
||||
AC_SUBST(_DEPEND_CFLAGS)
|
||||
AC_SUBST(MOZ_SYSTEM_NSPR)
|
||||
|
||||
if test -n "$MOZ_NUWA_PROCESS"; then
|
||||
AC_DEFINE(MOZ_NUWA_PROCESS)
|
||||
fi
|
||||
|
||||
OS_CFLAGS="$CFLAGS"
|
||||
OS_CXXFLAGS="$CXXFLAGS"
|
||||
OS_CPPFLAGS="$CPPFLAGS"
|
||||
|
@ -1296,26 +1296,12 @@ HelperThread::destroy()
|
||||
threadData.reset();
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
extern "C" {
|
||||
MFBT_API bool IsNuwaProcess();
|
||||
MFBT_API void NuwaMarkCurrentThread(void (*recreate)(void*), void* arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* static */
|
||||
void
|
||||
HelperThread::ThreadMain(void* arg)
|
||||
{
|
||||
PR_SetCurrentThreadName("JS Helper");
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
MOZ_ASSERT(NuwaMarkCurrentThread != nullptr);
|
||||
NuwaMarkCurrentThread(nullptr, nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
//See bug 1104658.
|
||||
//Set the FPU control word to be the same as the main thread's, or math
|
||||
//computations on this thread may use incorrect precision rules during
|
||||
|
@ -1121,10 +1121,6 @@ class Watchdog
|
||||
mozilla::Atomic<int32_t> mMinScriptRunTimeSeconds;
|
||||
};
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
#define PREF_MAX_SCRIPT_RUN_TIME_CONTENT "dom.max_script_run_time"
|
||||
#define PREF_MAX_SCRIPT_RUN_TIME_CHROME "dom.max_chrome_script_run_time"
|
||||
|
||||
@ -1282,13 +1278,6 @@ WatchdogMain(void* arg)
|
||||
{
|
||||
PR_SetCurrentThreadName("JS Watchdog");
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
NuwaMarkCurrentThread(nullptr, nullptr);
|
||||
NuwaFreezeCurrentThread();
|
||||
}
|
||||
#endif
|
||||
|
||||
Watchdog* self = static_cast<Watchdog*>(arg);
|
||||
WatchdogManager* manager = self->Manager();
|
||||
|
||||
|
@ -69,10 +69,6 @@
|
||||
#include "nsAnimationManager.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget;
|
||||
using namespace mozilla::ipc;
|
||||
@ -865,15 +861,6 @@ CreateVsyncRefreshTimer()
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// NUWA process will just use software timer. Use NuwaAddFinalConstructor()
|
||||
// to register a callback to create the vsync-base refresh timer after a
|
||||
// process is created.
|
||||
if (IsNuwaProcess()) {
|
||||
NuwaAddFinalConstructor(&CreateContentVsyncRefreshTimer, nullptr);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// If this process is not created by NUWA, just create the vsync timer here.
|
||||
CreateContentVsyncRefreshTimer(nullptr);
|
||||
}
|
||||
|
@ -64,9 +64,6 @@ if CONFIG['OS_TARGET'] == 'Linux':
|
||||
# For mremap
|
||||
DEFINES['_GNU_SOURCE'] = True
|
||||
|
||||
if CONFIG['MOZ_NUWA_PROCESS'] and CONFIG['MOZ_JEMALLOC4']:
|
||||
DEFINES['pthread_mutex_lock'] = '__real_pthread_mutex_lock'
|
||||
|
||||
if CONFIG['GNU_CC']:
|
||||
CFLAGS += ['-std=gnu99']
|
||||
|
||||
|
@ -35,9 +35,6 @@ DEFINES['MOZ_JEMALLOC_IMPL'] = True
|
||||
if CONFIG['OS_TARGET'] == 'Linux':
|
||||
NO_PGO = True
|
||||
|
||||
if CONFIG['MOZ_NUWA_PROCESS']:
|
||||
DEFINES['pthread_mutex_lock'] = '__real_pthread_mutex_lock';
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/memory/build',
|
||||
]
|
||||
|
@ -259,11 +259,6 @@ void
|
||||
DMDFuncs::StatusMsg(const char* aFmt, va_list aAp)
|
||||
{
|
||||
#ifdef ANDROID
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
// Don't call __android_log_vprint() during initialization, or the magic file
|
||||
// descriptors will be occupied by android logcat.
|
||||
if (gIsDMDInitialized)
|
||||
#endif
|
||||
__android_log_vprint(ANDROID_LOG_INFO, "DMD", aFmt, aAp);
|
||||
#else
|
||||
// The +64 is easily enough for the "DMD[<pid>] " prefix and the NUL.
|
||||
|
@ -307,18 +307,6 @@ pthread_atfork(void (*aPrepare)(void), void (*aParent)(void),
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include <pthread.h>
|
||||
|
||||
/* NUWA builds have jemalloc built with
|
||||
* -Dpthread_mutex_lock=__real_pthread_mutex_lock */
|
||||
int
|
||||
__real_pthread_mutex_lock(pthread_mutex_t* aMutex)
|
||||
{
|
||||
return pthread_mutex_lock(aMutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
MOZ_END_EXTERN_C
|
||||
|
||||
size_t parseNumber(Buffer aBuf)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,201 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=2 autoindent cindent expandtab: */
|
||||
/* 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 __NUWA_H_
|
||||
#define __NUWA_H_
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mozilla/Types.h"
|
||||
|
||||
/**
|
||||
* Nuwa is a goddess who created mankind according to her figure in the
|
||||
* ancient Chinese mythology.
|
||||
*/
|
||||
|
||||
// Max number of top level protocol that can be handled by Nuwa process.
|
||||
#ifndef NUWA_TOPLEVEL_MAX
|
||||
#define NUWA_TOPLEVEL_MAX 8
|
||||
#endif
|
||||
|
||||
struct NuwaProtoFdInfo {
|
||||
int protoId;
|
||||
int originFd;
|
||||
int newFds[2];
|
||||
};
|
||||
|
||||
#define NUWA_NEWFD_PARENT 0
|
||||
#define NUWA_NEWFD_CHILD 1
|
||||
|
||||
extern "C" {
|
||||
|
||||
/**
|
||||
* The following 3 methods are used to synchronously spawn the Nuwa process.
|
||||
* The typical usage is:
|
||||
*
|
||||
* The IPC thread The main thread
|
||||
* 1. Receives the request.
|
||||
* 2. NuwaSpawnPrepare().
|
||||
* 3. Request main thread to
|
||||
* spawn. --------------------------------------+
|
||||
* 4. NuwaSpawnWait(). V
|
||||
* 5. NuwaSpawn() to clone all
|
||||
* the threads in the Nuwa
|
||||
* process (including main
|
||||
* & IPC threads).
|
||||
* 6. NuwaSpawn() finishes and
|
||||
* +-------------------------------------- signals NuwaSpawnWait().
|
||||
* V
|
||||
* 7. NuwaSpawnWait() returns.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prepare for spawning a new process. The calling thread (typically the IPC
|
||||
* thread) will block further requests to spawn a new process.
|
||||
*/
|
||||
MFBT_API void NuwaSpawnPrepare();
|
||||
|
||||
/**
|
||||
* Called on the thread that receives the request. Used to wait until
|
||||
* NuwaSpawn() finishes and maintain the stack of the calling thread.
|
||||
*/
|
||||
MFBT_API void NuwaSpawnWait();
|
||||
|
||||
/**
|
||||
* Spawn a new content process, called in the Nuwa process. This has to run on
|
||||
* the main thread.
|
||||
*
|
||||
* @return The process ID of the new process.
|
||||
*/
|
||||
MFBT_API pid_t NuwaSpawn();
|
||||
|
||||
/**
|
||||
* The following methods are for marking threads created in the Nuwa process so
|
||||
* they can be frozen and then recreated in the spawned process. All threads
|
||||
* except the main thread must be marked by one of the following 4 methods;
|
||||
* otherwise, we have a thread that is created but unknown to us. The Nuwa
|
||||
* process will never become ready and this needs to be fixed.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Mark the current thread as supporting Nuwa. The thread will implicitly freeze
|
||||
* by calling a blocking method such as pthread_mutex_lock() or epoll_wait().
|
||||
*
|
||||
* @param recreate The custom function that will be called in the spawned
|
||||
* process, after the thread is recreated. Can be nullptr if no
|
||||
* custom function to be called after the thread is recreated.
|
||||
* Note that this function is called duing thread recreation
|
||||
* while other threads are frozen. It must not perform any
|
||||
* action (e.g. acquiring a mutex) that might depend on another
|
||||
* thread that is still blocked.
|
||||
* @param arg The argument passed to the custom function. Can be nullptr.
|
||||
*/
|
||||
MFBT_API void NuwaMarkCurrentThread(void (*recreate)(void *), void *arg);
|
||||
|
||||
/**
|
||||
* Mark the current thread as not supporting Nuwa. The calling thread will not
|
||||
* be automatically cloned from the Nuwa process to spawned process. If this
|
||||
* thread needs to be created in the spawned process, use NuwaAddConstructor()
|
||||
* or NuwaAddFinalConstructor() to do it.
|
||||
*/
|
||||
MFBT_API void NuwaSkipCurrentThread();
|
||||
|
||||
/**
|
||||
* Force the current thread to freeze explicitly at the current point.
|
||||
*/
|
||||
MFBT_API void NuwaFreezeCurrentThread();
|
||||
|
||||
/**
|
||||
* Helper functions for the NuwaCheckpointCurrentThread() macro.
|
||||
*/
|
||||
MFBT_API jmp_buf* NuwaCheckpointCurrentThread1();
|
||||
|
||||
MFBT_API bool NuwaCheckpointCurrentThread2(int setjmpCond);
|
||||
|
||||
/**
|
||||
* Set the point to recover after thread recreation. The calling thread is not
|
||||
* blocked. This is used for the thread that cannot freeze (i.e. the IPC
|
||||
* thread).
|
||||
*/
|
||||
#define NuwaCheckpointCurrentThread() \
|
||||
NuwaCheckpointCurrentThread2(setjmp(*NuwaCheckpointCurrentThread1()))
|
||||
|
||||
/**
|
||||
* The following methods are called in the initialization stage of the Nuwa
|
||||
* process.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prepare for making the Nuwa process.
|
||||
*/
|
||||
MFBT_API void PrepareNuwaProcess();
|
||||
|
||||
/**
|
||||
* Make the current process a Nuwa process. Start to freeze the threads.
|
||||
*/
|
||||
MFBT_API void MakeNuwaProcess();
|
||||
|
||||
/**
|
||||
* Register a method to be invoked after a new process is spawned. The method
|
||||
* will be invoked on the main thread *before* recreating the other threads.
|
||||
* The registered method must not perform any action (e.g. acquiring a mutex)
|
||||
* that might depend on another thread that has not yet been recreated.
|
||||
*
|
||||
* @param construct The method to be invoked.
|
||||
* @param arg The argument passed to the method.
|
||||
*/
|
||||
MFBT_API void NuwaAddConstructor(void (*construct)(void *), void *arg);
|
||||
|
||||
|
||||
/**
|
||||
* Register a method to be invoked after a new process is spawned and threads
|
||||
* are recreated. The method will be invoked on the main thread *after*
|
||||
* the other threads are recreated and fully functional.
|
||||
*
|
||||
* @param construct The method to be invoked.
|
||||
* @param arg The argument passed to the method.
|
||||
*/
|
||||
MFBT_API void NuwaAddFinalConstructor(void (*construct)(void *), void *arg);
|
||||
|
||||
|
||||
/**
|
||||
* Register a method to be invoked after the current thread is recreated in the
|
||||
* spawned process. Note that this function is called while other threads are
|
||||
* frozen. It must not perform any action (e.g. acquiring a mutex) that might
|
||||
* depend on another thread that is still blocked.
|
||||
*
|
||||
* @param construct The method to be invoked.
|
||||
* @param arg The argument passed to the method.
|
||||
*/
|
||||
MFBT_API void NuwaAddThreadConstructor(void (*construct)(void *), void *arg);
|
||||
|
||||
/**
|
||||
* The methods to query the Nuwa-related states.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return If the current process is the Nuwa process.
|
||||
*/
|
||||
MFBT_API bool IsNuwaProcess();
|
||||
|
||||
/**
|
||||
* @return If the Nuwa process is ready for spawning new processes.
|
||||
*/
|
||||
MFBT_API bool IsNuwaReady();
|
||||
|
||||
#if defined(DEBUG)
|
||||
/**
|
||||
* Asserts that aThread is not frozen.
|
||||
*/
|
||||
MFBT_API void NuwaAssertNotFrozen(unsigned int aThread,
|
||||
const char* aThreadName);
|
||||
#else
|
||||
#define NuwaAssertNotFrozen(aThread, aThreadName) do {} while(0);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* __NUWA_H_ */
|
@ -54,14 +54,6 @@ if not CONFIG['JS_STANDALONE']:
|
||||
'version',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_NUWA_PROCESS']:
|
||||
EXPORTS.ipc += [
|
||||
'Nuwa.h',
|
||||
]
|
||||
SOURCES += [
|
||||
'Nuwa.cpp',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
'arm.h',
|
||||
'mips.h',
|
||||
|
@ -35,9 +35,6 @@
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
#include "mozilla/Logging.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
@ -545,23 +542,6 @@ Predictor::GetInterface(const nsIID &iid, void **result)
|
||||
return QueryInterface(iid, result);
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
namespace {
|
||||
class NuwaMarkPredictorThreadRunner : public Runnable
|
||||
{
|
||||
NS_IMETHODIMP Run() override
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
if (IsNuwaProcess()) {
|
||||
NuwaMarkCurrentThread(nullptr, nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
// Predictor::nsICacheEntryMetaDataVisitor
|
||||
|
||||
#define SEEN_META_DATA "predictor::seen"
|
||||
@ -770,11 +750,6 @@ Predictor::MaybeCleanupOldDBFiles()
|
||||
rv = NS_NewNamedThread("NetPredictClean", getter_AddRefs(ioThread));
|
||||
RETURN_IF_FAILED(rv);
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
nsCOMPtr<nsIRunnable> nuwaRunner = new NuwaMarkPredictorThreadRunner();
|
||||
ioThread->Dispatch(nuwaRunner, NS_DISPATCH_NORMAL);
|
||||
#endif
|
||||
|
||||
RefPtr<PredictorOldCleanupRunner> runner =
|
||||
new PredictorOldCleanupRunner(ioThread, dbFile);
|
||||
ioThread->Dispatch(runner, NS_DISPATCH_NORMAL);
|
||||
|
@ -17,9 +17,6 @@
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
#include "nsISystemProxySettings.h"
|
||||
#include "nsContentUtils.h"
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -764,11 +761,6 @@ nsPACMan::NamePACThread()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread(), "wrong thread");
|
||||
PR_SetCurrentThreadName("Proxy Resolution");
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
NuwaMarkCurrentThread(nullptr, nullptr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -783,19 +783,9 @@ nsSocketTransportService::MarkTheLastElementOfPendingQueue()
|
||||
mServingPendingQueue = false;
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSocketTransportService::Run()
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
NuwaMarkCurrentThread(nullptr, nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
SOCKET_LOG(("STS thread init %d sockets\n", gMaxCount));
|
||||
|
||||
psm::InitializeSSLServerCertVerificationThreads();
|
||||
|
@ -434,40 +434,6 @@ nsOutputStreamTransport::IsNonBlocking(bool *result)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
|
||||
class STSThreadPoolListener final : public nsIThreadPoolListener
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSITHREADPOOLLISTENER
|
||||
|
||||
STSThreadPoolListener() {}
|
||||
|
||||
protected:
|
||||
~STSThreadPoolListener() {}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(STSThreadPoolListener, nsIThreadPoolListener)
|
||||
|
||||
NS_IMETHODIMP
|
||||
STSThreadPoolListener::OnThreadCreated()
|
||||
{
|
||||
if (IsNuwaProcess()) {
|
||||
NuwaMarkCurrentThread(nullptr, nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
STSThreadPoolListener::OnThreadShuttingDown()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif // MOZ_NUWA_PROCESS
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsStreamTransportService
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -488,11 +454,6 @@ nsStreamTransportService::Init()
|
||||
mPool->SetThreadLimit(25);
|
||||
mPool->SetIdleThreadLimit(1);
|
||||
mPool->SetIdleThreadTimeout(PR_SecondsToInterval(30));
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
mPool->SetListener(new STSThreadPoolListener());
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIObserverService> obsSvc =
|
||||
mozilla::services::GetObserverService();
|
||||
|
@ -27,10 +27,6 @@
|
||||
#include "mozilla/Base64.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include <cutils/properties.h>
|
||||
#endif
|
||||
@ -451,19 +447,6 @@ nsNotifyAddrListener::Observe(nsISupports *subject,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
class NuwaMarkLinkMonitorThreadRunner : public Runnable
|
||||
{
|
||||
NS_IMETHODIMP Run() override
|
||||
{
|
||||
if (IsNuwaProcess()) {
|
||||
NuwaMarkCurrentThread(nullptr, nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
nsNotifyAddrListener::Init(void)
|
||||
{
|
||||
@ -486,11 +469,6 @@ nsNotifyAddrListener::Init(void)
|
||||
rv = NS_NewNamedThread("Link Monitor", getter_AddRefs(mThread), this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
nsCOMPtr<nsIRunnable> runner = new NuwaMarkLinkMonitorThreadRunner();
|
||||
mThread->Dispatch(runner, NS_DISPATCH_NORMAL);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -4991,15 +4991,6 @@ if test -f "${srcdir}/${MOZ_BUILD_APP}/configure.in" ; then
|
||||
rm -f $tmpscript
|
||||
fi
|
||||
|
||||
dnl We need to wrap dlopen and related functions on Android because we use
|
||||
dnl our own linker.
|
||||
dnl This configuration will only work on Android SDK 11 and above: Bug 1220184.
|
||||
if test "$OS_TARGET" = Android; then
|
||||
if test "$MOZ_WIDGET_TOOLKIT" = gonk -a -n "$MOZ_NUWA_PROCESS"; then
|
||||
MOZ_GLUE_WRAP_LDFLAGS="${MOZ_GLUE_WRAP_LDFLAGS} -Wl,--wrap=pthread_create,--wrap=epoll_wait,--wrap=poll,--wrap=pthread_cond_timedwait,--wrap=pthread_cond_wait,--wrap=epoll_create,--wrap=epoll_ctl,--wrap=close,--wrap=pthread_key_create,--wrap=pthread_key_delete,--wrap=socketpair,--wrap=pthread_self,--wrap=pthread_mutex_lock,--wrap=pthread_mutex_trylock,--wrap=pthread_join,--wrap=pipe,--wrap=pipe2"
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST_LIST(MOZ_GLUE_WRAP_LDFLAGS)
|
||||
export MOZ_GLUE_WRAP_LDFLAGS
|
||||
|
||||
@ -6306,20 +6297,6 @@ AC_SUBST_LIST(MOZ_BZ2_LIBS)
|
||||
AC_SUBST_LIST(MOZ_PNG_CFLAGS)
|
||||
AC_SUBST_LIST(MOZ_PNG_LIBS)
|
||||
|
||||
if test "$MOZ_WIDGET_TOOLKIT" = gonk -a -n "$MOZ_NUWA_PROCESS"; then
|
||||
export MOZ_NUWA_PROCESS
|
||||
AC_DEFINE(MOZ_NUWA_PROCESS)
|
||||
fi
|
||||
AC_SUBST(MOZ_NUWA_PROCESS)
|
||||
if test "$MOZ_WIDGET_TOOLKIT" = gonk -a -n "$MOZ_B2G_LOADER"; then
|
||||
if test -z "$MOZ_NUWA_PROCESS"; then
|
||||
AC_MSG_ERROR([B2G loader works with Nuwa]);
|
||||
fi
|
||||
export MOZ_B2G_LOADER
|
||||
AC_DEFINE(MOZ_B2G_LOADER)
|
||||
fi
|
||||
AC_SUBST(MOZ_B2G_LOADER)
|
||||
|
||||
AC_SUBST(MOZ_SYSTEM_NSPR)
|
||||
|
||||
AC_SUBST(MOZ_SYSTEM_NSS)
|
||||
|
@ -506,19 +506,8 @@ SetCurrentProcessSandbox(UniquePtr<sandbox::bpf_dsl::Policy> aPolicy)
|
||||
}
|
||||
|
||||
void
|
||||
SandboxEarlyInit(GeckoProcessType aType, bool aIsNuwa)
|
||||
SandboxEarlyInit(GeckoProcessType aType)
|
||||
{
|
||||
// Bug 1168555: Nuwa isn't reliably single-threaded at this point;
|
||||
// it starts an IPC I/O thread and then shuts it down before calling
|
||||
// the plugin-container entry point, but that thread may not have
|
||||
// finished exiting. If/when any type of sandboxing is used for the
|
||||
// Nuwa process (e.g., unsharing the network namespace there instead
|
||||
// of for each content process, to save memory), this will need to be
|
||||
// changed by moving the SandboxEarlyInit call to an earlier point.
|
||||
if (aIsNuwa) {
|
||||
return;
|
||||
}
|
||||
|
||||
const SandboxInfo info = SandboxInfo::Get();
|
||||
if (info.Test(SandboxInfo::kUnexpectedThreads)) {
|
||||
return;
|
||||
|
@ -25,7 +25,7 @@
|
||||
namespace mozilla {
|
||||
|
||||
// This must be called early, while the process is still single-threaded.
|
||||
MOZ_SANDBOX_EXPORT void SandboxEarlyInit(GeckoProcessType aType, bool aIsNuwa);
|
||||
MOZ_SANDBOX_EXPORT void SandboxEarlyInit(GeckoProcessType aType);
|
||||
|
||||
#ifdef MOZ_CONTENT_SANDBOX
|
||||
// Call only if SandboxInfo::CanSandboxContent() returns true.
|
||||
|
@ -1414,10 +1414,6 @@ Extension.prototype = extend(Object.create(ExtensionData.prototype), {
|
||||
broadcast(msg, data) {
|
||||
return new Promise(resolve => {
|
||||
let count = Services.ppmm.childCount;
|
||||
if (AppConstants.MOZ_NUWA_PROCESS) {
|
||||
// The nuwa process is frozen, so don't expect it to answer.
|
||||
count--;
|
||||
}
|
||||
Services.ppmm.addMessageListener(msg + "Complete", function listener() {
|
||||
count--;
|
||||
if (count == 0) {
|
||||
|
@ -319,13 +319,6 @@ this.AppConstants = Object.freeze({
|
||||
#endif
|
||||
SOURCE_REVISION_URL: "@MOZ_SOURCE_URL@",
|
||||
|
||||
MOZ_NUWA_PROCESS:
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
HAVE_USR_LIB64_DIR:
|
||||
#ifdef HAVE_USR_LIB64_DIR
|
||||
true,
|
||||
|
@ -167,9 +167,6 @@ if CONFIG['MOZ_ENABLE_XREMOTE']:
|
||||
'/widget/xremoteclient',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_B2G_LOADER']:
|
||||
DEFINES['OMNIJAR_NAME'] = CONFIG['OMNIJAR_NAME']
|
||||
|
||||
CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
CXXFLAGS += CONFIG['MOZ_DBUS_CFLAGS']
|
||||
CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
|
||||
|
@ -195,10 +195,6 @@
|
||||
#include "base/command_line.h"
|
||||
#include "GTestRunner.h"
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
#include "ProcessUtils.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "GeneratedJNIWrappers.h"
|
||||
#endif
|
||||
@ -3954,10 +3950,6 @@ XREMain::XRE_mainRun()
|
||||
nsresult rv = NS_OK;
|
||||
NS_ASSERTION(mScopedXPCOM, "Scoped xpcom not initialized.");
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
mozilla::ipc::ProcLoaderClientGeckoInit();
|
||||
#endif
|
||||
|
||||
#ifdef NS_FUNCTION_TIMER
|
||||
// initialize some common services, so we don't pay the cost for these at odd times later on;
|
||||
// SetWindowCreator -> ChromeRegistry -> IOService -> SocketTransportService -> (nspr wspm init), Prefs
|
||||
|
@ -90,11 +90,6 @@
|
||||
using mozilla::_ipdltest::IPDLUnitTestProcessChild;
|
||||
#endif // ifdef MOZ_IPDL_TESTS
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
#include "nsLocalFile.h"
|
||||
#include "nsXREAppData.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_JPROF
|
||||
#include "jprof.h"
|
||||
#endif
|
||||
@ -949,40 +944,3 @@ XRE_InstallX11ErrorHandler()
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
extern const nsXREAppData* gAppData;
|
||||
|
||||
/**
|
||||
* Preload static data of Gecko for B2G loader.
|
||||
*
|
||||
* This function is supposed to be called before XPCOM is initialized.
|
||||
* For now, this function preloads
|
||||
* - XPT interface Information
|
||||
*/
|
||||
void
|
||||
XRE_ProcLoaderPreload(const char* aProgramDir, const nsXREAppData* aAppData)
|
||||
{
|
||||
void PreloadXPT(nsIFile *);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> omnijarFile;
|
||||
rv = NS_NewNativeLocalFile(nsCString(aProgramDir),
|
||||
true,
|
||||
getter_AddRefs(omnijarFile));
|
||||
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
rv = omnijarFile->AppendNative(NS_LITERAL_CSTRING(NS_STRINGIFY(OMNIJAR_NAME)));
|
||||
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
/*
|
||||
* gAppData is required by nsXULAppInfo. The manifest parser
|
||||
* evaluate flags with the information from nsXULAppInfo.
|
||||
*/
|
||||
gAppData = aAppData;
|
||||
|
||||
PreloadXPT(omnijarFile);
|
||||
|
||||
gAppData = nullptr;
|
||||
}
|
||||
#endif /* MOZ_B2G_LOADER */
|
||||
|
@ -30,10 +30,6 @@ class ThreadInfo {
|
||||
virtual void SetPendingDelete();
|
||||
bool IsPendingDelete() const { return mPendingDelete; }
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
void SetThreadId(int aThreadId) { mThreadId = aThreadId; }
|
||||
#endif
|
||||
|
||||
#ifndef SPS_STANDALONE
|
||||
/**
|
||||
* May be null for the main thread if the profiler was started during startup
|
||||
|
@ -92,10 +92,6 @@
|
||||
#include <string.h>
|
||||
#include <list>
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
#define SIGNAL_SAVE_PROFILE SIGUSR2
|
||||
|
||||
using namespace mozilla;
|
||||
@ -300,18 +296,6 @@ static void* SignalSender(void* arg) {
|
||||
// Taken from platform_thread_posix.cc
|
||||
prctl(PR_SET_NAME, "SamplerThread", 0, 0, 0);
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// If the Nuwa process is enabled, we need to mark and freeze the sampler
|
||||
// thread in the Nuwa process and have this thread recreated in the spawned
|
||||
// child.
|
||||
if(IsNuwaProcess()) {
|
||||
NuwaMarkCurrentThread(nullptr, nullptr);
|
||||
// Freeze the thread here so the spawned child will get the correct tgid
|
||||
// from the getpid() call below.
|
||||
NuwaFreezeCurrentThread();
|
||||
}
|
||||
#endif
|
||||
|
||||
int vm_tgid_ = getpid();
|
||||
DebugOnly<int> my_tid = gettid();
|
||||
|
||||
@ -500,18 +484,6 @@ void Sampler::Stop() {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
static void
|
||||
UpdateThreadId(void* aThreadInfo) {
|
||||
ThreadInfo* info = static_cast<ThreadInfo*>(aThreadInfo);
|
||||
// Note that this function is called during thread recreation. Only the thread
|
||||
// calling this method is running. We can't try to acquire
|
||||
// Sampler::sRegisteredThreadsMutex because it could be held by another
|
||||
// thread.
|
||||
info->SetThreadId(gettid());
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Sampler::RegisterCurrentThread(const char* aName,
|
||||
PseudoStack* aPseudoStack,
|
||||
bool aIsMainThread, void* stackTop)
|
||||
@ -543,20 +515,6 @@ bool Sampler::RegisterCurrentThread(const char* aName,
|
||||
|
||||
sRegisteredThreads->push_back(info);
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
if (info->IsMainThread()) {
|
||||
// Main thread isn't a marked thread. Register UpdateThreadId() to
|
||||
// NuwaAddConstructor(), which runs before all other threads are
|
||||
// recreated.
|
||||
NuwaAddConstructor(UpdateThreadId, info);
|
||||
} else {
|
||||
// Register UpdateThreadInfo() to be run when the thread is recreated.
|
||||
NuwaAddThreadConstructor(UpdateThreadId, info);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -26,10 +26,6 @@
|
||||
#define LOG(args...) \
|
||||
__android_log_print(ANDROID_LOG_INFO, "GonkMemoryPressure" , ## args)
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
namespace {
|
||||
@ -123,12 +119,6 @@ public:
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
NuwaMarkCurrentThread(nullptr, nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
int triggerResetTimeout = -1;
|
||||
bool memoryPressure;
|
||||
nsresult rv = CheckForMemoryPressure(&memoryPressure);
|
||||
|
@ -63,10 +63,6 @@
|
||||
#include "libui/InputReader.h"
|
||||
#include "libui/InputDispatcher.h"
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "GeckoProfiler.h"
|
||||
|
||||
@ -909,11 +905,6 @@ nsAppShell::Init()
|
||||
obsServ->AddObserver(this, "network-connection-state-changed", false);
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// Make sure main thread was woken up after Nuwa fork.
|
||||
NuwaAddConstructor((void (*)(void *))&NotifyEvent, nullptr);
|
||||
#endif
|
||||
|
||||
// Delay initializing input devices until the screen has been
|
||||
// initialized (and we know the resolution).
|
||||
return rv;
|
||||
|
@ -1246,10 +1246,6 @@ enum ccType
|
||||
ShutdownCC /* Shutdown CC, used for finding leaks. */
|
||||
};
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Top level structure for the cycle collector.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1926,12 +1926,6 @@ nsMemoryReporterManager::HandleChildReport(
|
||||
nsMemoryReporterManager::StartChildReport(mozilla::dom::ContentParent* aChild,
|
||||
const PendingProcessesState* aState)
|
||||
{
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (aChild->IsNuwaProcess()) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!aChild->IsAlive()) {
|
||||
MEMORY_REPORTING_LOG("StartChildReports (gen=%u): child exited before"
|
||||
" its report was started\n",
|
||||
@ -1984,7 +1978,7 @@ nsMemoryReporterManager::EndProcessReport(uint32_t aGeneration, bool aSuccess)
|
||||
RefPtr<ContentParent> nextChild;
|
||||
nextChild.swap(s->mChildrenPending.LastElement());
|
||||
s->mChildrenPending.TruncateLength(s->mChildrenPending.Length() - 1);
|
||||
// Start report (if the child is still alive and not Nuwa).
|
||||
// Start report (if the child is still alive).
|
||||
if (StartChildReport(nextChild, s)) {
|
||||
++s->mNumProcessesRunning;
|
||||
MEMORY_REPORTING_LOG("HandleChildReports (aGen=%u): started child report"
|
||||
|
@ -508,18 +508,6 @@ XRE_API(void,
|
||||
XRE_API(void,
|
||||
XRE_StopLateWriteChecks, (void))
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
XRE_API(int,
|
||||
XRE_ProcLoaderServiceRun, (pid_t, int, int argc, const char* argv[],
|
||||
mozilla::Vector<int>& aReservedFds));
|
||||
XRE_API(void,
|
||||
XRE_ProcLoaderClientInit, (pid_t, int,
|
||||
mozilla::Vector<int>& aReservedFds));
|
||||
XRE_API(void,
|
||||
XRE_ProcLoaderPreload, (const char* aProgramDir,
|
||||
const nsXREAppData* aAppData));
|
||||
#endif // MOZ_B2G_LOADER
|
||||
|
||||
XRE_API(void,
|
||||
XRE_EnableSameExecutableForContentProc, ())
|
||||
|
||||
|
@ -37,18 +37,6 @@
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIXULAppInfo.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
#include "mozilla/XPTInterfaceInfoManager.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
#define XPTONLY_MANIFEST &nsComponentManagerImpl::XPTOnlyManifestManifest
|
||||
#define XPTONLY_XPT &nsComponentManagerImpl::XPTOnlyManifestXPT
|
||||
#else
|
||||
#define XPTONLY_MANIFEST nullptr
|
||||
#define XPTONLY_XPT nullptr
|
||||
#endif
|
||||
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -78,21 +66,14 @@ struct ManifestDirective
|
||||
void (nsChromeRegistry::*regfunc)(
|
||||
nsChromeRegistry::ManifestProcessingContext& aCx,
|
||||
int aLineNo, char* const* aArgv, int aFlags);
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
// The function to handle the directive for XPT Only parsing.
|
||||
void (*xptonlyfunc)(
|
||||
nsComponentManagerImpl::XPTOnlyManifestProcessingContext& aCx,
|
||||
int aLineNo, char* const* aArgv);
|
||||
#else
|
||||
void* xptonlyfunc;
|
||||
#endif
|
||||
|
||||
bool isContract;
|
||||
};
|
||||
static const ManifestDirective kParsingTable[] = {
|
||||
{
|
||||
"manifest", 1, false, false, true, true, false,
|
||||
&nsComponentManagerImpl::ManifestManifest, nullptr, XPTONLY_MANIFEST
|
||||
&nsComponentManagerImpl::ManifestManifest, nullptr, nullptr
|
||||
},
|
||||
{
|
||||
"binary-component", 1, true, true, false, false, false,
|
||||
@ -100,7 +81,7 @@ static const ManifestDirective kParsingTable[] = {
|
||||
},
|
||||
{
|
||||
"interfaces", 1, false, true, false, false, false,
|
||||
&nsComponentManagerImpl::ManifestXPT, nullptr, XPTONLY_XPT
|
||||
&nsComponentManagerImpl::ManifestXPT, nullptr, nullptr
|
||||
},
|
||||
{
|
||||
"component", 2, false, true, false, false, false,
|
||||
@ -484,9 +465,6 @@ ParseManifest(NSLocationType aType, FileLocation& aFile, char* aBuf,
|
||||
nsComponentManagerImpl::ManifestProcessingContext mgrcx(aType, aFile,
|
||||
aChromeOnly);
|
||||
nsChromeRegistry::ManifestProcessingContext chromecx(aType, aFile);
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
nsComponentManagerImpl::XPTOnlyManifestProcessingContext xptonlycx(aFile);
|
||||
#endif
|
||||
nsresult rv;
|
||||
|
||||
NS_NAMED_LITERAL_STRING(kPlatform, "platform");
|
||||
@ -775,11 +753,6 @@ ParseManifest(NSLocationType aType, FileLocation& aFile, char* aBuf,
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
if (aXPTOnly) {
|
||||
directive->xptonlyfunc(xptonlycx, line, argv);
|
||||
} else
|
||||
#endif /* MOZ_B2G_LOADER */
|
||||
if (directive->regfunc) {
|
||||
if (GeckoProcessType_Default != XRE_GetProcessType()) {
|
||||
continue;
|
||||
|
@ -107,36 +107,6 @@ NS_DEFINE_CID(kCategoryManagerCID, NS_CATEGORYMANAGER_CID);
|
||||
|
||||
#define UID_STRING_LENGTH 39
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
typedef nsDataHashtable<nsCStringHashKey, bool> XPTIInfosBookType;
|
||||
static XPTIInfosBookType* sXPTIInfosBook = nullptr;
|
||||
|
||||
static XPTIInfosBookType*
|
||||
GetXPTIInfosBook()
|
||||
{
|
||||
if (!sXPTIInfosBook) {
|
||||
sXPTIInfosBook = new XPTIInfosBookType;
|
||||
}
|
||||
return sXPTIInfosBook;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsRegisteredXPTIInfo(FileLocation& aFile)
|
||||
{
|
||||
nsAutoCString uri;
|
||||
aFile.GetURIString(uri);
|
||||
return GetXPTIInfosBook()->Get(uri);
|
||||
}
|
||||
|
||||
static void
|
||||
MarkRegisteredXPTIInfo(FileLocation& aFile)
|
||||
{
|
||||
nsAutoCString uri;
|
||||
aFile.GetURIString(uri);
|
||||
GetXPTIInfosBook()->Put(uri, true);
|
||||
}
|
||||
#endif /* MOZ_B2G_LOADER */
|
||||
|
||||
nsresult
|
||||
nsGetServiceFromCategory::operator()(const nsIID& aIID,
|
||||
void** aInstancePtr) const
|
||||
@ -682,12 +652,6 @@ nsComponentManagerImpl::ManifestBinaryComponent(ManifestProcessingContext& aCx,
|
||||
static void
|
||||
DoRegisterXPT(FileLocation& aFile)
|
||||
{
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
if (IsRegisteredXPTIInfo(aFile)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t len;
|
||||
FileLocation::Data data;
|
||||
UniquePtr<char[]> buf;
|
||||
@ -701,9 +665,6 @@ DoRegisterXPT(FileLocation& aFile)
|
||||
}
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
XPTInterfaceInfoManager::GetSingleton()->RegisterBuffer(buf.get(), len);
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
MarkRegisteredXPTIInfo(aFile);
|
||||
#endif
|
||||
} else {
|
||||
nsCString uri;
|
||||
aFile.GetURIString(uri);
|
||||
@ -911,10 +872,6 @@ nsresult nsComponentManagerImpl::Shutdown(void)
|
||||
|
||||
delete sStaticModules;
|
||||
delete sModuleLocations;
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
delete sXPTIInfosBook;
|
||||
sXPTIInfosBook = nullptr;
|
||||
#endif
|
||||
|
||||
// Unload libraries
|
||||
mNativeModuleLoader.UnloadLibraries();
|
||||
@ -2072,52 +2029,6 @@ nsComponentManagerImpl::GetManifestLocations(nsIArray** aLocations)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsComponentManagerImpl::XPTOnlyManifestManifest(
|
||||
XPTOnlyManifestProcessingContext& aCx, int aLineNo, char* const* aArgv)
|
||||
{
|
||||
char* file = aArgv[0];
|
||||
FileLocation f(aCx.mFile, file);
|
||||
|
||||
DoRegisterManifest(NS_APP_LOCATION, f, false, true);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsComponentManagerImpl::XPTOnlyManifestXPT(
|
||||
XPTOnlyManifestProcessingContext& aCx, int aLineNo, char* const* aArgv)
|
||||
{
|
||||
FileLocation f(aCx.mFile, aArgv[0]);
|
||||
DoRegisterXPT(f);
|
||||
}
|
||||
|
||||
/**
|
||||
* To load XPT Interface Information before the component manager is ready.
|
||||
*
|
||||
* With this function, B2G loader could XPT interface info. as earier
|
||||
* as possible to gain benefit of shared memory model of the kernel.
|
||||
*/
|
||||
/* static */ void
|
||||
nsComponentManagerImpl::PreloadXPT(nsIFile* aFile)
|
||||
{
|
||||
MOZ_ASSERT(!nsComponentManagerImpl::gComponentManager);
|
||||
FileLocation location(aFile, "chrome.manifest");
|
||||
|
||||
DoRegisterManifest(NS_APP_LOCATION, location,
|
||||
false, true /* aXPTOnly */);
|
||||
}
|
||||
|
||||
void
|
||||
PreloadXPT(nsIFile* aOmnijarFile)
|
||||
{
|
||||
nsComponentManagerImpl::PreloadXPT(aOmnijarFile);
|
||||
}
|
||||
|
||||
#endif /* MOZ_B2G_LOADER */
|
||||
|
||||
EXPORT_XPCOM_API(nsresult)
|
||||
XRE_AddManifestLocation(NSLocationType aType, nsIFile* aLocation)
|
||||
{
|
||||
|
@ -40,10 +40,6 @@
|
||||
#include "mozilla/Omnijar.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
#include "mozilla/FileLocation.h"
|
||||
#endif
|
||||
|
||||
struct nsFactoryEntry;
|
||||
class nsIServiceManager;
|
||||
struct PRThread;
|
||||
@ -334,31 +330,6 @@ public:
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
// Preload XPT interface info for B2G loader.
|
||||
// This function is called before XPCOM has been initialized.
|
||||
static void PreloadXPT(nsIFile* aFile);
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_B2G_LOADER
|
||||
// Parsing functions of directives of manifest for XPT only parsing.
|
||||
struct XPTOnlyManifestProcessingContext
|
||||
{
|
||||
XPTOnlyManifestProcessingContext(mozilla::FileLocation& aFile)
|
||||
: mFile(aFile)
|
||||
{
|
||||
}
|
||||
|
||||
~XPTOnlyManifestProcessingContext() {}
|
||||
|
||||
mozilla::FileLocation mFile;
|
||||
};
|
||||
static void XPTOnlyManifestManifest(XPTOnlyManifestProcessingContext& aCx,
|
||||
int aLineNo, char* const* aArgv);
|
||||
static void XPTOnlyManifestXPT(XPTOnlyManifestProcessingContext& aCx,
|
||||
int aLineNo, char* const* aArgv);
|
||||
#endif
|
||||
|
||||
private:
|
||||
~nsComponentManagerImpl();
|
||||
};
|
||||
|
@ -14,9 +14,6 @@
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/ThreadHangStats.h"
|
||||
#include "mozilla/ThreadLocal.h"
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
#include "prinrval.h"
|
||||
#include "prthread.h"
|
||||
@ -59,12 +56,6 @@ private:
|
||||
{
|
||||
PR_SetCurrentThreadName("BgHangManager");
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
NuwaMarkCurrentThread(nullptr, nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We do not hold a reference to BackgroundHangManager here
|
||||
because the monitor thread only exists as long as the
|
||||
BackgroundHangManager instance exists. We stop the monitor
|
||||
|
@ -23,10 +23,6 @@
|
||||
#include "nsExceptionHandler.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
@ -184,12 +180,6 @@ ThreadMain(void*)
|
||||
{
|
||||
PR_SetCurrentThreadName("Hang Monitor");
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
NuwaMarkCurrentThread(nullptr, nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
MonitorAutoLock lock(*gMonitor);
|
||||
|
||||
// In order to avoid issues with the hang monitor incorrectly triggering
|
||||
|
@ -386,10 +386,6 @@ TimerThread::Shutdown()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
struct MicrosecondsToInterval
|
||||
@ -413,12 +409,6 @@ TimerThread::Run()
|
||||
{
|
||||
PR_SetCurrentThreadName("Timer");
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
if (IsNuwaProcess()) {
|
||||
NuwaMarkCurrentThread(nullptr, nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
// We need to know how many microseconds give a positive PRIntervalTime. This
|
||||
@ -446,11 +436,7 @@ TimerThread::Run()
|
||||
bool forceRunThisTimer = forceRunNextTimer;
|
||||
forceRunNextTimer = false;
|
||||
|
||||
if (mSleeping
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
|| IsNuwaProcess() // Don't fire timers or deadlock will result.
|
||||
#endif
|
||||
) {
|
||||
if (mSleeping) {
|
||||
// Sleep for 0.1 seconds while not firing timers.
|
||||
uint32_t milliseconds = 100;
|
||||
if (ChaosMode::isActive(ChaosFeature::TimerScheduling)) {
|
||||
|
@ -43,10 +43,6 @@
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "private/pprthred.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_LINUX
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
@ -677,12 +673,6 @@ nsThread::PutEvent(already_AddRefed<nsIRunnable> aEvent, nsNestedEventTarget* aT
|
||||
LeakRefPtr<nsIRunnable> event(Move(aEvent));
|
||||
nsCOMPtr<nsIThreadObserver> obs;
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// On debug build or when tests are enabled, assert that we are not about to
|
||||
// create a deadlock in the Nuwa process.
|
||||
NuwaAssertNotFrozen(PR_GetThreadID(mThread), PR_GetThreadName(mThread));
|
||||
#endif
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
nsChainedEventQueue* queue = aTarget ? aTarget->mQueue : &mEventsRoot;
|
||||
|
@ -14,9 +14,6 @@
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
#ifdef MOZ_TASK_TRACER
|
||||
#include "GeckoTaskTracerImpl.h"
|
||||
using namespace mozilla::tasktracer;
|
||||
|
Loading…
x
Reference in New Issue
Block a user