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

来源:互联网 发布:截面数据 编辑:程序博客网 时间:2024/06/06 02:30

上篇文章分析了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()

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

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

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

这里写图片描述

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

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

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

下次再讲讲这个问题~

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

0 0
原创粉丝点击