Chromium Mojo - 3

阅读时 Chrome版本: 75.0.3770.4


标记方法:

下划线为当前函数归属类。

A,b代表变量b,类型为A。


斜体代表特殊名词。

拥有:指控制对象的生命周期。

终端,端点:endpoint。

消息管道: message pipe。

消息:message。

任务:tasks。


粗体代表函数名。

Foo::Bar


删除线代表已经废弃。

ReadSingleMessage,此函数在上一个正式版中存在,此版本中已废弃。


方括号代表可能出现的步骤。

[7-1.] 第7步在某些特殊情况下会调用到此分支。

[7-b-1.] 第7步在某些特殊情况下会调用到此分支[7-b],在此之前还有一个并列的分支[7-a]。


本文由@leonwxqian (各社交媒体同号)编写。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------


1. base::`anonymous namespace'::ThreadFunc

   做简单初始化后,调用delegate->ThreadMain()。

   delegate为PlatformThread::Delegate*,值为thread_params->delegate。

   thread_params类型为ThreadParams。由CreateThread传递来的参数直接转换。最终delegate即为Thread对象。

2. base::Thread::ThreadMain

   在这一层初始化线程环境,并创建RunLoop run_loop对象,然后通过Run(run_loop_)传递给下一层。

3. content::BrowserProcessSubThread::Run

   根据三种情况调用不同的函数:

BrowserThread::UIUIThreadRun(run_loop)
BrowserThread::IOIOThreadRun(run_loop)
BrowserThread::ID_COUNT未实现

4. content::BrowserProcessSubThread::IOThreadRun

    直接调用Thread::Run(run_loop)。run_loop由上层传递而来。

5. base::Thread::Run

   由ServiceThread::RunBrowserProcessSubThread::IOThreadRun创建。我们只关心后面的情况。直接调用run_loop->Run()。

   run_loop即为RunLoop的实例。由[2]创建。

6. base::RunLoop::Run

    调用RunWithTimeout(TimeDelta::Max())。即不限时长地运行。

    在RunWithTimeout中,调用delegate_->Run

    同样,delegate_在RunLoop::RunLoop构造时就会被初始化成tls_delegate.Get().Get()。即MessageLoop

7. base::MessageLoop::Run

    调用对应系统的Run操作。

8. base::MessagePump[System]::Run

    简单初始化后直接调用DoRunLoop()。

9. base::MessagePumpForIO::DoRunLoop

    消息循环中依次调用:

    state_->delegate->DoSomeWork()、WaitForIOCompletion、state_->delegate->DoIdleWork()。我们只看第二种情况。

10. base::MessagePumpForIO::WaitForIOCompletion

    一直等待系统,直到IO完成。

    如果消息已经完成,调用item.handler->OnIOCompleted

    item的定义为IOItemIOItem是一个结构体,它在MessagePumpForIO::GetIOItem处被GetQueuedCompletionStatus初始化。这是一个和系统绑定的对象。具体见下一个调用。

11. mojo::core::`anonymous namespace'::Channel[System]::OnIOCompleted

    此类根据系统不同而名称不同。

    但是动作一致,都是在IO动作完成后,如果是读动作,则调用OnReadDone并进一步触发OnReadComplete

    如果是写动作,则调用OnWriteDone并进一步触发OnWriteComplete

12. mojo::core::Channel::OnReadComplete

    当管道中消息大于消息头大小时,开始尝试读取头。

    若消息数据不是对齐的,则试图重新对齐,以防在非x86架构上出现SIGBUS错误。

    读取后,调用TryDispatchMessage来尝试分发消息。

13. mojo::core::Channel::TryDispatchMessage

    校验消息合法性(头大小、载荷大小、载荷句柄数量),如果消息合法,则试图分发。

    如果是控制消息,则转发到OnControlMessage

    如果是已经不再需要的消息,则直接丢弃。

    如果是其他消息,则发送到delegate_->OnChannelMessage

14. mojo::core::NodeChannel::OnChannelMessage

     该函数进入时则创建RequestContext request_context(RequestContext::Source::SYSTEM)。

     该函数处理多种节点消息,分别如下:

MessageType::ACCEPT_INVITEE
处理被邀请的对象
MessageType::ACCEPT_INVITATION
处理邀请
MessageType::ADD_BROKER_CLIENT
添加代理客户端
MessageType::BROKER_CLIENT_ADDED
代理客户端已添加
MessageType::ACCEPT_BROKER_CLIENT
处理代理客户端
MessageType::EVENT_MESSAGE
事件消息
MessageType::REQUEST_PORT_MERGE
请求端口合并
MessageType::REQUEST_INTRODUCTION
请求详情
MessageType::INTRODUCE
详情消息
MessageType::RELAY_EVENT_MESSAGEWIN 或 MAC OS (不包含iOS)续传事件消息
MessageType::BROADCAST_EVENT
广播事件消息
MessageType::EVENT_MESSAGE_FROM_RELAYWIN 或 MAC OS (不包含iOS)来自续传事件的消息
MessageType::ACCEPT_PEER
处理节点

    函数会根据节点类型调用对应的delegate_->OnXXXXX()函数。NodeChannel::NodeChannel初始化时即构造了delegate_。

    动作通常由NodeChannel::Create完成。一些特殊类型的消息,例如Introduce,会在OnIntroduce中调用Create,并将NodeController添加为delegate_。

    不过,如果消息不属于上述任何一个类型,函数将会退出。但是退出时会析构RequestContext

    在RequestContext::~RequestContext中,如果有Watch挂在当前Context下,它会先依次创建RequestContext对象,并借由它清空所有Watch(通过发送MOJO_RESULT_CANCELLED)。然后再对所有需要通知的Watch(watch_notify_finalizers_)调用watch.watch->InvokeCallback

15. mojo::core::Watch::InvokeCallback

     如果消息没有取消,则调用watcher_->InvokeWatchCallback。在Watch::Watch构造时,const scoped_refptr<WatcherDispatcher> ,watcher_即被初始化。

     通常,这是在调用WatcherDispatcher::WatchDispatcher时,通过将this传入Watch的构造函数来完成的。

     所以,下一步即调用mojo::core::WatcherDispatcher::InvokeWatchCallback

16. mojo::core::WatcherDispatcher::InvokeWatchCallback

     根据调入的参数,构造一个MojoTrapEvent对象,并调用handler_(&event)。handler_的定义为const MojoTrapEventHandler。在构造WatcherDispatcher时,handler_就会被初始化。

     通常,这是在调用Core::CreateTrap时,新建一个Trap,并加入传入的handle从而初始化的。

     在SimpleWatcher::SimpleWatcher处,MojoResult rv = CreateTrap(&Context::CallNotify, &trap_handle_); 通过该语句将自己注册成Trap Handler。

     所以在本例中,下一步即调用 mojo::SimpleWatcher::Context::CallNotify

N. 后置逻辑

http://chromium.world/?id=3