nuwa :线程分析,nuwa 如何产生,nuwa如何恢复线程?

Nuwa.cpp 的ForkIPCProcess()

/**
 * Fork a new process that is ready for running IPC.
 *
 * @return the PID of the new process.
 */
static int
ForkIPCProcess() {
    P_LOGI(SEPARATOR_LINE);
    P_LOGI("call -- * Fork a new process that is ready for running IPC.  --->");
    int pid;

P_LOGI("call -- REAL(pthread_mutex_lock)(&sForkLock); --->");
    REAL(pthread_mutex_lock)(&sForkLock);

P_LOGI("call -- PrepareProtoSockets(sProtoFdInfos, sProtoFdInfosSize); --->");
    PrepareProtoSockets(sProtoFdInfos, sProtoFdInfosSize);

sNuwaForking = true;
    pid = fork();
    P_LOGI("call -- pid = fork(); pid=%d  --->",pid);
    sNuwaForking = false;
    if (pid == -1) {
        abort();
    }

if (pid > 0) {
        P_LOGI("call -- // in the parent --->");
        // in the parent
        P_LOGI("call -- AddNewProcess(pid, sProtoFdInfos, sProtoFdInfosSize); --->");
        AddNewProcess(pid, sProtoFdInfos, sProtoFdInfosSize);//调用此fork函数的父进程开始发消息给b2g??
        P_LOGI("call -- CloseAllProtoSockets(sProtoFdInfos, sProtoFdInfosSize); --->");
        CloseAllProtoSockets(sProtoFdInfos, sProtoFdInfosSize);
    } else {
        P_LOGI("call -- // in the child --->");
        // in the child
        sIsNuwaChildProcess = true;
        if (getenv("MOZ_DEBUG_CHILD_PROCESS")) {
            printf("\n\nNUWA CHILDCHILDCHILDCHILD\n  debug me @ %d\n\n", getpid());
            P_LOGI("call -- sleep(30); --->");
            sleep(30);
        }
        P_LOGI("call -- AfterForkHook(); --->");
        AfterForkHook();
        P_LOGI("call -- ReplaceSignalFds(); --->");
        ReplaceSignalFds();//开始重建进程中的各线程?
        ReplaceIPC(sProtoFdInfos, sProtoFdInfosSize);
        RecreateEpollFds();
        RecreateThreads();
       CloseAllProtoSockets(sProtoFdInfos, sProtoFdInfosSize);
    }

//解锁

P_LOGI("call -- sForkWaitCondChanged = true; --->");
    sForkWaitCondChanged = true;
    P_LOGI("call -- pthread_cond_signal(&sForkWaitCond); --->");
    pthread_cond_signal(&sForkWaitCond);
    P_LOGI("call -- pthread_mutex_unlock(&sForkLock); --->");
    pthread_mutex_unlock(&sForkLock);

P_LOGI("call -- return pid:%d; --->",pid);
    return pid;
}

Log:

整个nuwa 的fork 只是fork 了ipc 线程,,复制了一份与nuwa 进程一样的资源。repalace**就是在重建线程?

Nuwa.cpp

NuwaParent.cpp

NuwaChild.cpp

1.NuwaChild.cpp:270,Fun:AddNewIPCProcess

/**
 * AddNewIPCProcess() is called by Nuwa process to tell the parent
 * process that a new process is created.
 *AddNewIPCProcess用于告诉父进程新进程已经创建好了
 * In the newly created process, ResetContentChildTransport() is called to
 * reset fd for the IPC Channel and the session. 用于为新创建的进程重置ipc通道连接
 */
NS_EXPORT void
AddNewIPCProcess(pid_t aPid, NuwaProtoFdInfo* aInfoList, size_t aInfoListSize)
{
P_LOGI(SEPARATOR_LINE);
  nsTArray<mozilla::ipc::ProtocolFdMapping> maps;

for (size_t i = 0; i < aInfoListSize; i++) {
    int _fd = aInfoList[i].newFds[NUWA_NEWFD_PARENT];
    mozilla::ipc::FileDescriptor fd(_fd);
    mozilla::ipc::ProtocolFdMapping map(aInfoList[i].protoId, fd);
    maps.AppendElement(map);
  }

RefPtr<RunAddNewIPCProcess> runner = new RunAddNewIPCProcess(aPid, maps);
  NS_DispatchToMainThread(runner);
}

AddNewIPCProcess()

ResetContentChildTransport()

2.NuwaParent.cpp

NuwaParent.cpp:276,Fun:ForkNewProcess

3.Nuwa.cpp

ForkIPCProcess

ReplaceIPC

RecreateThreads

ContentProcess.cpp

ContentParent.cpp

ContentChild.cpp

/

1.ContentProcess.cpp

目的初始化content进程,PrecLoaderServiceRun就开始初始化content进程了,只做一次,就是nuwa没成熟前做的事情。

2.ContentParent.cpp

用于初始化b2g这端的

同时构建与child端的连接,

3.ContentChild.cpp

用于初始化并处理nuwa那端的,

ProcessChild.cpp

gecko/dom/plugins/ipc/PluginProcessParent.cpp?

层次:process --> content -->nuwa

出现新线程时就会有nuwamarkcurrentthread()出现,说明?产生新线程时会有一个自动检查是否支持nuwa的检查代码模块。

XRE_mianRun就进入GeckoChildProcessHost了,这似乎承担着ProcessParnet的角色

GeckoChildProcessHost.cpp是老大?

ProcessUtils_linux.cpp:254,Fun:ProcLoaderClientGeckoInit 用于与procLoader进行类型,就是那3个生成的文件。

nsAppRunner.cpp:4257,Fun:XRE_mainRun 作为使用这些组件模块的入口?

nsAppStartup.cpp:695,Fun:CreateChromeWindow2 创建窗口,

appshell/nsAppShellService.cpp:245,Fun:CreateTopLevelWindow创建顶层窗口实际执行者,然后就发现有imageio 线程出现了,如何创建的线程? 创建窗口。

nsBrowerApp.cpp的do_main等就是往下层的窗口,是上层浏览器的底层实现入口。直接是b2g loader 往下的实现,这就是在b2g 进程中。

在XRE_mainRun就开始创建hidden window 了,

创建好之后就开始调appstartup ->Run 接着RunNuwaProcess,

nuwa是作为contentparent(b2g)的一个APP来看待的,ContentParent.cpp:772,Fun:RunNuwaProcess 去运行nuwa进程,也即是去将nuwa进程launch出来,process_util_linux.cc:306,Fun:LaunchApp 判断是不是第一次且在nuwa第一次启动之前,也就是判断当前是不是Nuwa的加载阶段。

process_util_linux.cc:254,Fun:LaunchAppProcLoader call -- * Launch an app using B2g Loader.用b2g loader加载nuwa 应用,

RunNuwaProcess 完成了以下工作,即建立起连接通道(通过ProcLoader与preNuwa 建立了连接)并初始化nuwa,

init的具体的效果就是,PProcLoader SendLoad 请求,然后PreNuwa收到请求RecvLoad,一个写一个读,

接着就是plugin-container PrepareNuwa,

Nuwa.cpp:1959,Fun:PrepareNuwaProcess call -- * Prepare to freeze the Nuwa-supporting threads.  冻结支持Nuwa的线程,

接着就是XRE_initchildprocess,XRE_intCommandline,初始化子进程以及命令行,

processChilld初始化contchild 端,建立通道等

contentchild系统默认初始化 怎么出来的?继承关系?应该是new 了mContent,

ContentProcess.cpp:122,Fun:Init call -- mContent.Init(IOThreadChild::message_loop(), ParentPid(), IOThreadChild::channel()); --->

ContentProcess.cpp初始化,使得contentchild 设置通道等

ContentChild.cpp:693,Fun:Init call -- SetTransport(aChannel); -设置通道,

接着

ContentChild.cpp:742,Fun:Init call -- InitProcessAttributes(); --->

初始化进程的属性,设置名称,名字从b2g 变成nuwa

此时只是名字变了,里面的内容还需要处理,

Nuwa.cpp:2159,Fun:NuwaAddConstructor call -- * Register methods to be invoked before recreating threads in the spawned * process.  --->

调用添加nuwa构造器,目的是注册各种线程,并进行标记。如组件管理器,timer,js engine ,自动注册js helper? 初始化线程池,后台挂起监控,等,

ContentProcess.cpp:126,Fun:Init call -- mXREEmbed.Start(); --->初始化contentprocess,启动ns_initxpcom 给nuwa注册各种线程,

ContentProcess.cpp:128,Fun:Init call -- mContent.InitXPCOM(); --->继续初始化XPCOM,

ContentParent.cpp:3475,Fun:RecvGetXPCOMProcessAttributes -收到xpcom进程的属性,发自contentchild,

此时,

b2g 进程app服务nsAppShellService.cpp:744,Fun:GetHiddenWindow ----------------------------------请求获取隐藏窗口,而此时nuwa已经被b2g loader load 出来了,正在对load 出来的进程(nuwa)进行初始化,

同时也在标记一些线程为nuwa支持型,

在nuwa中nsEmbedFunctions.cpp:859,Fun:XRE_RunAppShell call -- return appShell->Run(); ---要求appshell 运行,接着nuwa中contentchild 获取appinfo,要准备干嘛呢

接着nuwa开始nsAppStartup.cpp:202,Fun:Init 启动APP并进行初始化?对象是??ok ,现在nuwa准备好,

接着,把此线程设置为nuwa,并通知NuwaChild.cpp:301,Fun:OnNuwaProcessReady call -- mozilla::unused << nuwaChild->SendNotifyReady();

紧接着b2g 就收到Nuwa准备好的消息,它要干嘛?

b2g调ContentParent.cpp:3141,Fun:OnNuwaReady call -- PreallocatedProcessManager::OnNuwaReady(); 就是preallocated 进程管理器,准备让它forknuwa,即复制nuwa 成为preallocated ,

b2g 进程,PreallocatedProcessManager.cpp:434,Fun:NuwaFork call -- mPreallocatedAppProcess->ForkNewProcess(false);开始创建新进程,基于nuwa,

最后是b2g中,NuwaParent.cpp:276,Fun:ForkNewProcess 发信息给nuwachild,NuwaChild.cpp:179,Fun:RecvFork收到fork消息,

ok ,nuwa正在fork新进程,

其实是为ipc 创建一个IPC进程,/Nuwa.cpp:1839,Fun:ForkIPCProcess call -- * Fork a new process that is ready for running IPC.

在生成的子进程中重新创建一些线程,设置此进程的特性等,重建的线程如下,

同时,nuwa 在

Nuwa.cpp:1859,Fun:ForkIPCProcess call -- AddNewProcess(pid:757, sProtoFdInfos, sProtoFdInfosSize); --->

fork新进程之后,调addnewprocess 告诉b2g ,进程已经创建,

然后,/NuwaParent.cpp:238,Fun:RecvAddNewProcess -就收到了,

b2g 里ContentParent.cpp:3154,Fun:OnNewProcessCreated -准备launch app 了

创建通道等,继续进行一些初始化,

直到 创建出来的进程ContentChild.cpp:764,Fun:InitProcessAttributes,将自己的名字设置为Preallocated proc

同时preallcoted 获得app 信息,ContentChild.cpp:2576,Fun:RecvAppInfo --

并且去获取隐藏窗口,nsAppShellService.cpp:744,Fun:GetHiddenWindow

b2g 和 preallocated 都去获取hidenwindow ,

同时b2g 的/ContentParent.cpp:1285,Fun:CreateBrowserOrApp创建app,需要获取preallocated 进程

重点在这里,将ContentParent.cpp:1812,Fun:TransformPreallocatedIntoApp -将reallocated 传到app 里,就设置成home screen 了

nuwa :线程分析,nuwa 如何产生,nuwa如何恢复线程?相关推荐

  1. (58)模拟线程切换——添加挂起、恢复线程功能

    一.回顾 我们在上一篇博客分析了模拟线程切换的源码. <模拟线程切换> 我们着重分析了 Scheduling 和 SwitchContext 这两个函数,对线程切换的过程有了新的认识: 线 ...

  2. 易语言创建线程挂起线程恢复线程销毁线程

    线程创建CreateThread,线程挂起SuspendThread,线程恢复ResumeThread,线程销毁TerminateThread,都是kernel32的命令,我们自己封装这些线程的命令, ...

  3. 【JVM】jstack和dump线程分析(2)

    一:jstack jstack命令的语法格式: jstack  <pid>.可以用jps查看java进程id.这里要注意的是: 1. 不同的 JAVA虚机的线程 DUMP的创建方法和文件格 ...

  4. 【Java 并发编程】线程池机制 ( 测试线程开销 | 启动线程分析 | 用户态 | 内核态 | 用户线程 | 内核线程 | 轻量级进程 )

    文章目录 一.测试线程开销 1.正常测试 2.不创建线程 3.只创建不启动线程 4.只启动不等待执行完成 二.分析测试结果 1.启动线程分析 2.用户线程与内核线程 3.轻量级进程 4.验证 Java ...

  5. 高并发编程-线程通信_使用wait和notify进行线程间的通信2_多生产者多消费者导致程序假死原因分析

    文章目录 概述 jstack或者可视化工具检测是否死锁(没有) 原因分析 概述 高并发编程-线程通信_使用wait和notify进行线程间的通信 - 遗留问题 我们看到了 应用卡住了 .... 怀疑是 ...

  6. vlc学习计划(5)--VLC程序宏及线程分析

    第一部分             变量及宏定义 1.消息映射宏                        vlc_module_begin();                           ...

  7. jvm线程分析命令_JVM:如何分析线程转储

    jvm线程分析命令 本文将教您如何分析JVM线程转储,并查明问题的根本原因. 以我的观点,线程转储分析是掌握Java EE生产支持的任何个人最重要的技能. 您可以从线程转储快照中获取的信息量通常远远超 ...

  8. java线程内存溢出_Java常见问题分析(内存溢出、内存泄露、线程阻塞等)

    Java垃圾回收机制(GC) 1.1 GC机制作用 1.2 堆内存3代分布(年轻代.老年代.持久代) 1.3 GC分类 1.4 GC过程 Java应用内存问题分析 2.1 Java内存划分 2.2 J ...

  9. 大厂之路一由浅入深、并行基础、源码分析一 “J.U.C.L”之线程池(最全,最深,最喜欢)

    参考博客: 点击!!!!!点击!!!!!点击!!!!!点击!!!!!点击!!!!!点击!!!!!延迟队列详情点击!!主要参考,点击!!!!! 为什么提出线程池? 什么是线程池技术? 什么时候用线程池计 ...

最新文章

  1. mysql原生查询单条数据_原生查询数据库流程
  2. 使用分页插件PageHelper
  3. java getimage_Java ImageView.getImage方法代码示例
  4. leetcode —— 面试题54. 二叉搜索树的第k大节点
  5. 计算机五个部件中协调,计算机基础知识(一)
  6. java bufferedrandomaccessfile_java 读写操作大文件 BufferedReader和RandomAccessFile
  7. 【C#】图片处理(底片,黑白,锐化,柔化,浮雕,雾化)
  8. TortoiseSVN中的“文件和文件夹过滤”在VS项目中的使用
  9. spark与Hive的整合入门
  10. 引入pingfang SC字体
  11. MySQL图形化性能监控工具MySQLMTOP详解
  12. 利用MATLAB进行符号运算。
  13. 怎么从PDF中提取图片?教你简单的提取方法
  14. 019-zabbix数据库表详解
  15. Altium Designer快捷键总结
  16. [渝粤教育] 西南科技大学 律师实务 在线考试复习资料2021版(1)
  17. 阿里C/C++面试题
  18. HDU6194(后缀数组)
  19. Linux下利用ssh远程文件传输 传输命令 scp
  20. linux etc fstab 重启,如何重新挂载/etc/fstab而无须重启

热门文章

  1. python形参和实参_python函数实参和形参
  2. 201712-1 CCF认证考试 最小差值 Python版
  3. 如何把uboot从SD卡烧到emmc
  4. PyCharm中的光标
  5. 软件工程实践专题 第一次作业
  6. 数字媒体发布管理系统DMS(Digital Media System)
  7. python 简历_我的Python面试简历
  8. SQLServer——MASTER..spt_values
  9. 关于SoftMax函数的一些介绍
  10. SigAI——深入浅出聚类算法