转:Firefox OS启动过程分析-nuwa进程启动

https://blog.csdn.net/zembers/article/details/48519661

上篇文章分析了b2g进程的基本启动过程,那么nuwa进程是什么东东?Firefox os创建新进程又是如何发生的?

nuwa进程类似于android内的zygote进程,需要启动一个应用时,nuwa会预先fork一个进程出来,该进程与父进程(nuwa)共享了某些资源(代码段,已打开文件描述符等),之后会加载应用的html,变成需要启动的应用。
使用nuwa预先创建的空壳进程,能够加快应用启动速度。

以下分析nuwa进程的创建以及初始化:
main()                   (b2g/app/B2GLoader.cpp)
    |
    |-RunProcesses
              |
              |-fork
              |
              |-XRE_ProcLoaderServiceRun            (nuwa process)    (ipc/glue/ProcessUtils_linux.cpp)                 
              |                   |
              |                   |-mozilla::ipc::ProcLoaderServiceRun
              |                                  |
              |                                  |-XRE_InitCommandLine        
              |                                  |
              |                                  |-process = new ContentProcess(aPeerPid);
              |                                  |
              |                                  |-ProcLoaderChild *loaderChild = new ProcLoaderChild(aPeerPid);
              |                                  |
              |                                  |-loaderChild->Open(transport, aPeerPid, iothread->message_loop());
              |                                  |
              |                                  |-loop.Run();       // wait until received "load" command
              |                                  |
              |                                  |-XRE_DeinitCommandLine
              |                                  |
              |                                  |-sProcLoaderDispatchedTask->DoWork();
              |                                                   |
              |                                                   |-content_process_main(argc, argv);    // start nuwa. (ipc/contentproc/plugin-container.cpp)
              |                                                                 |
              |                                                                 |-isNuwa |= strcmp(argv[i], "-nuwa") == 0;
              |                                                                 |
              |                                                                 |-XRE_SetProcessType
              |                                                                 |
              |                                                                 |-PrepareNuwaProcess
              |                                                                 |
              |                                                                 |-NuwaAddFinalConstructor(&InitializeBinder, nullptr);
              |                                                                 |
              |                                                                 |-XRE_InitChildProcess  (toolkit/xre/nsEmbedFunctions.cpp)
              |                                                                              |
              |                                                                              |-XRE_InitCommandLine
              |                                                                              |
              |                                                                              |-uiLoopType = MessageLoop::TYPE_MOZILLA_CHILD;
              |                                                                              |
              |                                                                              |-MessageLoop uiMessageLoop(uiLoopType);
              |                                                                              |
              |                                                                              |-process = new ContentProcess(parentPID);
              |                                                                              |
              |                                                                              |-process->Init();
              |                                                                              |
              |                                                                              |-uiMessageLoop.MessageLoop::Run(); // run forever
              |                                                                              |
              |                                                                              |-XRE_DeinitCommandLine
              |
              |
              |-XRE_ProcLoaderClientInit  (b2g process)
              |
              |-b2g_main
                       |
                       |-XRE_main
                               |
                               |-XREMain::XRE_main
                                        |
                                        |-XREMain::XRE_mainRun()
                                                   |
                                                   |-mozilla::ipc::ProcLoaderClientGeckoInit();

那么,nuwa进程是如何创建一个新的进程的?

b2进程启动时,会在初始化各种共享库后fork一个子进程(nuwa进程),nuwa进程在开始运行后会创建一个ProcLoaderChild对象,并进入message loop进行等待。nuwa进程与b2g进程会进行ipc通讯,当接收到b2g进程发送来的”load”(RecvLoad)命令时,

  virtual bool RecvLoad(InfallibleTArray<nsCString>&& aArgv,
                        InfallibleTArray<nsCString>&& aEnv,
                        InfallibleTArray<FDRemap>&& aFdsremap,
                        const uint32_t& aPrivs,
                        const int32_t& aCookie);

nuwa进程会跳出等待状态,并调用

content_process_main(argc, argv);

对nuwa进程进行初始化工作,最后又进入message loop循环处理各种任务。当接收到b2g进程发送的”fork”(“RecvFork”)命令,

NuwaChild::RecvFork()
  • 1

nuwa进程就会创建新的空壳进程。

nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction(&NuwaFork);
MOZ_ASSERT(runnable);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(runnable)));
NuwaFork()
  • 1

通过下面的图来了解b2g进程、nuwa进程间创建空壳进程的过程:

这里写图片描述

从以上图可以看出,初始化nuwa使用的是”SendLoad/RecvLoad”命令,而创建空壳进程使用的是”SendFork/RecvFork”。

当创建nuwa完成后(即收到nuwa进程ready信息),b2g进程会主动要求nuwa进程去创建一个空壳进程,日后需要启动应用时,可以直接使用该空壳进程,以加快应用启动速度。

那么,如果系统需要启动一个新的程序,但是已经没有了空壳进程(即mSpareProcesses为空),那b2g进程如何要求nuwa进程去创建一个新的空壳进程呢?

下次再讲讲这个问题~

P.S.
关于nuwa的设计思想,可以看看mozilla的bugzilla:
bugzilla
以及wiki:
wiki

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值