Chromium进程间通信Mojo 初始化

初始化

我们在Chromium代码中使用mojo,是不必做mojo初始化相关的事情的,因为这部分Chromium代码已经做好了。如果我们在Chromium之外的工程使用Mojo,需要做一些初始化的工作,代码如下:

int main(int argc, char* argv[]) {
  base::AtExitManager exit_manager;
  base::CommandLine::Init(0, 0);
  logging::LoggingSettings settings;
  settings.logging_dest = logging::LOG_TO_ALL;
  settings.delete_old = logging::DELETE_OLD_LOG_FILE;
  settings.log_file_path = L"mojo.log";
  logging::InitLogging(settings);

  base::MessageLoop loop;

  mojo::core::Init();
  base::Thread ipc_thread("ipc");
  ipc_thread.StartWithOptions(
      base::Thread::Options(base::MessagePumpType::IO, 0));
  mojo::core::ScopedIPCSupport ipc_support(
      ipc_thread.task_runner(),
      mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN);

  base::RunLoop().Run();

  return 0;
}

我们调用mojo::core::Init();,它会创建Core对象,并初始化好thunk函数。mojo最底层提供的都是纯C接口的thunk函数,它实际都是调用Core对象的方法。

此外我们还需要一个ScopedIPCSupport对象,如它名字所表示,它是一个IPC支持类,打开和关闭IPC。我们需要把一个用于IPC的IO线程TaskRunner传递给它,这个TaskRunner是用于IPC连接的创建和数据的收发。

ShutdownPolicy

ScopedIPCSupport初始化的时候有个ShutdownPolicy参数,指定IPC关闭时的策略。mojo的多个进程之间实际上可以建立成一个IPC网状结构,当两个以上的进程涉及到中间进程代理建立连接的时候,可能会发生意外。如果设置成ShutdownPolicy::CLEAN模式会妥善的清理退出,但是可能会导致阻塞。另外一种是ShutdownPolicy::FAST,快速的退出,不会阻塞。

这微妙的差异通常我们不用关注,使用ShutdownPolicy::CLEAN模式会更好,这也是默认的策略模式。

动态链接

上面代码是静态连接mojo的例子,这也是普遍的做法。实际上mojo也可以动态链接。动态链接稍微复杂一些,可以参考 Dynamic Linking

基本对象

mojo初始化

mojo IPC中,每个进程有一个Core对象,它拥有着一个NodeController实例。NodeController用于管理建立IPC连接的。NodeController拥有一个ports::Node实例。一个进程中也只有一个ports::Node,ports::Node可与其他进程中的ports::Node建立真正的IPC连接。