Chromium Mojo - 2

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


阅读时 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]。


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

0. 前置逻辑

   前置仍然有许多逻辑,下一篇再看吧。


1. mojo::SimpleWatcher::Context::CallNotify

   获取MojoTrapEvent的Context,并调用其Notify函数。

   在SimpleWatcher构造时,TrapEvent的上下文即被设置为Context::CallNotify

   所以这里调用的即SimpleWatcher::Context::Notify

2. mojo::SimpleWatcher::Context::Notify

   如果消息未被取消,则继续发送消息。

   根据不同的设置来确认是从base::WeakPtr<SimpleWatcher>,Weakptr指向的内容直接调用OnHandleReady还是PostTask去调用SimpleWatcher::OnHandleReady

   我们只关心后面的情况。

3.  mojo::SimpleWatcher::OnHandleReady

   如果消息已经是取消状态,则不做任何事。

   如果有回调,则调用该回调。ReadyCallbackWithState,callback指向callback_。

   ReadyCallbackWithState是一个语法糖,实际为 base::RepeatingCallback<void(MojoResult result, const HandleSignalsState& state)>

   

   在mojo::SimpleWatcher::Watch时,callback_就会被设置上。

[3-1.]. mojo::Connector::Connector

   会调用WaitToReadMore

[3-2.]. mojo::Connector::WaitToReadMore 或  mojo::Connector::EnsureSyncWatcherExists 

   会创建mojo::Connector::OnWatcherHandleReady 或 mojo::Connector::OnSyncHandleWatcherHandleReady

   我们现在只关心前一种情况。

    WaitToReadMore调用Watch,即handle_watcher_->Watch,绑定Connector::OnWatcherHandleReady

[3-3. ]. mojo::Connector::OnWatcherHandleReady 或 mojo::Connector::OnSyncHandleWatcherHandleReady

   都会通知到OnHandleReadyInternal

  

   这样,这里的回调,相当于就通知到了OnWatcherHandleReady ,随后调用 OnHandleReadyInternal


4.  mojo::Connector::OnHandleReadyInternal

   如果获得通知时mojo的状态正确,则调用ReadAllAvailableMessages来处理消息。

5. mojo::Connector::ReadAllAvailableMessages

   调用[5-1.]ReadMessage从消息管道中获取消息,如果该消息是消息队列中的第一个消息,或者标记为需要立刻发送。则调用DispatchMessage立刻分发该消息。

   否则,向base::queue<Message>,dispatch_queue_中推送该消息。dispatch_queue_代表所有已经读取但是没有处理的消息

   调用PostTask任务队列上推送对此消息的处理,绑定的函数是Connector::DispatchNextMessageInQueue

[5-1. ]. mojo::Connector::ReadMessage

   在早期版本中此函数叫ReadSingleMessage

   从消息管道中取出一个消息,然后创建一个Message对象。

   当创建失败时返回异常(NotifyBadMessage)。

6.  mojo::Connector::DispatchNextMessageInQueue

   调用DispatchMessage来处理消息。

7. mojo::Connector::DispatchMessage

   调用incoming_receiver_->Accept(&message)来处理消息。通常,在MultiplexRouter构造时会调用connector_.set_incoming_receiver(&filters_);将自己的std::vector<std::unique_ptr<MessageReceiver>>,filters_注册为incoming_receiver_。

8.  mojo::internal::MultiplexRouter::Accept

   异步和同步消息都会走到这里,为了防止阻塞导致的问题,程序会在Accept的第一时间就调用MultiplexRouter::InsertEndpointsForMessage将数据插入到消息关联的端点列表中。

   -  如果base::circular_deque<std::unique_ptr<Task>>,tasks_目前为空,代表无待处理的消息,则转发消息到MultiplexRouter::ProcessIncomingMessage中开始处理消息。

   -  如果任务失败或tasks_不为空,则将消息封装塞入tasks_,如果此task还有同步标志,则向std::map<InterfaceId, base::circular_deque<Task*>>, sync_message_tasks_[id](id为InterfaceId)中也推送task,并通知端点。sync_message_tasks_只保留指针副本,不拥有指针对象。

   -  如果任务成功执行,但是执行的过程中又产生了新消息(如抛出异常),导致tasks_不再为空,则程序再次调用ProcessTasks处理这个任务。

[8-1. MultiplexRouter::ProcessTasks

    如果当前任务是异常通知任务,则调用ProcessNotifyErrorTask。否则调用ProcessIncomingMessage来处理消息。

    在完成后会清理掉消息。如果此消息仍未被处理,则把它推到tasks_的最前端,在下一个循环中继续执行。

N.  后置逻辑

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