b2g process 和nuwa process 通信
它们通信的目的在于:
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,进程预加载 |
以上数据函数库等完全准备好了。
完毕之后就开始:
main --> return RunProcesses(argc, argv, reservedFds)
开始fork后分出两个进程进行工作。
main() (b2g/app/B2GLoader.cpp) |
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 p:330, Fuc:RunProcesses call return b2g_main(argc:1,argv:/system/b2g/b2g)---> |
main() ->RunProcesses fork 出2进程后:
main() ->RunProcesses->b2g_main -> XPCOMGlueLoadXULFunctions 不厌其烦地废话!!!
XPCOMGlueLoadXULFunctions 就加载些函数,并不是重点,过。
call XPCOMGlueLoadXULFunctions 2cond --->//第一次是在LoadStaticdata |
中间分析: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 do_main---> do_main call StartBootAnimation--->//调用开机动画模块, do_main call return XRE_main---> |
main() (b2g/app/B2GLoader.cpp) |
gecko/toolkit/xre/nsAppRunner.cpp:4569, Fuc:XRE_main >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func
|-XREMain::XRE_main |
重点分析XRE_main:
结构:
|-new ScopedAppData(aAppData); |-XREMain::XRE_mainRun() |
前3个稍微了解即可,初始化启动些必要的东西。简言之,准备数据,数据丢进运行功能模块运行。
do_main call return XRE_main--->//进入xre_main |
NS_InitXPCOM2重点分析:b2g process
| |
b2g process NS_InitXPCOM2部分Log分析:
Fuc:XRE_main rv = mScopedXPCOM->Initialize()--->//开始进入初始化xpcom的入口 Fuc:NS_InitXPCOM2 call -- mozilla::AvailableMemoryTracker::Init(); ---> MessageLoop最早出现在这里,可能是某个地方初始化时就启动了,未查明,不管了,不重要,估计单开了某个线程专门用于此 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)--> |
启动app(nuwa)进程 部分:
|-XREMain::XRE_mainRun() |
较完整版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()); ---> 完成了xpcom等的启动: Fuc:XRE_main call XRE_mainRun--->//XRE_mainRun入口 rocessUtils_linux.cpp:231, Fuc:ProcLoaderClientGeckoInit ----------------------------------//创建parent actor, |ProcLoaderParent Fuc:XRE_mainRun call SetWindowCreator--->//调用窗口创建器 打了太多垃圾log!!!! 上段一样的,合并保留,懒得整理一起了 , Fuc:XRE_main call XRE_mainRun---> /ProcessUtils_linux.cpp:252, Fuc:ProcLoaderClientGeckoInit sProcLoaderParent = new ProcLoaderParent() 谁调了它,,, 循环多次??为什么?启动了几个APP???不可能, ines/nsCommandLine.cpp:554, Fuc:EnumerateHandlers call -- rv = catman->GetCategoryEntry('command-line-handler', entry.get(), getter_Copies(contractID)); ---> ines/nsCommandLine.cpp:554, Fuc:EnumerateHandlers call -- rv = catman->GetCategoryEntry('command-line-handler', entry.get(), getter_Copies(contractID)); ---> ines/nsCommandLine.cpp:554, Fuc:EnumerateHandlers call -- rv = catman->GetCategoryEntry('command-line-handler', entry.get(), getter_Copies(contractID)); ---> ines/nsCommandLine.cpp:554, Fuc:EnumerateHandlers call -- rv = catman->GetCategoryEntry('command-line-handler', entry.get(), getter_Copies(contractID)); ---> 循环四次以后,又开始关闭应用???疯了吗? 为了等待下面这个条件满足? 下面是nuwa进程紧接着打印的Log,将要开始load nuwa 开始load nuwa: /ProcessUtils_linux.cpp:521, Fuc:RecvLoad ---------------------------------- |
nuwa部分分析:
完整的nuwa process 端Log分析:
fork后b2g部分 Fuc:RunProcesses ### pid >0 is parentSock(Pid of childSock), or 0 is return by childSock:464 fork 后nuwa部分 nuwa 进程开始运行: Fuc:RunProcesses ### pid >0 is parentSock(Pid of childSock), or 0 is return by childSock:0 /ipc/glue/ProcessUtils_linux.cpp:584, Fuc:ProcLoaderServiceRun ---------------------------------- 。。。与b2g process 创建连接 /ipc/glue/ProcessUtils_linux.cpp:620, Fuc:ProcLoaderServiceRun call -- ChildThread *iothread = process->child_thread(); --->//调用子线程? /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()--->//禁止后台挂起 //不知为何就开始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 ################ 开始重复b2g里的那套 nuwa是b2g的复制??? 556, Fuc:XRE_InitChildProcess nsresult rv = XRE_InitCommandLine(aArgc, aArgv)-->又重复,初始化命令行 nuwa这一线下来是完成对自己的初始化和各功能块拉起? 213, Fuc:XRE_InitEmbedding2 call -- startupNotifier->Observe(nullptr, APPSTARTUP_TOPIC, nullptr); --->启动通知器 |
b2g 叫相关模块Load nuwa 以及之后,混杂b2g 和nuwa 进程
。。。 Fuc:XRE_mainRun call -- appStartup->GetShuttingDown(&mShuttingDown); ---> 673, 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 ---------------------------------- ... |
两进程交互部分:
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 通信相关推荐
- 问题:org.gradle.process.internal.ExecException: Process 'command 'C:\Program Files\Java\jdk1.8.0
在用as开发项目的过程中,我碰到了这个错误,在网上找到了如下的解决方法,做下总结: 被编译的代码或资源有问题( finished with non-zero exit value 1): 出现这种编译 ...
- java process 重启_JAVA Process启动sh 后的问题
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 import android.annotation.SuppressLint; import android.os.*; import java.io.* ...
- 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 ...
- python process pool_python multiprocessing.Process,multiprocessing.Pool区别(不同之处)
我们知道GIL Lock禁用了Python中的多线程功能.在Python中multiprocessing提供了两个用于多进程的类,即Process和Pool类.在以下各节中,我已对使用pool和pro ...
- checkpoint process vs writer process vs wal writer process
开始 我目前的理解是: 如果我执行了一条SQL文,那么 先是相关数据写到 wal buffer里, 然后再写到 data buffer(shared_buffer)里. 这之后, 由于wal wr ...
- python process 函数_Python Process创建进程的2种方法详解
前面介绍了使用 os.fork() 函数实现多进程编程,该方法最明显的缺陷就是不适用于 Windows 系统.本节将介绍一种支持 Python 在 Windows 平台上创建新进程的方法. Pytho ...
- Dirichlet Process 和 Dirichlet Process Mixture模型
[本文链接:http://www.cnblogs.com/breezedeus/archive/2012/11/05/2754940.html,转载请注明出处.] Dirichlet Process ...
- vue中 process.env与process.VUE_CLI_SERVICE
在vue中设置环境变量离不开process.env属性,那么如何设置自定义环境变更呢? 可以通过设置.env文件或者借助process.VUE_CLI_SERVICE来设置 process proce ...
- 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, ...
最新文章
- LLVM官方文档翻译---- LLVM原子指令与并发指引
- 怎么做到的?美术生居然转型做程序员?
- modprobe和insmod区别
- codevs1251 括号
- 2021年下半年软考报考流程!
- go和java线程,Go的多线程和pthread或Java线程有什么区别?
- Word Embedding News|词嵌入新鲜事:六月刊:GPT-3来了
- 14条Yahoo(雅虎)十四条优化原则【转】
- IBASE archive write processing report RIBARCHA
- hash表冲突处理方法
- Bailian3237 鸡兔同笼【入门】
- 决策单调性Ⅰ:四边形不等式(bzoj 1563: [NOI2009]诗人小G)
- firefox与IE浏览器在web开发上面的一些区别
- labview打包文档_labview怎么生成exe文件
- Zedgraph 总结
- 怎么把两个pdf合并成一个pdf?
- 【css】boder-sizing 中content-box与boder-box的区别
- IntelliJ IDEA Dependency 'XXXX' not found 或 java:程序包XXXX不存在,找不到的解决方案
- Python判断坐标点在五环线以内
- 论文阅读 [TPAMI-2022] Locally Connected Network for Monocular 3D Human Pose Estimation
热门文章
- 用python计算符号函数一元定积分和不定积分
- JAVA学习日记DAY09--javaweb的一些简单应用
- 2021年危险化学品生产单位安全生产管理人员报名考试及危险化学品生产单位安全生产管理人员模拟考试
- 小白要努力之为了蓝桥杯刷题!!!超简单哦!!!
- 暴力递归到动态规划 05 (贴纸拼词)
- bpduguard使用在接着虚拟机的服务器上,避免网络环路:STP和VMware vSwitch
- 通过改变电脑的某些设置来呵护我们的眼睛
- .NET导出Excel(复杂表头)
- 【C语言--文件】(详细解读)
- codeforces 1139c Edgy Trees 【并查集 】