它们通信的目的在于:

b2g要发消息给nuwa,让它fork出web app进程。它们发生在nuwa进程已经完全启动,并准备好fork 其他app子进程。猜想,用的是socket pair 建立关系,ipdl(最终用的是共享内存读写)进行线程级别的信息交互。socket pair只是用于建立通道???

nuwa的操作,从b2g开始fork出两个进程之后,兵分两路,nuwa进程完成自己的所有初始化(包括哪些?)且一直在等待b2g的加载新进程的消息。b2g也一路走下去,完成初始化等,并在appstartup 请求nuwa加载新进程。

具体通信:

/*** 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.*创建parent actor 用于请求nuwa加载进程* 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.*/
/**
 * 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.
 *创建parent actor 用于请求nuwa加载进程
 * 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.
 */

#include "mozilla/ipc/PProcLoaderParent.h"
#include "mozilla/ipc/PProcLoaderChild.h"

gecko/ipc/glue/ProcessUtils_linux.cpp

前b2g:

main->LoadStaticData  ->LoadLibxul-> XPCOMGlueEnablePreload--->//设置值为true ,使得可preload,预加载

main->LoadStaticData  ->LoadLibxul -> XPCOMGlueStartup--->XPCOMGlueLoad --->ReadDependentCB//获取5个.so库

main->LoadStaticData  ->LoadLibxul  -> XPCOMGlueLoadXULFunctions--->//加载出GlueLoadXUL函数,并保存其地址,两次加载的函数不一样

main->LoadStaticData  ->XRE_ProcLoaderPreload --->//开始preload,进程预加载
.cpp:945, Fuc:XRE_ProcLoaderPreload  >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func
.cpp:950, Fuc:XRE_ProcLoaderPreload  call NS_NewNativeLocalFile-->//新的本地文件
.cpp:951, Fuc:XRE_ProcLoaderPreload  aProgramDir:/system/b2g/,omnijarFile//程序目录
.cpp:957, Fuc:XRE_ProcLoaderPreload  call Omnijar->AppendNative--->//添加进omnijar中
.cpp:970, Fuc:XRE_ProcLoaderPreload  <<<<<<<<<<<<<<<<<<<<<<<<<<<ed.func

以上数据函数库等完全准备好了。

完毕之后就开始:

main --> return RunProcesses(argc, argv, reservedFds)

开始fork后分出两个进程进行工作。

main()     (b2g/app/B2GLoader.cpp)
|
|-ReserveFileDescriptors
|
|-LoadStaticData
|
|-RunProcesses
       |
       |-fork
       |
       |-XRE_ProcLoaderServiceRun      (child(nuwa) process)
       |
       |-b2g_main               (parent(b2g) process) (b2g/app/nsBrowserApp.cpp)
                |
                |-android::ProcessState::self()->startThreadPool();
                |
                |-(void)setsid();
                |
                |-do_main
                         |
                         |-mozilla::StartBootAnimation();
                         |
                         |-XRE_main
                               |
                               |-XREMain::XRE_main

nuwa process:

main ->RunProcesses->XRE_ProcLoaderServiceRun -> mozilla::ipc::ProcLoaderServiceRun(aPeerPid:180, aFd:14,aArgc:1, aArgv[...0]:/system/b2g/b2g,aReservedFds[...0]:3)

RunProcesses->XRE_ProcLoaderServiceRun->ProcLoaderServiceRun->

(1XRE_InitCommandLine->XRE_GetBinaryPath(aArgv:/system/b2g/b2g)

(2process= new ContentProcess(aPeerPid:179)--->

ChildThread *iothread = process->child_thread();

(3new ProcLoaderChild(aPeerPid:179)->iothread->message_loop()

ProcLoaderChild *loaderChild = new ProcLoaderChild(aPeerPid)

loaderChild->Open(transport, aPeerPid, iothread->message_loop())

ProcessChild::ProcessChild(ProcessId aParentPid)
  : ChildProcess(new IOThreadChild())
  , mUILoop(MessageLoop::current())
  , mParentPid(aParentPid)
{ ... }

(4BackgroundHangMonitor::Prohibit()

(5loop.Run();
  
(6    BackgroundHangMonitor::Allow();
  
(7    XRE_DeinitCommandLine();

(8  int ret = task->DoWork()->int ret = content_process_main(argc, argv)

RunProcesses开始,

nuwa 进程被fork 出来,去执行XRE_ProcLoaderServiceRun->ProcLoaderServiceRun  call XRE_InitCommandLine--->

Fuc:RunProcesses  ### pid >0 is parentSock(Pid of childSock), or 0 is return by childSock:0
Fuc:RunProcesses  ### pid=0,|pid='0',it is childprocess|, isChildProcess=1
Fuc:RunProcesses  close parentSock,in nuwa(child) process
Fuc:RunProcesses  call XRE_ProcLoaderServiceRun--->
Fuc:RunProcesses  XRE_ProcLoaderServiceRun(getppid():181, childSock:14, argc:1, argv:/system/b2g/b2g,aReservedFds[...0]:3)
ipc/glue/ProcessUtils_linux.cpp:672, Fuc:XRE_ProcLoaderServiceRun  ----------------------------------
ipc/glue/ProcessUtils_linux.cpp:673, Fuc:XRE_ProcLoaderServiceRun  .==nuwa process==. XRE_ProcLoaderServiceRun call mozilla::ipc::ProcLoaderServiceRun(aPeerPid:181, aFd:14,aArgc:1, aArgv[...0]:/system/b2g/b2g,aReservedFds[...0]:3)
ipc/glue/ProcessUtils_linux.cpp:577, Fuc:ProcLoaderServiceRun  ----------------------------------
ipc/glue/ProcessUtils_linux.cpp:588, Fuc:ProcLoaderServiceRun  aArgv[i]:/system/b2g/b2g
ipc/glue/ProcessUtils_linux.cpp:597, Fuc:ProcLoaderServiceRun  call XRE_InitCommandLine--->b2g ,nuwa都要来执行这个模块,为了getbinarypath 二进制可执行文件的地址?
cpp:4583, Fuc:XRE_InitCommandLine  ----------------------------------

nuwa 进程被fork 出来,去执行XRE_ProcLoaderServiceRun->ProcLoaderServiceRun  ->XRE_InitCommandLine--->

XRE_ProcLoaderServiceRun传入b2g的pid,child的sock 号,就直接去初始化XRE_InitCommandLine,

Fuc:XRE_InitCommandLine  XRE_GetBinaryPath(aArgv:/system/b2g/b2g)--->//一样,获取地址
rocessUtils_linux.cpp:610, Fuc:ProcLoaderServiceRun  new ContentProcess(aPeerPid:181)--->
rocessChild.cpp:46, Fuc:ProcessChild  >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func
rocessUtils_linux.cpp:615, Fuc:ProcLoaderServiceRun  new ProcLoaderChild(aPeerPid:181)--->//传入b2g的进程pid,是直接复制b2g一模一样的资源吗?
rocessUtils_linux.cpp:619, Fuc:ProcLoaderServiceRun      loaderChild->Open(transport, aPeerPid, iothread->message_loop())//加载子进程并打开,io线程执行message_loop,并与b2g进程进行传输消息?
rocessUtils_linux.cpp:621, Fuc:ProcLoaderServiceRun  call BackgroundHangMonitor::Prohibit()--->//禁止后台挂起监控
rocessUtils_linux.cpp:625, Fuc:ProcLoaderServiceRun  call loop.Run--->//循环运行

/**
 * Run service of ProcLoader.//开启进程加载器的服务端,一直在那里运行,传入参数就是b2g进程的pid,以及socket的文件描述符(父进程的?不对是childSock:14,)
 *
 * \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)
{

...

}

///

//

b2g process:

1.

1.1main ->RunProcesses->XRE_ProcLoaderClientInit->ProcLoaderClientInit //初始化client 端,各数据供后与nuwa通信用

XRE_ProcLoaderClientInit call mozilla::ipc::ProcLoaderClientInit(aPeerPid:556, aChannelFd:13)

ProcLoaderClientInit  sProcLoaderPid:556,sProcLoaderChannelFd:13,sProcLoaderClientInitialized:true

初始化这些数据,供后面nuwa 与b2g 通信时建立连接等。

1.2main ->RunProcesses->b2g_main  -> startThreadPool--->//共享线程池
1.3main ->RunProcesses->b2g_main  ->XPCOMGlueLoadXULFunctions //再次加载GlueLoadXUL函数

抓重点!!!别看些细枝末节的东西。

1.4b2g_main->do_main  -> StartBootAnimation--->//开机动画

1.5main ->RunProcesses->b2g_main  -> do_main--->XRE_main

b2g_main->do_main  -> XRE_main--->XRE_main::XRE_main()->:

b2g_main->do_main-> XRE_main--->XRE_main::XRE_main()  -> XRE_mainInit--->mDirProvider.Initialize-->//初始化目录服务

XRE_mainInit  -> XRE_InitCommandLine()-->//xre 主初始化命令行,

XRE_main::XRE_main()  -> XRE_mainStartup--->//主启动,版本创建

ScopedXPCOMStartup::Initialize()

XRE_main::XRE_main()  ->rv = mScopedXPCOM->Initialize()--->NS_InitXPCOM2-->//初始化并启动xpcom等

fork分开之初:

Fuc:RunProcesses  aReservedFds:0,argv[]:PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin
Fuc:RunProcesses  aReservedFds:0,argv[]:LOOP_MOUNTPOINT=/mnt/obb
Fuc:RunProcesses  aReservedFds:-1229987536,argv[]:ANDROID_DATA=/data
Fuc:RunProcesses  aReservedFds:1,argv[]:ANDROID_ROOT=/system
Fuc:RunProcesses  aReservedFds:0,argv[]:EMULATED_STORAGE_TARGET=/storage/emulated
Fuc:RunProcesses  virtual fd from socketpair,ipcSockets[0]:13,ipcSockets[1]:14
Fuc:RunProcesses  parentSock:13,childSock:14
Fuc:RunProcesses  before fork,childSock:14,parentSock:13

Fuc:RunProcesses  ### pid >0 is parentSock(Pid of childSock), or 0 is return by childSock:530
Fuc:RunProcesses  ### pid=530,|pid='0',it is childprocess|, isChildProcess=0
Fuc:RunProcesses  close childSock,in b2g(parent) process
Fuc:RunProcesses  call XRE_ProcLoaderClientInit--->
Fuc:RunProcesses  XRE_ProcLoaderClientInit(childPid:530, parentSock:13, aReservedFds[...03)]:
ipc/glue/ProcessUtils_linux.cpp:658, Fuc:XRE_ProcLoaderClientInit  ----------------------------------
ipc/glue/ProcessUtils_linux.cpp:661, Fuc:XRE_ProcLoaderClientInit  call  mozilla::ipc::CloseFileDescriptors(aReservedFds)
ipc/glue/ProcessUtils_linux.cpp:663, Fuc:XRE_ProcLoaderClientInit  .==b2g process==. XRE_ProcLoaderClientInit call mozilla::ipc::ProcLoaderClientInit(aPeerPid:530, aChannelFd:13)
ipc/glue/ProcessUtils_linux.cpp:216, Fuc:ProcLoaderClientInit  ----------------------------------
ipc/glue/ProcessUtils_linux.cpp:222,Fuc:ProcLoaderClientInit  sProcLoaderPid:530,sProcLoaderChannelFd:13,sProcLoaderClientInitialized:true
Fuc:RunProcesses  call return b2g_main(argc:1,argv:/system/b2g/b2g)--->
g_main  >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func

p:330, Fuc:RunProcesses  call return b2g_main(argc:1,argv:/system/b2g/b2g)--->
 Fuc:b2g_main  >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func

 Fuc:b2g_main  call startThreadPool--->
 Fuc:b2g_main  call XPCOMGlueLoadXULFunctions 2cond --->
COMGlue.cpp:446, Fuc:XPCOMGlueLoadXULFunctions  ----------------------------------
COMGlue.cpp:451, Fuc:XPCOMGlueLoadXULFunctions  sTop->libHandle:libxul.so

main() ->RunProcesses fork 出2进程后:

main() ->RunProcesses->b2g_main  -> XPCOMGlueLoadXULFunctions 不厌其烦地废话!!!

XPCOMGlueLoadXULFunctions 就加载些函数,并不是重点,过。

call XPCOMGlueLoadXULFunctions 2cond --->//第一次是在LoadStaticdata
, Fuc:XPCOMGlueLoadXULFunctions  ----------------------------------
, Fuc:XPCOMGlueLoadXULFunctions  sTop->libHandle:libxul.so
, Fuc:XPCOMGlueLoadXULFunctions  aSymbols->functionName:XRE_GetFileFromPath
, Fuc:XPCOMGlueLoadXULFunctions  buffer:XRE_GetFileFromPath
, Fuc:XPCOMGlueLoadXULFunctions  call GetSymbol(sTop->libHandle, buffer)--->
, Fuc:GetSymbol  dlsym: XRE_GetFileFromPath
, Fuc:XPCOMGlueLoadXULFunctions  result of GetSymbol: aSymbols->function:b4ef5bed
, Fuc:XPCOMGlueLoadXULFunctions  ++aSymbols:b6fe7da0
, Fuc:XPCOMGlueLoadXULFunctions  aSymbols->functionName:XRE_CreateAppData
, Fuc:XPCOMGlueLoadXULFunctions  buffer:XRE_CreateAppData
, Fuc:XPCOMGlueLoadXULFunctions  call GetSymbol(sTop->libHandle, buffer)--->
, Fuc:GetSymbol  dlsym: XRE_CreateAppData
, Fuc:XPCOMGlueLoadXULFunctions  result of GetSymbol: aSymbols->function:b4efec61
, Fuc:XPCOMGlueLoadXULFunctions  ++aSymbols:b6fe7da8
, Fuc:XPCOMGlueLoadXULFunctions  aSymbols->functionName:XRE_FreeAppData
, Fuc:XPCOMGlueLoadXULFunctions  buffer:XRE_FreeAppData
, Fuc:XPCOMGlueLoadXULFunctions  call GetSymbol(sTop->libHandle, buffer)--->
, Fuc:GetSymbol  dlsym: XRE_FreeAppData
, Fuc:XPCOMGlueLoadXULFunctions  result of GetSymbol: aSymbols->function:b4efce11
, Fuc:XPCOMGlueLoadXULFunctions  ++aSymbols:b6fe7db0
, Fuc:XPCOMGlueLoadXULFunctions  aSymbols->functionName:XRE_TelemetryAccumulate
, Fuc:XPCOMGlueLoadXULFunctions  buffer:XRE_TelemetryAccumulate
, Fuc:XPCOMGlueLoadXULFunctions  call GetSymbol(sTop->libHandle, buffer)--->
, Fuc:GetSymbol  dlsym: XRE_TelemetryAccumulate
, Fuc:XPCOMGlueLoadXULFunctions  result of GetSymbol: aSymbols->function:b4ee0089
, Fuc:XPCOMGlueLoadXULFunctions  ++aSymbols:b6fe7db8
, Fuc:XPCOMGlueLoadXULFunctions  aSymbols->functionName:XRE_main
, Fuc:XPCOMGlueLoadXULFunctions  buffer:XRE_main
, Fuc:XPCOMGlueLoadXULFunctions  call GetSymbol(sTop->libHandle, buffer)--->
, Fuc:GetSymbol  dlsym: XRE_main
, Fuc:XPCOMGlueLoadXULFunctions  result of GetSymbol: aSymbols->function:b4efbfed
, Fuc:XPCOMGlueLoadXULFunctions  ++aSymbols:b6fe7dc0
gotCounters:1
rocesses  ### pid >0 is parentSock(Pid of childSock), or 0 is return by childSock:0

中间分析:b2g -> nuwa 猜想假设等

RunProcesses  XRE_ProcLoaderClientInit(childPid:530, parentSock:13, aReservedFds[...0]:3)

ProcLoaderClientGeckoInit    sProcLoaderParent = new ProcLoaderParent()

RunProcesses  XRE_ProcLoaderServiceRun(getppid():181, childSock:14, argc:1, argv:/system/b2g/b2g,aReservedFds[...0]:3)

ProcLoaderServiceRun  new ContentProcess(aPeerPid:181)--->,

new ProcLoaderChild(aPeerPid:181)

在b2g 和nuwa之间,起触发因素的似乎是appstartup,猜想,是appstartup 提交了启动应用的请求,b2g发消息给nuwa,nuwa结束目前循环,加载出来一个进程(对应一个上层应用),然后把它丢到后台,继续回来接活,直到又有新应用向b2g发请求,说”给我拉起一个进程,让这家伙跑“,nuwa接到活后快乐的去把它拉起来,丢到后台,然后继续出来接活,反反复复。

nuwa其实就是一个进程生产器,生产出来就丢出去,至于它们跟b2g的通信,或者进程和进程之间的通信,应该是它们自己解决,如何呢?ipdl如何运作?以及猜想是否正确,待验证。

b2g总模块:

从main->RunProcesses  -> return b2g_main()进来开始,

b2g_main  call startThreadPool--->//启动线程池子
b2g_main  call XPCOMGlueLoadXULFunctions 2cond --->//加载公用函数,保存其地址

b2g_main  call do_main--->

do_main  call StartBootAnimation--->//调用开机动画模块

do_main  call return XRE_main--->

main()     (b2g/app/B2GLoader.cpp)
|
|-ReserveFileDescriptors
|
|-LoadStaticData
|
|-RunProcesses
       |
       |-fork
       |
       |-XRE_ProcLoaderServiceRun      (child(nuwa) process)
       |
       |-b2g_main               (parent(b2g) process) (b2g/app/nsBrowserApp.cpp)
                |
                |-android::ProcessState::self()->startThreadPool();
                |
                |-(void)setsid();
                |
                |-do_main
                         |
                         |-mozilla::StartBootAnimation();
                         |
                         |-XRE_main
                               |
                               |-XREMain::XRE_main

gecko/toolkit/xre/nsAppRunner.cpp:4569, Fuc:XRE_main  >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func

|-XREMain::XRE_main
       |
       |-new ScopedAppData(aAppData);
       |
       |-XREMain::XRE_mainInit
       |
       |-XREMain::XRE_mainStartup
       |
       |-mScopedXPCOM = MakeUnique<ScopedXPCOMStartup>();
       |
       |-mScopedXPCOM->Initialize();          (toolkit/xre/nsAppRunner.cpp)
       |           |
       |           |-NS_InitXPCOM2                       (xpcom/build/XPCOMInit.cpp)
       |                  |
       |                  |-sMessageLoop = new MessageLoopForUI(MessageLoop::TYPE_MOZILLA_UI);
       |                  |
       |                  |-ioThread = MakeUnique<BrowserProcessSubThread>(BrowserProcessSubThread::IO);
       |                  |-ioThread->StartWithOptions
       |                  |
       |                  |-nsThreadManager::get()->Init();
       |                  |
       |                  |-nsTimerImpl::Startup();
       |                  |
       |                  |-nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl();
       |                  |
       |                  |-nsCycleCollector_init
       |                  |
       |                  |-nsCycleCollector_startup
       |                  |
       |                  |-JS_Init
       |                  |
       |                  |-nsComponentManagerImpl::gComponentManager->Init();(xpcom/components/nsComponentManager.cpp)
       |                  |     |
       |                  |     |-nsComponentManagerImpl::InitializeStaticModules()
       |                  |     |
       |                  |     |-RegisterModule(...)
       |                  |     |
       |                  |     |-greOmnijar =mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE);
       |                  |     |
       |                  |     |-cl->location.Init(greOmnijar, "chrome.manifest");
       |                  |     |
       |                  |     |-nsComponentManagerImpl::RereadChromeManifests
       |                  |               |
       |                  |               |-nsComponentManagerImpl::RegisterManifest
       |                  |                       |
       |                  |                       |-DoRegisterManifest
       |                  |                                |
       |                  |                                |-ParseManifest
       |                  |                                      |
       |                  |                                      |-...
       |                  |                                      |
       |                  |                                      |-nsComponentManagerImpl::ManifestContract
       |                  |
       |                  |-XPTInterfaceInfoManager::GetSingleton();
       |                  |
       |                  |-nsDirectoryService::gService->RegisterCategoryProviders();
       |                  |
       |                  |-SharedThreadPool::InitStatics();
       |                  |
       |                  |-AbstractThread::InitStatics();
       |                  |
       |                  |-mozilla::scache::StartupCache::GetSingleton();
       |                  |
       |                  |-mozilla::AvailableMemoryTracker::Activate();
       |                  |
       |                  |-NS_CreateServicesFromCategory(...)
       |                  |
       |                  |-mozilla::HangMonitor::Startup();
       |                  |
       |                  |-mozilla::BackgroundHangMonitor::Startup();
       |                  |
       |                  |-sMainHangMonitor = new mozilla::BackgroundHangMonitor
       |                  
       |-XREMain::XRE_mainRun()
                |
                |-mozilla::ipc::ProcLoaderClientGeckoInit();
                |
                |-mScopedXPCOM->SetWindowCreator(mNativeApp);
                |
                |-startupNotifier->Observe(nullptr, APPSTARTUP_TOPIC, nullptr);
                |
                |-mDirProvider.DoStartup();
                |
                |-cmdLine->Init(...)
                |
                |-obsService->NotifyObservers(cmdLine, "command-line-startup", nullptr);
                |
                |-appStartup->CreateHiddenWindow();
                |
                |-obsService->NotifyObservers(nullptr, "final-ui-startup", nullptr);
                |
                |-cmdLine->Run();     (toolkit/components/commandlines/nsCommandLine.cpp)
                |          |
                |          |- nsCommandLine::EnumerateValidators
                |          |
                |          |-nsCommandLine::EnumerateHandlers
                |                  |
                |                  |-EnumRun
                |                        |
                |                        |-nsICommandLineHandler->Handle   (first page will be loaded in here)        
                |                                  
                |-mNativeApp->Enable();
                |
                |-appStartup->Run();     (toolkit/components/startup/nsAppStartup.cpp)
                          |
                          |-mAppShell->Run();         (widget/gonk/nsAppShell.cpp->widget/nsBaseAppShell.cpp)
                                   |
                                   |-MessageLoop::current()->Run();  // run forever~~~~~

重点分析XRE_main:

结构:

|-new ScopedAppData(aAppData);
       |
       |-XREMain::XRE_mainInit//简言之,开启路径获取模块,获取路径
       |
       |-XREMain::XRE_mainStartup//设置关闭检查,创建版本
       |
       |-mScopedXPCOM = MakeUnique<ScopedXPCOMStartup>();
       |
       |-mScopedXPCOM->Initialize();          (toolkit/xre/nsAppRunner.cpp)

|-XREMain::XRE_mainRun()

前3个稍微了解即可,初始化启动些必要的东西。简言之,准备数据,数据丢进运行功能模块运行。

do_main  call return XRE_main--->//进入xre_main
:do_main  <<<<<<<<<<<<<<<<<<<<<<<<<<<ed.func
er.cpp:4569, Fuc:XRE_main  >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func
er.cpp:4571, Fuc:XRE_main  call XRE_CreateStatsObject--->//创建对象?不重要
er.cpp:4573, Fuc:XRE_main  call main.XRE_main()--->
er.cpp:4403, Fuc:XRE_main  ----------------------------------
er.cpp:4408, Fuc:XRE_main  call profilerGuard--->//保护设置
er.cpp:4418, Fuc:XRE_main  gArgc:1,gArgv:/system/b2g/b2g
er.cpp:4440, Fuc:XRE_main  call XRE_mainInit--->
er.cpp:3140, Fuc:XRE_mainInit  ----------------------------------
er.cpp:3218, Fuc:XRE_mainInit  chek for application.ini override//检查覆盖
er.cpp:3254, Fuc:XRE_mainInit  XRE_GetBinaryPath-->//获取二进制文件路径
er.cpp:3301, Fuc:XRE_mainInit  mDirProvider.Initialize-->//初始化目录提供服务模块
er.cpp:3310, Fuc:XRE_mainInit  MOZ_CRASHREPORTER
er.cpp:3504, Fuc:XRE_mainInit  call XRE_InitCommandLine()-->//b2g ,nuwa都要来执行这个模块,为了getbinarypath 二进制可执行文件的地址?
er.cpp:4583, Fuc:XRE_InitCommandLine  ----------------------------------
er.cpp:4595, Fuc:XRE_InitCommandLine  XRE_GetBinaryPath(aArgv:/system/b2g/b2g)--->//获取二进制文件路径,不重要
er.cpp:3527, Fuc:XRE_mainInit  <<<<<<<<<<<<<<<<<<<<<<<<<<<ed.func//mainInit主要的初始化结束,
er.cpp:4446, Fuc:XRE_main  XRE_mainStartup--->
er.cpp:3658, Fuc:XRE_mainStartup  ----------------------------------
er.cpp:3664, Fuc:XRE_mainStartup  call SetShutdownChecks()-->//设置关闭/机检查
er.cpp:3964, Fuc:XRE_mainStartup  call BuildVersion-->//创建版本?不重要
er.cpp:4050, Fuc:XRE_mainStartup  <<<<<<<<<<<<<<<<<<<<<<<<<<<ed.func
er.cpp:4454, Fuc:XRE_main  call MakeUnique--->
er.cpp:4459, Fuc:XRE_main  ----------------------------------
er.cpp:4460, Fuc:XRE_main   ScopedXPCOMStartup::Initialize()
er.cpp:4461, Fuc:XRE_main    rv = mScopedXPCOM->Initialize()--->
er.cpp:1571, Fuc:Initialize  ----------------------------------
er.cpp:1575, Fuc:Initialize  ---here ,startup xpcom---
er.cpp:1576, Fuc:Initialize  ScopedXPCOMStartup::Initialize,call NS_InitXPCOM2-->
xpcom/build/XPCOMInit.cpp:512, Fuc:NS_InitXPCOM2  ----------------------------------

NS_InitXPCOM2重点分析:b2g process

|
|-NS_InitXPCOM2                       (xpcom/build/XPCOMInit.cpp)
       |
       |-sMessageLoop = new MessageLoopForUI(MessageLoop::TYPE_MOZILLA_UI);//创建UI的messageloop,与界面请求相关,点击等
       |
       |-ioThread = MakeUnique<BrowserProcessSubThread>(BrowserProcessSubThread::IO);
       |-ioThread->StartWithOptions
       |
       |-nsThreadManager::get()->Init();
       |
       |-nsTimerImpl::Startup();
       |
       |-nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl();
       |
       |-nsCycleCollector_init
       |
       |-nsCycleCollector_startup
       |
       |-JS_Init
       |
       |-nsComponentManagerImpl::gComponentManager->Init();(xpcom/components/nsComponentManager.cpp)
       |     |
       |     |-nsComponentManagerImpl::InitializeStaticModules()
       |     |
       |     |-RegisterModule(...)
       |     |
       |     |-greOmnijar =mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE);
       |     |
       |     |-cl->location.Init(greOmnijar, "chrome.manifest");
       |     |
       |     |-nsComponentManagerImpl::RereadChromeManifests
       |               |
       |               |-nsComponentManagerImpl::RegisterManifest
       |                       |
       |                       |-DoRegisterManifest
       |                                |
       |                                |-ParseManifest
       |                                      |
       |                                      |-...
       |                                      |
       |                                      |-nsComponentManagerImpl::ManifestContract
       |
       |-XPTInterfaceInfoManager::GetSingleton();
       |
       |-nsDirectoryService::gService->RegisterCategoryProviders();
       |
       |-SharedThreadPool::InitStatics();
       |
       |-AbstractThread::InitStatics();
       |
       |-mozilla::scache::StartupCache::GetSingleton();
       |
       |-mozilla::AvailableMemoryTracker::Activate();
       |
       |-NS_CreateServicesFromCategory(...)
       |
       |-mozilla::HangMonitor::Startup();
       |
       |-mozilla::BackgroundHangMonitor::Startup();
       |
       |-sMainHangMonitor = new mozilla::BackgroundHangMonitor

b2g process NS_InitXPCOM2部分Log分析:

Fuc:XRE_main    rv = mScopedXPCOM->Initialize()--->//开始进入初始化xpcom的入口
 Fuc:Initialize  ----------------------------------
 Fuc:Initialize  ---here ,startup xpcom---
 Fuc:Initialize  ScopedXPCOMStartup::Initialize,call NS_InitXPCOM2-->//调NS_InitXPCOM2
c:NS_InitXPCOM2  ----------------------------------//进NS_InitXPCOM2
c:NS_InitXPCOM2  the whole process: main()->RunProcesses()->b2g_main()->do_main()->XRE_main->ScopedXPCOMStartup::Initialize()->NS_InitXPCOM2()

Fuc:NS_InitXPCOM2  call -- mozilla::AvailableMemoryTracker::Init(); --->
 Fuc:NS_InitXPCOM2  return value of MessageLoop::current = false//测试messageloop::current 是否已存在,作为判断是否是第一次开启的开关
 Fuc:NS_InitXPCOM2  call -- sMessageLoop = new MessageLoopForUI(MessageLoop::TYPE_MOZILLA_UI); --->//创建UI的messageloop,与界面请求相关,点击等
 Fuc:NS_InitXPCOM2  call -- sMessageLoop->set_thread_name('Gecko'); --->
 Fuc:NS_InitXPCOM2  call -- sMessageLoop->set_hang_timeouts(128, 8192); --->//设置挂起时间
 Fuc:NS_InitXPCOM2   if (XRE_IsParentProcess() && !BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)) = ??         //是父进程(仅b2g或者包括其他父进程?)且BrowserProcessSubThread::GetMessageLoop(nuwa那边)为false,即没有messageloop?简言之,保证是初次启动xpcom,且没有messageloop
 Fuc:NS_InitXPCOM2   if (XRE_IsParentProcess() && !BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)) = true       //进来了,满足两个条件,
 Fuc:NS_InitXPCOM2  call -- UniquePtr<BrowserProcessSubThread> ioThread = MakeUnique<BrowserProcessSubThread>(BrowserProcessSubThread::IO); --->//new(创建) 了一个BrowserProcessSubThread::IO线程
 Fuc:NS_InitXPCOM2  call -- options.message_loop_type = MessageLoop::TYPE_IO; --->//设置线程类型,
 Fuc:NS_InitXPCOM2  call -- sIOThread = ioThread.release(); --->//释放线程???阻塞模式,直到所有工作完成才会释放 shutdown?
 Fuc:NS_InitXPCOM2   Establish the main thread here.//创建主线程,
 Fuc:NS_InitXPCOM2  call -- rv = nsThreadManager::get()->Init(); --->//创建主线程,初始化
 Fuc:NS_InitXPCOM2  call -- // Set up the timer globals/timer thread --->
 Fuc:NS_InitXPCOM2  call -- rv = nsTimerImpl::Startup(); --->//启动timer线程,用于???
 Fuc:NS_InitXPCOM2  call -- NS_StartupLocalFile(); --->//启动localfile服务
 Fuc:NS_InitXPCOM2  call -- if (aBinDirectory) { --->//获取二进制文件目录?
 Fuc:NS_InitXPCOM2  call -- nsDirectoryService::gService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, --->//设置当前进程目录
 Fuc:NS_InitXPCOM2  aAppFileLocationProvider = true,call RegisterProvider()-->//获取app文件成功后,调用注册服务,注册组件?
 Fuc:NS_InitXPCOM2  call -- nsDirectoryService::gService->Get(NS_GRE_BIN_DIR, --->//获取二进制文件目录
 Fuc:NS_InitXPCOM2  call -- xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL)); --->
 Fuc:NS_InitXPCOM2  call -- nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib); --->//设置库文件路径    Fuc:NS_InitXPCOM2  call -- if (!mozilla::Omnijar::IsInitialized()) { --->//omnijar 未初始化则进行初始化,
 Fuc:NS_InitXPCOM2  call -- if (!mozilla::Omnijar::IsInitialized()) { --->
 Fuc:NS_InitXPCOM2  call -- mozilla::Omnijar::Init(); --->//按照所提供的NSfile 去调取相应的app???组件?
 Fuc:NS_InitXPCOM2  Create the Component/Service Manage----
 Fuc:NS_InitXPCOM2  call -- nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl(); --->//创建组件服务和管理
 Fuc:NS_InitXPCOM2  call -- // Global cycle collector initialization.  --->//全局循环收集器初始化
 Fuc:NS_InitXPCOM2  call -- if (!nsCycleCollector_init()) { --->//若未初始化则初始化
 Fuc:NS_InitXPCOM2  call -- nsCycleCollector_startup(); --->//并启动循环收集器
 Fuc:NS_InitXPCOM2  call -- mozilla::SetICUMemoryFunctions(); --->
 Fuc:NS_InitXPCOM2  ----- Initialize the JS engine -----//初始化js 引擎
 Fuc:NS_InitXPCOM2    if (!JS_Init()),call JS_Init()--->
 Fuc:NS_InitXPCOM2  call -- rv = nsComponentManagerImpl::gComponentManager->Init(); --->//初始化组件管理器,,,

MessageLoop最早出现在这里,可能是某个地方初始化时就启动了,未查明,不管了,不重要,估计单开了某个线程专门用于此
MessageLoop  ----------------------------------
MessageLoop      return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
MessageLoop  ----------------------------------
MessageLoop      return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)

 Fuc:NS_InitXPCOM2      NS_ADDREF(*aResult = nsComponentManagerImpl::gComponentManager)
 Fuc:NS_InitXPCOM2   The iimanager constructor searches and registers XPT files.---
 Fuc:NS_InitXPCOM2  call -- (void)XPTInterfaceInfoManager::GetSingleton(); --->//单例模式自动注册xpt,在这些组件均未实例化之前
 Fuc:NS_InitXPCOM2  call -- // After autoreg, but before we actually instantiate any components, // add any services listed in the 'xpcom-directory-providers' category // to the directory service.  --->
 Fuc:NS_InitXPCOM2    nsDirectoryService::gService->RegisterCategoryProviders()-->//自动注册组件,多个个???
 Fuc:NS_InitXPCOM2  call -- // Init SharedThreadPool (which needs the service manager).  --->
 Fuc:NS_InitXPCOM2  call -- SharedThreadPool::InitStatics(); --->//共享线程初始化
 Fuc:NS_InitXPCOM2  call -- AbstractThread::InitStatics(); --->//抽象?线程初始化
 Fuc:NS_InitXPCOM2  do_GetService of jsloader----
 Fuc:NS_InitXPCOM2   componentLoader =    do_GetService('@mozilla.org/moz/jsloader;1')--->//实例化jsloader服务
 Fuc:NS_InitXPCOM2    // Notify observers of xpcom autoregistration star//
 Fuc:NS_InitXPCOM2  NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_CATEGORY,nullptr,NS_XPCOM_STARTUP_OBSERVER_ID) --->//创建监听服务,xpcom启动后的监听观察者
 Fuc:NS_InitXPCOM2   XRE_IsParentProcess =true,call  mozilla::SystemMemoryReporter::Init()--->//是父进程则
 Fuc:NS_InitXPCOM2  call -- // The memory reporter manager is up and running -- register our reporters.  --->
 Fuc:NS_InitXPCOM2  call -- RegisterStrongMemoryReporter(new ICUReporter()); --->//注册内存报告服务
 Fuc:NS_InitXPCOM2  call -- mozilla::Telemetry::Init(); --->//远程测试?初始化
 Fuc:NS_InitXPCOM2  call -- mozilla::HangMonitor::Startup(); --->//启动挂起监控
 Fuc:NS_InitXPCOM2  call -- mozilla::BackgroundHangMonitor::Startup(); --->//启动后台挂起监控

Fuc:NS_InitXPCOM2  call -- const MessageLoop* const loop = MessageLoop::current(); --->//调用消息队列循环,它之前为何出现messageloop 的信息

Fuc:NS_InitXPCOM2  call -- sMainHangMonitor = new mozilla::BackgroundHangMonitor( loop->thread_name().c_str(), loop->transient_hang_timeout(), loop->permanent_hang_timeout()); --->")//新建一个后台挂起监控,监听(线程名,短暂挂起,永久挂起)情况

--->startup xpcom seccessed?? call do_QueryInterface(mServiceManager)-->
Fuc:XRE_main  call XRE_mainRun--->
XRE_mainRun  ----------------------------------
call mozilla::ipc::ProcLoaderClientGeckoInit()--->

启动app(nuwa)进程 部分:

|-XREMain::XRE_mainRun()
         |
         |-mozilla::ipc::ProcLoaderClientGeckoInit();//调用ProcLoaderClientGeckoInit与service端建立连接?
         |
         |-mScopedXPCOM->SetWindowCreator(mNativeApp);
         |
         |-startupNotifier->Observe(nullptr, APPSTARTUP_TOPIC, nullptr);//开启APP启动监听者进行监听,
         |
         |-mDirProvider.DoStartup();
         |
         |-cmdLine->Init(...)//初始化命令行
         |
         |-obsService->NotifyObservers(cmdLine, "command-line-startup", nullptr);//通知器通知命令行启动
         |
         |-appStartup->CreateHiddenWindow();//创建隐藏窗口
         |
         |-obsService->NotifyObservers(nullptr, "final-ui-startup", nullptr);//通知器通知启动最终ui(窗口)
         |
         |-cmdLine->Run();     (toolkit/components/commandlines/nsCommandLine.cpp)//加载进第一个页面iframe进去???
         |          |
         |          |- nsCommandLine::EnumerateValidators
         |          |
         |          |-nsCommandLine::EnumerateHandlers
         |                  |
         |                  |-EnumRun
         |                        |
         |                        |-nsICommandLineHandler->Handle   (first page will be loaded in here)        //启动第一个页面/窗口(window)
         |                                  
         |-mNativeApp->Enable();
         |
         |-appStartup->Run();     (toolkit/components/startup/nsAppStartup.cpp)//启动各种app,先systme app,homescreen 等?
                   |
                   |-mAppShell->Run();         (widget/gonk/nsAppShell.cpp->widget/nsBaseAppShell.cpp)
                            |
                            |-MessageLoop::current()->Run();  // run forever~~~~~

较完整版XRE_mainRun

/XPCOMInit.cpp:858, Fuc:NS_InitXPCOM2  call -- sMainHangMonitor = new mozilla::BackgroundHangMonitor( loop->thread_name().c_str(), loop->transient_hang_timeout(), loop->permanent_hang_timeout()); --->
, Fuc:Initialize  startup xpcom seccessed?? call do_QueryInterface(mServiceManager)-->

完成了xpcom等的启动:

Fuc:XRE_main  call XRE_mainRun--->//XRE_mainRun入口
Fuc:XRE_mainRun  ----------------------------------
Fuc:XRE_mainRun  call mozilla::ipc::ProcLoaderClientGeckoInit()--->//调ProcLoaderClientGeckoInit,作用是,new ProcLoaderParent端

rocessUtils_linux.cpp:231, Fuc:ProcLoaderClientGeckoInit  ----------------------------------//创建parent actor, |ProcLoaderParent
rocessUtils_linux.cpp:251, Fuc:ProcLoaderClientGeckoInit    sProcLoaderParent = new ProcLoaderParent()
rocessUtils_linux.cpp:251, Fuc:ProcLoaderClientGeckoInit sProcLoaderParent->Open(transport,sProcLoaderPid,XRE_GetIOMessageLoop(),ParentSide)//打开传输,并开始调XRE_GetIOMessageLoop循环,获取io的消息循环
73, Fuc:XRE_GetIOMessageLoop  ----------------------------------
75, Fuc:XRE_GetIOMessageLoop      return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)

rocessUtils_linux.cpp:258, Fuc:ProcLoaderClientGeckoInit  call  sProcLoaderLoop = MessageLoop::current()--->//两个循环不一样???// Returns the MessageLoop object for the current thread, or null if none.返回当前线程的消息

Fuc:XRE_mainRun  call SetWindowCreator--->//调用窗口创建器
mponents/startup/nsAppStartup.cpp:172, Fuc:nsAppStartup  ----------------------------------//进入app启动器
mponents/startup/nsAppStartup.cpp:179, Fuc:Init  ----------------------------------//初始化APP启动器,创建io观察监听器等
mponents/startup/nsAppStartup.cpp:185, Fuc:Init   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObse
mponents/startup/nsAppStartup.cpp:190, Fuc:Init    os->AddObserver(this, 'quit-application.........', true)//添加监听器
Fuc:XRE_mainRun    nsCOMPtr<nsIPrefService> prefs = do_GetService('@mozilla.org/preferences-service;1', &rv)//获取preferences 服务,偏好或优先权配置
Fuc:XRE_mainRun  set of CrashReporter after xpcom Initialization,here? again?

打了太多垃圾log!!!!
Fuc:XRE_mainRun  startupNotifier ,do_CreateInstance --//启动通知器

上段一样的,合并保留,懒得整理一起了

, Fuc:XRE_main  call XRE_mainRun--->
, Fuc:XRE_mainRun  ----------------------------------
, Fuc:XRE_mainRun  call mozilla::ipc::ProcLoaderClientGeckoInit()--->  ProcLoaderClientGeckoInit目的在于最后与nuwa 建立连接?
/ProcessUtils_linux.cpp:231, Fuc:ProcLoaderClientGeckoInit  ----------------------------------
/ProcessUtils_linux.cpp:250, Fuc:ProcLoaderClientGeckoInit  call -- Transport *transport = OpenDescriptor(fd, Transport::MODE_CLIENT); --->//open the fd of nuwa(child process)?设置打开nuwa的fd方式?

/ProcessUtils_linux.cpp:252, Fuc:ProcLoaderClientGeckoInit    sProcLoaderParent = new ProcLoaderParent()
/ProcessUtils_linux.cpp:254, Fuc:ProcLoaderClientGeckoInit  sProcLoaderParent->Open(transport,sProcLoaderPid,XRE_GetIOMessageLoop(),ParentSide)  //打开建立连接,并启XRE_GetIOMessageLoop
:673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop      return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)

/ProcessUtils_linux.cpp:259, Fuc:ProcLoaderClientGeckoInit  call  sProcLoaderLoop = MessageLoop::current()--->  创建当前的消息循环
, Fuc:XRE_mainRun  call -- rv = mScopedXPCOM->SetWindowCreator(mNativeApp); --->//给app设置窗口,
components/startup/nsAppStartup.cpp:172, Fuc:nsAppStartup  ---------------------------------- 开始启动APP
components/startup/nsAppStartup.cpp:179, Fuc:Init  ----------------------------------//初始化等,如获取监听服务,添加服务等
components/startup/nsAppStartup.cpp:185, Fuc:Init   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService()        
components/startup/nsAppStartup.cpp:190, Fuc:Init    os->AddObserver(this, 'quit-application.........', true)
, Fuc:XRE_mainRun    nsCOMPtr<nsIPrefService> prefs = do_GetService('@mozilla.org/preferences-service;1', &rv) 获取偏好设置服务
, Fuc:XRE_mainRun  set of CrashReporter after xpcom Initialization,here? again?
, Fuc:XRE_mainRun  call -- if (mStartOffline) { --->
, Fuc:XRE_mainRun  call -- nsCOMPtr<nsIObserver> startupNotifier (do_CreateInstance(NS_APPSTARTUPNOTIFIER_CONTRACTID, &rv)); ---> 启动通知器
, Fuc:XRE_mainRun  call -- startupNotifier->Observe(nullptr, APPSTARTUP_TOPIC, nullptr); --->使通知器启动一个对应用启动的监听
:673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop      return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)

, Fuc:XRE_mainRun  call -- nsCOMPtr<nsIAppStartup> appStartup (do_GetService(NS_APPSTARTUP_CONTRACTID)); ---> 获取app启动服务,,重要
, Fuc:XRE_mainRun  call -- mDirProvider.DoStartup(); ---> 启动路径提供器

谁调了它,,,
/XPCOMInit.cpp:272, Fuc:nsThreadManagerGetSingleton  call -- return nsThreadManager::get()->QueryInterface(aIID, aInstancePtr); ---> 通过线程管理器获取单列模式的app线程?
:673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop      return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
:673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop      return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
:673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop      return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
:673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop      return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
:673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop      return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
:673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop      return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)

, Fuc:XRE_mainRun  call -- appStartup->GetShuttingDown(&mShuttingDown); ---> app诡异的关闭?关闭什么?
components/startup/nsAppStartup.cpp:574, Fuc:GetShuttingDown  ----------------------------------
, Fuc:XRE_mainRun  call -- if (!mShuttingDown) { --->关闭之后
, Fuc:XRE_mainRun  call -- cmdLine = do_CreateInstance('@mozilla.org/toolkit/command-line;1'); --->  调用命令行,并初始化命令行
, Fuc:XRE_mainRun  call -- rv = cmdLine->Init(gArgc, gArgv, workingDir, nsICommandLine::STATE_INITIAL_LAUNCH); --->调用 初始化启动APP的各参数
ines/nsCommandLine.cpp:451, Fuc:Init  ----------------------------------
, Fuc:XRE_mainRun  call -- nsCOMPtr<nsIObserverService> obsService = mozilla::services::GetObserverService(); ---> 再此获取监听服务
, Fuc:XRE_mainRun  call -- obsService->NotifyObservers(cmdLine, 'command-line-startup', nullptr); ---> 通知服务通知观察者启动命令行
, Fuc:XRE_mainRun    SaveStateForAppInitiatedRestart()---> 保存APP的状态,用于重启
, Fuc:XRE_mainRun  call -- // clear out any environment variables which may have been set // during the relaunch process now that we know we won't be relaunching.  --->清除各种环境变量
, Fuc:XRE_mainRun  call -- if (!mShuttingDown) { --->
, Fuc:XRE_mainRun  call -- rv = appStartup->CreateHiddenWindow(); ---> 创建APP的隐藏窗口
components/startup/nsAppStartup.cpp:264, Fuc:CreateHiddenWindow  ----------------------------------
, Fuc:XRE_mainRun  call -- nsCOMPtr<nsIObserverService> obsService = mozilla::services::GetObserverService(); --->获取监听观察服务
, Fuc:XRE_mainRun  call -- if (obsService) obsService->NotifyObservers(nullptr, 'final-ui-startup', nullptr); --->观察者通知监听器启动最终的ui
, Fuc:XRE_mainRun  appStartup->DoneStartingUp()--> 完成APP的启动
components/startup/nsAppStartup.cpp:590, Fuc:DoneStartingUp  ----------------------------------
, Fuc:XRE_mainRun   call   appStartup->GetShuttingDown(&mShuttingDown) 又关闭APP
components/startup/nsAppStartup.cpp:574, Fuc:GetShuttingDown  ----------------------------------
, Fuc:XRE_mainRun  call -- if (!mShuttingDown) { --->
, Fuc:XRE_mainRun   mShuttingDown = false,   rv = cmdLine->Run() 调用命令行运行
ines/nsCommandLine.cpp:641, Fuc:Run  ----------------------------------
ines/nsCommandLine.cpp:643, Fuc:Run    rv = EnumerateValidators(EnumValidate, nullptr)-->列举可以的APP???
ines/nsCommandLine.cpp:582, Fuc:EnumerateValidators  ----------------------------------
ines/nsCommandLine.cpp:647, Fuc:Run    rv = EnumerateHandlers(EnumRun, nullptr)-->
ines/nsCommandLine.cpp:530, Fuc:EnumerateHandlers  ----------------------------------
ines/nsCommandLine.cpp:533, Fuc:EnumerateHandlers  call -- nsCOMPtr<nsICategoryManager> catman (do_GetService(NS_CATEGORYMANAGER_CONTRACTID)); --->
ines/nsCommandLine.cpp:539, Fuc:EnumerateHandlers  call -- rv = catman->EnumerateCategory('command-line-handler', getter_AddRefs(entenum)); ---> 处理命令行获取的APP???
ines/nsCommandLine.cpp:549, Fuc:EnumerateHandlers  call -- while (NS_SUCCEEDED(strenum->HasMore(&hasMore)) && hasMore) { --->如果成功,则一直去处理更多的APP的运行???

循环多次??为什么?启动了几个APP???不可能,

ines/nsCommandLine.cpp:554, Fuc:EnumerateHandlers  call -- rv = catman->GetCategoryEntry('command-line-handler', entry.get(), getter_Copies(contractID)); --->
ines/nsCommandLine.cpp:561, Fuc:EnumerateHandlers  call -- nsCOMPtr<nsICommandLineHandler> clh(do_GetService(contractID.get())); --->
ines/nsCommandLine.cpp:633, Fuc:EnumRun  ----------------------------------
ines/nsCommandLine.cpp:634, Fuc:EnumRun  call -- return aHandler->Handle(aThis); --->

ines/nsCommandLine.cpp:554, Fuc:EnumerateHandlers  call -- rv = catman->GetCategoryEntry('command-line-handler', entry.get(), getter_Copies(contractID)); --->
ines/nsCommandLine.cpp:561, Fuc:EnumerateHandlers  call -- nsCOMPtr<nsICommandLineHandler> clh(do_GetService(contractID.get())); --->
ines/nsCommandLine.cpp:633, Fuc:EnumRun  ----------------------------------
ines/nsCommandLine.cpp:634, Fuc:EnumRun  call -- return aHandler->Handle(aThis); --->

ines/nsCommandLine.cpp:554, Fuc:EnumerateHandlers  call -- rv = catman->GetCategoryEntry('command-line-handler', entry.get(), getter_Copies(contractID)); --->
ines/nsCommandLine.cpp:561, Fuc:EnumerateHandlers  call -- nsCOMPtr<nsICommandLineHandler> clh(do_GetService(contractID.get())); --->
ines/nsCommandLine.cpp:633, Fuc:EnumRun  ----------------------------------
ines/nsCommandLine.cpp:634, Fuc:EnumRun  call -- return aHandler->Handle(aThis); --->

ines/nsCommandLine.cpp:554, Fuc:EnumerateHandlers  call -- rv = catman->GetCategoryEntry('command-line-handler', entry.get(), getter_Copies(contractID)); --->
ines/nsCommandLine.cpp:561, Fuc:EnumerateHandlers  call -- nsCOMPtr<nsICommandLineHandler> clh(do_GetService(contractID.get())); --->
ines/nsCommandLine.cpp:633, Fuc:EnumRun  ----------------------------------
ines/nsCommandLine.cpp:634, Fuc:EnumRun  call -- return aHandler->Handle(aThis); --->

循环四次以后,又开始关闭应用???疯了吗?
components/startup/nsAppStartup.cpp:727, Fuc:Observe  ----------------------------------
, Fuc:XRE_mainRun  call -- appStartup->GetShuttingDown(&mShuttingDown); --->
components/startup/nsAppStartup.cpp:574, Fuc:GetShuttingDown  ----------------------------------

为了等待下面这个条件满足?
, Fuc:XRE_mainRun  call -- if (PR_GetEnv('MOZ_INSTRUMENT_EVENT_LOOP')) { --->
, Fuc:XRE_mainRun  call -- rv = appStartup->Run(); --->

components/startup/nsAppStartup.cpp:295, Fuc:Run  ----------------------------------
components/startup/nsAppStartup.cpp:309, Fuc:Run   call  nsresult rv = mAppShell->Run()--->APP开始运行?之后去哪了?
cessHost.cpp:448, Fuc:LaunchAndWaitForProcessHandle  call -- PrepareLaunch(); --->准备启动nuwa
cessHost.cpp:451, Fuc:LaunchAndWaitForProcessHandle  call -- MessageLoop* ioLoop = XRE_GetIOMessageLoop(); --->调用messageloop信息队列循环,
:673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop      return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)

cessHost.cpp:470, Fuc:InitializeChannel  call -- CreateChannel(); ---> 创建通道连接service端
/ProcessUtils_linux.cpp:322, Fuc:ProcLoaderLoad  ----------------------------------调ProcLoaderLoad开始加载nuwa进程???
/ProcessUtils_linux.cpp:323, Fuc:ProcLoaderLoad  call -- * Request the loader service, the server, to load Nuwa.  --->
/ProcessUtils_linux.cpp:352, Fuc:ProcLoaderLoad    sProcLoaderLoop->PostTask(FROM_HERE, NewRunnableFunction(AsyncSendLoad, load))-->   将任务post到messageloop里,之后service 端开始接收到加载的请求,
:673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop      return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)

下面是nuwa进程紧接着打印的Log,将要开始load nuwa

开始load nuwa:

/ProcessUtils_linux.cpp:521, Fuc:RecvLoad  ----------------------------------
/ProcessUtils_linux.cpp:529, Fuc:RecvLoad  call -- sProcLoaderDispatchedTask = new ProcLoaderLoadRunner(aArgv, aEnv, aFdsRemap, privs); --->

/ProcessUtils_linux.cpp:532, Fuc:RecvLoad  call -- SendLoadComplete(mPeerPid, aCookie); --->
/ProcessUtils_linux.cpp:535, Fuc:RecvLoad  call -- MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction(_ProcLoaderChildDestroy, this)); --->
/ProcessUtils_linux.cpp:639, Fuc:ProcLoaderServiceRun  call BackgroundHangMonitor::Allow()--->
/ProcessUtils_linux.cpp:641, Fuc:ProcLoaderServiceRun  call XRE_DeinitCommandLine--->
/ProcessUtils_linux.cpp:648, Fuc:ProcLoaderServiceRun  call task->DoWork()--->
/ProcessUtils_linux.cpp:451, Fuc:DoWork  ----------------------------------
/ProcessUtils_linux.cpp:467, Fuc:DoWork    call SetCurrentProcessPrivileges(mPrivs)--->
/ProcessUtils_linux.cpp:471, Fuc:DoWork   Start Nuwa (main function),call int ret = content_process_main(argc, argv)--->

nuwa部分分析:

完整的nuwa process 端Log分析:

fork后b2g部分

Fuc:RunProcesses  ### pid >0 is parentSock(Pid of childSock), or 0 is return by childSock:464
 Fuc:RunProcesses  ### pid=464,|pid='0',it is childprocess|, isChildProcess=0
 Fuc:RunProcesses  XRE_ProcLoaderClientInit(childPid:464, parentSock:13, aReservedFds[...0]:3)
/ipc/glue/ProcessUtils_linux.cpp:674, Fuc:XRE_ProcLoaderClientInit  .==b2g process==. XRE_ProcLoaderClientInit call mozilla::ipc::ProcLoaderClientInit(aPeerPid:464, aChannelFd:13)
/ipc/glue/ProcessUtils_linux.cpp:222, Fuc:ProcLoaderClientInit  sProcLoaderPid:464,sProcLoaderChannelFd:13,sProcLoaderClientInitialized:true

fork 后nuwa部分 nuwa 进程开始运行:

Fuc:RunProcesses  ### pid >0 is parentSock(Pid of childSock), or 0 is return by childSock:0
 Fuc:RunProcesses  ### pid=0,|pid='0',it is childprocess|, isChildProcess=1
 Fuc:RunProcesses  close parentSock,in nuwa(child) process
 Fuc:RunProcesses  call XRE_ProcLoaderServiceRun--->
 Fuc:RunProcesses  XRE_ProcLoaderServiceRun(getppid():180, childSock:14, argc:1, argv:/system/b2g/b2g,aReservedFds[...0]:3)
/ipc/glue/ProcessUtils_linux.cpp:683, Fuc:XRE_ProcLoaderServiceRun  ----------------------------------
/ipc/glue/ProcessUtils_linux.cpp:684, Fuc:XRE_ProcLoaderServiceRun  .==nuwa process==. XRE_ProcLoaderServiceRun call mozilla::ipc::ProcLoaderServiceRun(aPeerPid:180, aFd:14,aArgc:1, aArgv[...0]:/system/b2g/b2g,aReservedFds[...0]:3)//nuwa调ProcLoaderServiceRun

/ipc/glue/ProcessUtils_linux.cpp:584, Fuc:ProcLoaderServiceRun  ----------------------------------
/ipc/glue/ProcessUtils_linux.cpp:595, Fuc:ProcLoaderServiceRun  aArgv[i]:/system/b2g/b2g
/ipc/glue/ProcessUtils_linux.cpp:604, Fuc:ProcLoaderServiceRun  call XRE_InitCommandLine--->
.cpp:4583, Fuc:XRE_InitCommandLine  ----------------------------------
.cpp:4595, Fuc:XRE_InitCommandLine  XRE_GetBinaryPath(aArgv:/system/b2g/b2g)--->
/ipc/glue/ProcessUtils_linux.cpp:617, Fuc:ProcLoaderServiceRun  new ContentProcess(aPeerPid:180)--->传入b2g进程的pid?为什么
/ipc/glue/ProcessUtils_linux.cpp:618, Fuc:ProcLoaderServiceRun  call -- process = new ContentProcess(aPeerPid); --->
/ipc/glue/ProcessChild.cpp:46, Fuc:ProcessChild  >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func//进入ProcessChild

。。。与b2g process 创建连接
/ipc/glue/ProcessChild.cpp:47, Fuc:ProcessChild  init with-- ProcessChild::ProcessChild(ProcessId aParentPid) : ChildProcess(new IOThreadChild()) , mUILoop(MessageLoop::current()) , mParentPid(aParentPid) --- 为子进程创建io子线程,创建uiloop消息循环线程?

/ipc/glue/ProcessUtils_linux.cpp:620, Fuc:ProcLoaderServiceRun  call -- ChildThread *iothread = process->child_thread(); --->//调用子线程?
/ipc/glue/ProcessUtils_linux.cpp:623, Fuc:ProcLoaderServiceRun  call -- Transport *transport = OpenDescriptor(fd, Transport::MODE_CLIENT); --->//打开文件描述符(与b2g打开的相同,实现传输?),MODE_CLIENT方式???传输部分?进程间??
/ipc/glue/ProcessUtils_linux.cpp:625, Fuc:ProcLoaderServiceRun  new ProcLoaderChild(aPeerPid:180)--->
/ipc/glue/ProcessUtils_linux.cpp:626, Fuc:ProcLoaderServiceRun  call -- ProcLoaderChild *loaderChild = new ProcLoaderChild(aPeerPid); --->//创建loaderChild, Pass a message loop to initialize (connect) the channel    // (connection). 下面的open发一个messageloop去建立连接通道,因为上面已经指定了进程号和文件描述符,使建立连接通道,接着nuwa这侧就在等load信号了

/ipc/glue/ProcessUtils_linux.cpp:630, Fuc:ProcLoaderServiceRun      loaderChild->Open(transport, aPeerPid, iothread->message_loop())//进行传输,与b2g进程,并启动它的其中一个子线程用于messageloop,消息队列循环,ipdl的open,线程间相互传消息

/ipc/glue/ProcessUtils_linux.cpp:632, Fuc:ProcLoaderServiceRun  call BackgroundHangMonitor::Prohibit()--->//禁止后台挂起
/ipc/glue/ProcessUtils_linux.cpp:636, Fuc:ProcLoaderServiceRun  call loop.Run--->//loop 循环,等待b2g的load 请求

//不知为何就开始recvload了,获得了,b2g 端以及发请求,详见交互部分log:

等待。等待。等待。

673, Fuc:XRE_GetIOMessageLoop  ----------------------------------//b2g 那边的循环突然来了,那边已经appStartup->Run 此为b2g的log

ProcessUtils_linux.cpp:521, Fuc:RecvLoad  ----------------------------------//谁调了它,接收到调用请求

ProcessUtils_linux.cpp:522, Fuc:RecvLoad  ############this func RecvLoad(),called by objdir-gecko/ipc/ipdl/PProcLoaderChild.cpp ################
ProcessUtils_linux.cpp:523, Fuc:RecvLoad  call -- if ((!(RecvLoad(mozilla::Move(argv), mozilla::Move(env), mozilla::Move(fdsRemap), mozilla::Move(privs), mozilla::Move(cookie))))) { --->

ProcessUtils_linux.cpp:529, Fuc:RecvLoad  call -- sProcLoaderDispatchedTask = new ProcLoaderLoadRunner(aArgv, aEnv, aFdsRemap, privs); ---> 创建进程加载调度任务,ProcLoaderLoadRunner
ProcessUtils_linux.cpp:532, Fuc:RecvLoad  call -- SendLoadComplete(mPeerPid:181, aCookie); --->发送完整的加载指令,发给b2g???
ProcessUtils_linux.cpp:535, Fuc:RecvLoad  call -- MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction(_ProcLoaderChildDestroy, this)); --->消息队列MessageLoop::current添加任务
ProcessUtils_linux.cpp:639, Fuc:ProcLoaderServiceRun  call BackgroundHangMonitor::Allow()--->允许线程挂起,后台线程监控允许
ProcessUtils_linux.cpp:641, Fuc:ProcLoaderServiceRun  call XRE_DeinitCommandLine--->反初始化CommandLine释放相关资源
ProcessUtils_linux.cpp:648, Fuc:ProcLoaderServiceRun  call task->DoWork()--->任务开始工作
ProcessUtils_linux.cpp:451, Fuc:DoWork  ----------------------------------
ProcessUtils_linux.cpp:467, Fuc:DoWork    call SetCurrentProcessPrivileges(mPrivs)---> 设置进程特性
ProcessUtils_linux.cpp:471, Fuc:DoWork   Start Nuwa (main function),call int ret = content_process_main(argc, argv)--->调content_process_main真正创建出一个进程
pp:182, Fuc:content_process_main  ----------------------------------
pp:214, Fuc:content_process_main      XRE_SetProcessType(argv[--argc])--> 设置进程类型
pp:219, Fuc:content_process_main    isNuwa=true,    PrepareNuwaProcess()-->是Nuwa进程,则准备启动nuwa进程
pp:245, Fuc:content_process_main   isNuwa=true,  NuwaAddFinalConstructor(&InitializeBinder, nullptr)添加nuwa的最后构造者,初始化binder等
pp:274, Fuc:content_process_main   ***   nsresult rv = XRE_InitChildProcess(argc, argv, loader)--> 初始化子进程(此时是否已经出来新进程了)需要看到新的进程号
329, Fuc:XRE_InitChildProcess  ----------------------------------
467, Fuc:XRE_InitChildProcess  defined MOZ_CRASHREPORTER

开始重复b2g里的那套

nuwa是b2g的复制???

556, Fuc:XRE_InitChildProcess    nsresult rv = XRE_InitCommandLine(aArgc, aArgv)-->又重复,初始化命令行
 Fuc:XRE_InitCommandLine  ----------------------------------
 Fuc:XRE_InitCommandLine  XRE_GetBinaryPath(aArgv:/system/b2g/plugin-container)--->获取二进制文件地址
 Fuc:XRE_InitCommandLine  mozilla::Omnijar::Init(greOmni, appOmni)-->将omni文件传入,Omnijar::Init初始化
565, Fuc:XRE_InitChildProcess    switch (XRE_GetProcessType())--> 获取进程类型
ProcessChild.cpp:46, Fuc:ProcessChild  >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func
ProcessChild.cpp:47, Fuc:ProcessChild  init with-- ProcessChild::ProcessChild(ProcessId aParentPid) : ChildProcess(new IOThreadChild()) , mUILoop(MessageLoop::current()) , mParentPid(aParentPid) ---  初始化子进程启动子进程的io子线程,uiloop等,只有nuwa进程需要吗???
ScopedXREEmbed.cpp:59, Fuc:SetAppDir  ----------------------------------
.cpp:108, Fuc:Init  ----------------------------------初始化
.cpp:109, Fuc:Init  call -- mContent.Init(IOThreadChild::message_loop(), ParentPid(), IOThreadChild::channel()); --->对content进行初始化,传入io子线程的消息队列循环,父进程PID,io线程的通道对content进程进行初始化
.cpp:113, Fuc:Init  call -- mXREEmbed.Start(); --->开始嵌入?
ScopedXREEmbed.cpp:73, Fuc:Start  ----------------------------------
ScopedXREEmbed.cpp:89, Fuc:Start    rv = localFile->GetParent(getter_AddRefs(parent)-->获取父类的什么?
ScopedXREEmbed.cpp:93, Fuc:Start    localFile = do_QueryInterface(parent)-->本地文件??
ScopedXREEmbed.cpp:130, Fuc:Start  mAppDir = true,call  rv = XRE_InitEmbedding2(localFile, mAppDir, nullptr)-->传入本地文件以及APP目录开始着床进程???
172, Fuc:XRE_InitEmbedding2  ----------------------------------

nuwa这一线下来是完成对自己的初始化和各功能块拉起?
192, Fuc:XRE_InitEmbedding2  call -- rv = gDirServiceProvider->Initialize(aAppDirectory, aLibXULDirectory, --->目录服务初始化
197, Fuc:XRE_InitEmbedding2    rv = NS_InitXPCOM2(nullptr, aAppDirectory, gDirServiceProvider)-->又开始初始化xpcom???
XPCOMInit.cpp:513, Fuc:NS_InitXPCOM2  ----------------------------------
XPCOMInit.cpp:514, Fuc:NS_InitXPCOM2  ###################basic part of nuwa and b2g proc start ######################
XPCOMInit.cpp:517, Fuc:NS_InitXPCOM2  call -- if (sInitialized) { --->
XPCOMInit.cpp:525, Fuc:NS_InitXPCOM2  call -- mozPoisonValueInit(); --->
XPCOMInit.cpp:563, Fuc:NS_InitXPCOM2  ###################basic part of nuwa and b2g proc end ######################
XPCOMInit.cpp:565, Fuc:NS_InitXPCOM2  call -- if (!MessageLoop::current()) {//when nuwa then will not come in for loop = true --->专门给b2g的
XPCOMInit.cpp:577, Fuc:NS_InitXPCOM2   if (XRE_IsParentProcess() && !BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)) = ??         也不是nuwa 的菜

XPCOMInit.cpp:597, Fuc:NS_InitXPCOM2  ##############nuwa jump here directly from basic for b2g and nuwa part #######################
XPCOMInit.cpp:599, Fuc:NS_InitXPCOM2 Establish the main thread here. 创建主线程(每个进程自己的主线程?)
XPCOMInit.cpp:600, Fuc:NS_InitXPCOM2  call -- rv = nsThreadManager::get()->Init(); --->线程管理器获取并初始化线程
XPCOMInit.cpp:606, Fuc:NS_InitXPCOM2  call -- // Set up the timer globals/timer thread --->设置timer 全局线程
XPCOMInit.cpp:608, Fuc:NS_InitXPCOM2  call -- rv = nsTimerImpl::Startup(); --->
XPCOMInit.cpp:625, Fuc:NS_InitXPCOM2  call -- NS_StartupLocalFile(); --->
XPCOMInit.cpp:628, Fuc:NS_InitXPCOM2  call -- StartupSpecialSystemDirectory(); --->
XPCOMInit.cpp:631, Fuc:NS_InitXPCOM2  call -- nsDirectoryService::RealInit(); --->目录服务真正启动?
XPCOMInit.cpp:637, Fuc:NS_InitXPCOM2  call -- if (aBinDirectory) { --->
XPCOMInit.cpp:640, Fuc:NS_InitXPCOM2  call -- nsDirectoryService::gService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, --->初始化当前进程的目录(proc目录下的那些??)
XPCOMInit.cpp:647, Fuc:NS_InitXPCOM2  aAppFileLocationProvider = true,call RegisterProvider()-->调用注册
XPCOMInit.cpp:655, Fuc:NS_InitXPCOM2  call -- nsDirectoryService::gService->Get(NS_GRE_BIN_DIR, --->
XPCOMInit.cpp:663, Fuc:NS_InitXPCOM2  call -- xpcomLib->GetPath(path); --->xpcomLib获取路径
XPCOMInit.cpp:667, Fuc:NS_InitXPCOM2  call -- xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL)); --->
XPCOMInit.cpp:669, Fuc:NS_InitXPCOM2  call -- nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib); --->
XPCOMInit.cpp:672, Fuc:NS_InitXPCOM2  call -- if (!mozilla::Omnijar::IsInitialized()) { --->看omnijar有没有初始化,没有初始化则会中断?
XPCOMInit.cpp:714, Fuc:NS_InitXPCOM2  Create the Component/Service Manage----创建组件服务管理器
XPCOMInit.cpp:715, Fuc:NS_InitXPCOM2  call -- nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl(); --->
XPCOMInit.cpp:720, Fuc:NS_InitXPCOM2  call -- // Global cycle collector initialization.  --->全局循环收集器初始化,负责它自己的线程?
XPCOMInit.cpp:721, Fuc:NS_InitXPCOM2  call -- if (!nsCycleCollector_init()) { --->
XPCOMInit.cpp:726, Fuc:NS_InitXPCOM2  call -- // And start it up for this thread too.  --->
XPCOMInit.cpp:728, Fuc:NS_InitXPCOM2  call -- nsCycleCollector_startup(); --->全局循环收集器启动,为此线程
XPCOMInit.cpp:737, Fuc:NS_InitXPCOM2  call -- mozilla::SetICUMemoryFunctions(); --->
XPCOMInit.cpp:766, Fuc:NS_InitXPCOM2  ----- Initialize the JS engine -----初始化js引擎,应该不做了,在b2g里已经搞定?
XPCOMInit.cpp:767, Fuc:NS_InitXPCOM2    if (!JS_Init()),call JS_Init()--->继续log看
XPCOMInit.cpp:772, Fuc:NS_InitXPCOM2  call -- rv = nsComponentManagerImpl::gComponentManager->Init(); --->组件管理器初始化并启动
ntManager.cpp:400, Fuc:Init  ----------------------------------
ntManager.cpp:444, Fuc:Init  call -- InitializeModuleLocations(); --->组件管理器加载相关app??
ntManager.cpp:452, Fuc:Init  call -- RefPtr<nsZipArchive> greOmnijar = mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE); --->
ntManager.cpp:458, Fuc:Init  call -- cl->location.Init(greOmnijar, 'chrome.manifest'); --->
ntManager.cpp:471, Fuc:Init  call -- RefPtr<nsZipArchive> appOmnijar = mozilla::Omnijar::GetReader(mozilla::Omnijar::APP); --->
ntManager.cpp:481, Fuc:Init  call -- RereadChromeManifests(false); --->读取清单文件??不读?
ntManager.cpp:878, Fuc:RereadChromeManifests  ----------------------------------
ntManager.cpp:484, Fuc:Init  call -- nsCategoryManager::GetSingleton()->SuppressNotifications(false); --->
673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
678, Fuc:XRE_GetIOMessageLoop  call -- return IOThreadChild::message_loop(); --->

XPCOMInit.cpp:789, Fuc:NS_InitXPCOM2   The iimanager constructor searches and registers XPT files.---
XPCOMInit.cpp:790, Fuc:NS_InitXPCOM2  call -- (void)XPTInterfaceInfoManager::GetSingleton(); --->
XPCOMInit.cpp:793, Fuc:NS_InitXPCOM2  call -- // After autoreg, but before we actually instantiate any components, // add any services listed in the 'xpcom-directory-providers' category // to the directory service.  --->自动注册组件??
XPCOMInit.cpp:797, Fuc:NS_InitXPCOM2    nsDirectoryService::gService->RegisterCategoryProviders()-->
ntManager.cpp:173, Fuc:operator()  ----------------------------------
XPCOMInit.cpp:800, Fuc:NS_InitXPCOM2  call -- // Init SharedThreadPool (which needs the service manager).  --->
XPCOMInit.cpp:802, Fuc:NS_InitXPCOM2  call -- SharedThreadPool::InitStatics(); --->共享线程
XPCOMInit.cpp:806, Fuc:NS_InitXPCOM2  call -- AbstractThread::InitStatics(); --->抽象线程
XPCOMInit.cpp:811, Fuc:NS_InitXPCOM2  do_GetService of jsloader----获取jsloader加载器
XPCOMInit.cpp:812, Fuc:NS_InitXPCOM2   componentLoader =    do_GetService('@mozilla.org/moz/jsloader;1')--->
XPCOMInit.cpp:820, Fuc:NS_InitXPCOM2    // Notify observers of xpcom autoregistration star//
XPCOMInit.cpp:821, Fuc:NS_InitXPCOM2  NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_CATEGORY,nullptr,NS_XPCOM_STARTUP_OBSERVER_ID) --->通知自动注册,为什么多次注册,继续Log
XPCOMInit.cpp:832, Fuc:NS_InitXPCOM2  call -- if (XRE_IsParentProcess()) { --->,true will enter
XPCOMInit.cpp:838, Fuc:NS_InitXPCOM2  call -- // The memory reporter manager is up and running -- register our reporters.  --->
XPCOMInit.cpp:840, Fuc:NS_InitXPCOM2  call -- RegisterStrongMemoryReporter(new ICUReporter()); --->
XPCOMInit.cpp:850, Fuc:NS_InitXPCOM2  call -- mozilla::Telemetry::Init(); --->
XPCOMInit.cpp:852, Fuc:NS_InitXPCOM2  call -- mozilla::HangMonitor::Startup(); --->后台线程管理相关
XPCOMInit.cpp:854, Fuc:NS_InitXPCOM2  call -- mozilla::BackgroundHangMonitor::Startup(); --->
XPCOMInit.cpp:856, Fuc:NS_InitXPCOM2  call -- const MessageLoop* const loop = MessageLoop::current(); --->
XPCOMInit.cpp:858, Fuc:NS_InitXPCOM2  call -- sMainHangMonitor = new mozilla::BackgroundHangMonitor( loop->thread_name().c_str(), loop->transient_hang_timeout(), loop->permanent_hang_timeout()); --->

213, Fuc:XRE_InitEmbedding2  call -- startupNotifier->Observe(nullptr, APPSTARTUP_TOPIC, nullptr); --->启动通知器
                                                                                                                                                                                                                             
.cpp:115, Fuc:Init  call -- mContent.InitXPCOM(); --->又来了,怎么回事?不一样吧
.cpp:117, Fuc:Init  call -- mContent.InitGraphicsDeviceData(); --->mcontent初始化xpcom和图像设备数据????
653, Fuc:XRE_InitChildProcess        uiMessageLoop.MessageLoop::Run()-->启动界面消息队列循环,开始有真正界面了是吗???
673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
678, Fuc:XRE_GetIOMessageLoop  call -- return IOThreadChild::message_loop(); --->
673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
678, Fuc:XRE_GetIOMessageLoop  call -- return IOThreadChild::message_loop(); --->
673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
678, Fuc:XRE_GetIOMessageLoop  call -- return IOThreadChild::message_loop(); --->

XPCOMInit.cpp:272, Fuc:nsThreadManagerGetSingleton  call -- return nsThreadManager::get()->QueryInterface(aIID, aInstancePtr); --->猜想:nuwa进程获取界面调用消息?返回
omponents/startup/nsAppStartup.cpp:172, Fuc:nsAppStartup  ----------------------------------谁调了它
omponents/startup/nsAppStartup.cpp:179, Fuc:Init  ----------------------------------
omponents/startup/nsAppStartup.cpp:185, Fuc:Init   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService() 获取监听服务      
omponents/startup/nsAppStartup.cpp:190, Fuc:Init    os->AddObserver(this, 'quit-application.........', true)获取到退出应用的消息
673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
678, Fuc:XRE_GetIOMessageLoop  call -- return IOThreadChild::message_loop(); --->
673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
678, Fuc:XRE_GetIOMessageLoop  call -- return IOThreadChild::message_loop(); --->
:673, Fuc:XRE_GetIOMessageLoop  ----------------------------------
:678, Fuc:XRE_GetIOMessageLoop  call -- return IOThreadChild::message_loop(); --->

b2g 叫相关模块Load nuwa 以及之后,混杂b2g 和nuwa 进程

。。。

Fuc:XRE_mainRun  call -- appStartup->GetShuttingDown(&mShuttingDown); --->
omponents/startup/nsAppStartup.cpp:574, Fuc:GetShuttingDown  ----------------------------------
 Fuc:XRE_mainRun  call -- if (PR_GetEnv('MOZ_INSTRUMENT_EVENT_LOOP')) { --->
 Fuc:XRE_mainRun  call -- rv = appStartup->Run(); --->
omponents/startup/nsAppStartup.cpp:295, Fuc:Run  ----------------------------------
omponents/startup/nsAppStartup.cpp:309, Fuc:Run   call  nsresult rv = mAppShell->Run()--->
essHost.cpp:448, Fuc:LaunchAndWaitForProcessHandle  call -- PrepareLaunch(); --->
essHost.cpp:451, Fuc:LaunchAndWaitForProcessHandle  call -- MessageLoop* ioLoop = XRE_GetIOMessageLoop(); --->不是后台的那个loop,是这里往io里写东西,然后nuwa的ioloop 接收到?XRE_GetIOMessageLoop都在b2g进程中,APP也会发吗?谁激发b2g,启动的load信号

673, Fuc:XRE_GetIOMessageLoop  ----------------------------------

Fuc:XRE_GetIOMessageLoop      return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
ost.cpp:470, Fuc:InitializeChannel  call -- CreateChannel(); --->
essUtils_linux.cpp:322, Fuc:ProcLoaderLoad  ----------------------------------//一直循环,等待postTask任务
essUtils_linux.cpp:323, Fuc:ProcLoaderLoad  call -- * Request the loader service, the server, to load Nuwa.  --->

essUtils_linux.cpp:352, Fuc:ProcLoaderLoad    sProcLoaderLoop->PostTask(FROM_HERE, NewRunnableFunction(AsyncSendLoad, load))-->   
 Fuc:XRE_GetIOMessageLoop  ----------------------------------
 Fuc:XRE_GetIOMessageLoop      return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)

以上为b2g 部分,此时才开始叫相关模块拉起nuwa来,此时b2g实际已经完成了哪些工作呢?

已经完成xpcom的启动,开始调用XRE_mainRun(),并已经到appStartup->Run部分,要真正启动"app"了,nuwa就是第一个应用??然后用它孵化出其他app(具体的)???

在appStartup->Run部分load nuwa

以下是nuwa部分log

接收到加载的信号,,开始进行相关加载任务:

essUtils_linux.cpp:521, Fuc:RecvLoad  ----------------------------------
essUtils_linux.cpp:529, Fuc:RecvLoad  call -- sProcLoaderDispatchedTask = new ProcLoaderLoadRunner(aArgv, aEnv, aFdsRemap, privs); --->
ess
Utils_linux.cpp:532, Fuc:RecvLoad  call -- SendLoadComplete(mPeerPid, aCookie); --->
essUtils_linux.cpp:535, Fuc:RecvLoad  call -- MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction(_ProcLoaderChildDestroy, this)); --->
essUtils_linux.cpp:639, Fuc:ProcLoaderServiceRun  call BackgroundHangMonitor::Allow()--->
essUtils_linux.cpp:641, Fuc:ProcLoaderServiceRun  call XRE_DeinitCommandLine--->
essUtils_linux.cpp:648, Fuc:ProcLoaderServiceRun  call task->DoWork()--->
essUtils_linux.cpp:451, Fuc:DoWork  ----------------------------------
essUtils_linux.cpp:467, Fuc:DoWork    call SetCurrentProcessPrivileges(mPrivs)--->
essUtils_linux.cpp:471, Fuc:DoWork   Start Nuwa (main function),call int ret = content_process_main(argc, argv)--->
82, Fuc:content_process_main  ----------------------------------
14, Fuc:content_process_main      XRE_SetProcessType(argv[--argc])-->
19, Fuc:content_process_main    isNuwa=true,    PrepareNuwaProcess()-->
45, Fuc:content_process_main   isNuwa=true,  NuwaAddFinalConstructor(&InitializeBinder, nullptr)
74, Fuc:content_process_main   ***   nsresult rv = XRE_InitChildProcess(argc, argv, loader)-->
 Fuc:XRE_InitChildProcess  ----------------------------------
 Fuc:XRE_InitChildProcess  defined MOZ_CRASHREPORTER
 Fuc:XRE_InitChildProcess    nsresult rv = XRE_InitCommandLine(aArgc, aArgv)-->
:XRE_InitCommandLine  ----------------------------------

...

两进程交互部分:

RunProcesses  -> XRE_ProcLoaderClientInit--->//初始化client端,传入nuwa进程的pid,fd,parent sock等

在前面初始化client的时候,ProcLoaderClientInit  sProcLoaderPid:530,sProcLoaderChannelFd:13,sProcLoaderClientInitialized:true

这里搞定之后就开始进入b2g_main了,

与上层应用联系的地方?gecko/widget/gonk/nsAppShell.cpp

进程间:

#include "mozilla/ipc/PProcLoaderParent.h"
#include "mozilla/ipc/PProcLoaderChild.h"

gecko/ipc/glue/ProcessUtils_linux.cpp

/*** 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)
{P_LOGI(SEPARATOR_LINE );MOZ_ASSERT(!sProcLoaderClientInitialized, "call ProcLoaderClientInit() more than once");MOZ_ASSERT(aPeerPid != 0 && aChannelFd != -1, "invalid argument");sProcLoaderPid = aPeerPid;sProcLoaderChannelFd = aChannelFd;sProcLoaderClientInitialized = true;P_LOGI("sProcLoaderPid:%d,sProcLoaderChannelFd:%d,sProcLoaderClientInitialized:true",sProcLoaderPid,sProcLoaderChannelFd);
}/*** Initialize the client of B2G loader for Gecko.*/
void
ProcLoaderClientGeckoInit()
{P_LOGI(SEPARATOR_LINE );MOZ_ASSERT(sProcLoaderClientInitialized, "call ProcLoaderClientInit() at first");MOZ_ASSERT(!sProcLoaderClientGeckoInitialized,"call ProcLoaderClientGeckoInit() more than once");if (!Preferences::GetBool("dom.ipc.processPrelaunch.enabled", false)) {P_LOGI(" call  kill(sProcLoaderPid, SIGKILL)");kill(sProcLoaderPid, SIGKILL);sProcLoaderPid = 0;close(sProcLoaderChannelFd);sProcLoaderChannelFd = -1;return;}sProcLoaderClientGeckoInitialized = true;TransportDescriptor fd;fd.mFd = base::FileDescriptor(sProcLoaderChannelFd, /*auto_close=*/ false);sProcLoaderChannelFd = -1;Transport *transport = OpenDescriptor(fd, Transport::MODE_CLIENT);P_LOGI("  sProcLoaderParent = new ProcLoaderParent()");sProcLoaderParent = new ProcLoaderParent();P_LOGI("sProcLoaderParent->Open(transport,sProcLoaderPid,XRE_GetIOMessageLoop(),ParentSide)   ");sProcLoaderParent->Open(transport,sProcLoaderPid,XRE_GetIOMessageLoop(),ParentSide);P_LOGI("call  sProcLoaderLoop = MessageLoop::current()--->");sProcLoaderLoop = MessageLoop::current();
}/*** 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)
{P_LOGI(SEPARATOR_LINE );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(FROM_HERE,NewRunnableFunction(AsyncSendLoad, load));return true;
}/*** 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)
{P_LOGI(SEPARATOR_LINE );// 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]);P_LOGI("aArgv[i]:%s",_argv[i]);MOZ_ASSERT(_argv[i] != nullptr);}_argv[aArgc] = nullptr;gArgv = _argv;gArgc = aArgc;{P_LOGI("call XRE_InitCommandLine--->");nsresult rv = XRE_InitCommandLine(aArgc, _argv);if (NS_FAILED(rv)) {MOZ_CRASH();}TransportDescriptor fd;fd.mFd = base::FileDescriptor(aFd, /*auto_close =*/false);MOZ_ASSERT(!sProcLoaderServing);MessageLoop loop;nsAutoPtr<ContentProcess> process;P_LOGI("new ContentProcess(aPeerPid:%d)--->",aPeerPid);process = new ContentProcess(aPeerPid);ChildThread *iothread = process->child_thread();Transport *transport = OpenDescriptor(fd, Transport::MODE_CLIENT);P_LOGI("new ProcLoaderChild(aPeerPid:%d)--->",aPeerPid);ProcLoaderChild *loaderChild = new ProcLoaderChild(aPeerPid);// Pass a message loop to initialize (connect) the channel// (connection).P_LOGI("    loaderChild->Open(transport, aPeerPid, iothread->message_loop())");loaderChild->Open(transport, aPeerPid, iothread->message_loop());P_LOGI("call BackgroundHangMonitor::Prohibit()--->");BackgroundHangMonitor::Prohibit();sProcLoaderServing = true;P_LOGI("call loop.Run--->");loop.Run();P_LOGI("call BackgroundHangMonitor::Allow()--->");BackgroundHangMonitor::Allow();P_LOGI("call XRE_DeinitCommandLine--->");XRE_DeinitCommandLine();}MOZ_ASSERT(sProcLoaderDispatchedTask != nullptr);ProcLoaderRunnerBase *task = sProcLoaderDispatchedTask;sProcLoaderDispatchedTask = nullptr;P_LOGI("call task->DoWork()--->");int ret = task->DoWork();delete task;for (int i = 0; i < aArgc; i++) {free(_argv[i]);}delete[] _argv;return ret;
}#ifdef MOZ_B2G_LOADERvoid
XRE_ProcLoaderClientInit(pid_t aPeerPid, int aChannelFd, FdArray& aReservedFds)
{P_LOGI(SEPARATOR_LINE );// We already performed fork(). It's safe to free the "danger zone" of file// descriptors .mozilla::ipc::CloseFileDescriptors(aReservedFds);P_LOGI(".==b2g process==. XRE_ProcLoaderClientInit call mozilla::ipc::ProcLoaderClientInit(aPeerPid:%d, aChannelFd:%d)",aPeerPid, aChannelFd);mozilla::ipc::ProcLoaderClientInit(aPeerPid, aChannelFd);
}int
XRE_ProcLoaderServiceRun(pid_t aPeerPid, int aFd,int aArgc, const char *aArgv[],FdArray& aReservedFds)
{P_LOGI(SEPARATOR_LINE );P_LOGI(".==nuwa process==. XRE_ProcLoaderServiceRun call mozilla::ipc::ProcLoaderServiceRun(aPeerPid:%d, aFd:%d,aArgc:%d, aArgv[...0]:%s,aReservedFds[...0]:%d)",aPeerPid, aFd,aArgc, aArgv[0],aReservedFds[0]);return mozilla::ipc::ProcLoaderServiceRun(aPeerPid, aFd,aArgc, aArgv,aReservedFds);
}
#endif /* MOZ_B2G_LOADER */
/*** 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)
{P_LOGI(SEPARATOR_LINE );// 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]);P_LOGI("aArgv[i]:%s",_argv[i]);MOZ_ASSERT(_argv[i] != nullptr);}_argv[aArgc] = nullptr;gArgv = _argv;gArgc = aArgc;{P_LOGI("call XRE_InitCommandLine--->");nsresult rv = XRE_InitCommandLine(aArgc, _argv);if (NS_FAILED(rv)) {MOZ_CRASH();}TransportDescriptor fd;fd.mFd = base::FileDescriptor(aFd, /*auto_close =*/false);MOZ_ASSERT(!sProcLoaderServing);MessageLoop loop;nsAutoPtr<ContentProcess> process;P_LOGI("new ContentProcess(aPeerPid:%d)--->",aPeerPid);process = new ContentProcess(aPeerPid);ChildThread *iothread = process->child_thread();Transport *transport = OpenDescriptor(fd, Transport::MODE_CLIENT);P_LOGI("new ProcLoaderChild(aPeerPid:%d)--->",aPeerPid);ProcLoaderChild *loaderChild = new ProcLoaderChild(aPeerPid);// Pass a message loop to initialize (connect) the channel// (connection).P_LOGI("    loaderChild->Open(transport, aPeerPid, iothread->message_loop())");loaderChild->Open(transport, aPeerPid, iothread->message_loop());P_LOGI("call BackgroundHangMonitor::Prohibit()--->");BackgroundHangMonitor::Prohibit();sProcLoaderServing = true;P_LOGI("call loop.Run--->");loop.Run();P_LOGI("call BackgroundHangMonitor::Allow()--->");BackgroundHangMonitor::Allow();P_LOGI("call XRE_DeinitCommandLine--->");XRE_DeinitCommandLine();}MOZ_ASSERT(sProcLoaderDispatchedTask != nullptr);ProcLoaderRunnerBase *task = sProcLoaderDispatchedTask;sProcLoaderDispatchedTask = nullptr;P_LOGI("call task->DoWork()--->");int ret = task->DoWork();delete task;for (int i = 0; i < aArgc; i++) {free(_argv[i]);}delete[] _argv;return ret;
}

processchild:

gecko/ipc/glue/ProcessChild.cppProcessChild::ProcessChild(ProcessId aParentPid): ChildProcess(new IOThreadChild()), mUILoop(MessageLoop::current()), mParentPid(aParentPid)
{P_LOGI(STA_LINE);//P_LOGI("ProcessId:%d aParentPid:%d",ProcessId, aParentPid);MOZ_ASSERT(mUILoop, "UILoop should be created by now");MOZ_ASSERT(!gProcessChild, "should only be one ProcessChild");gProcessChild = this;
}

b2g process 和nuwa process 通信相关推荐

  1. 问题:org.gradle.process.internal.ExecException: Process 'command 'C:\Program Files\Java\jdk1.8.0

    在用as开发项目的过程中,我碰到了这个错误,在网上找到了如下的解决方法,做下总结: 被编译的代码或资源有问题( finished with non-zero exit value 1): 出现这种编译 ...

  2. java process 重启_JAVA Process启动sh 后的问题

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 import android.annotation.SuppressLint; import android.os.*; import java.io.* ...

  3. STOP: c000021a { Fatal System Error } the initial session process or system process terminated ...

    错误: STOP: c000021a { Fatal System Error } the initial session process or system process terminated u ...

  4. python process pool_python multiprocessing.Process,multiprocessing.Pool区别(不同之处)

    我们知道GIL Lock禁用了Python中的多线程功能.在Python中multiprocessing提供了两个用于多进程的类,即Process和Pool类.在以下各节中,我已对使用pool和pro ...

  5. checkpoint process vs writer process vs wal writer process

    开始 我目前的理解是: 如果我执行了一条SQL文,那么 先是相关数据写到  wal buffer里, 然后再写到 data  buffer(shared_buffer)里. 这之后, 由于wal wr ...

  6. python process 函数_Python Process创建进程的2种方法详解

    前面介绍了使用 os.fork() 函数实现多进程编程,该方法最明显的缺陷就是不适用于 Windows 系统.本节将介绍一种支持 Python 在 Windows 平台上创建新进程的方法. Pytho ...

  7. Dirichlet Process 和 Dirichlet Process Mixture模型

    [本文链接:http://www.cnblogs.com/breezedeus/archive/2012/11/05/2754940.html,转载请注明出处.] Dirichlet Process ...

  8. vue中 process.env与process.VUE_CLI_SERVICE

    在vue中设置环境变量离不开process.env属性,那么如何设置自定义环境变更呢? 可以通过设置.env文件或者借助process.VUE_CLI_SERVICE来设置 process proce ...

  9. A process in the process pool was terminated abruptly while the future was running or pending

    解决方法: 把代码加到main中执行,有时能加速6倍左右 改之前: p = ProcessPoolExecutor(max_workers=3) results = p.map(task, URLS, ...

最新文章

  1. LLVM官方文档翻译---- LLVM原子指令与并发指引
  2. 怎么做到的?美术生居然转型做程序员?
  3. modprobe和insmod区别
  4. codevs1251 括号
  5. 2021年下半年软考报考流程!
  6. go和java线程,Go的多线程和pthread或Java线程有什么区别?
  7. Word Embedding News|词嵌入新鲜事:六月刊:GPT-3来了
  8. 14条Yahoo(雅虎)十四条优化原则【转】
  9. IBASE archive write processing report RIBARCHA
  10. hash表冲突处理方法
  11. Bailian3237 鸡兔同笼【入门】
  12. 决策单调性Ⅰ:四边形不等式(bzoj 1563: [NOI2009]诗人小G)
  13. firefox与IE浏览器在web开发上面的一些区别
  14. labview打包文档_labview怎么生成exe文件
  15. Zedgraph 总结
  16. 怎么把两个pdf合并成一个pdf?
  17. 【css】boder-sizing 中content-box与boder-box的区别
  18. IntelliJ IDEA Dependency 'XXXX' not found 或 java:程序包XXXX不存在,找不到的解决方案
  19. Python判断坐标点在五环线以内
  20. 论文阅读 [TPAMI-2022] Locally Connected Network for Monocular 3D Human Pose Estimation

热门文章

  1. 用python计算符号函数一元定积分和不定积分
  2. JAVA学习日记DAY09--javaweb的一些简单应用
  3. 2021年危险化学品生产单位安全生产管理人员报名考试及危险化学品生产单位安全生产管理人员模拟考试
  4. 小白要努力之为了蓝桥杯刷题!!!超简单哦!!!
  5. 暴力递归到动态规划 05 (贴纸拼词)
  6. bpduguard使用在接着虚拟机的服务器上,避免网络环路:STP和VMware vSwitch
  7. 通过改变电脑的某些设置来呵护我们的眼睛
  8. .NET导出Excel(复杂表头)
  9. 【C语言--文件】(详细解读)
  10. codeforces 1139c Edgy Trees 【并查集 】