Chromium中跨进程文件句柄传递-阿里云开发者社区

开发者社区> 开发与运维> 正文

Chromium中跨进程文件句柄传递

简介: 实现说明 在Chromium跨进程架构下,也会有Browser/Renderer两个进程对相同文件进行操作的需求。

实现说明

在Chromium跨进程架构下,也会有Browser/Renderer两个进程对相同文件进行操作的需求。比如Browser的某个任务依赖于Renderer端对指定文件的输出。而在POXIS下,允许不同进程间传递文件描述符(File Descriptor))的, 比如传递socket,或者普通文件,进而可以达到不需要重新打开文件,而对相同文件读写的效果(并不是分享文件句柄)。Chromium对这个特性做了封装,也包括了Windows下的实现(也包括了Windows下的实现)。涉及的基本结构如下:
structure

其中dbus::FileDescriptor,定义在dbus/file_descriptor.h中。因为安全原因不能传递目录的FD。
base::File是对不同平台文件句柄的封装,定义在base/file.h中。
PlatformFile是一组函数,定义在base/ipc_platform_file.h,其中两个重要的API是:

IPC_EXPORT PlatformFileForTransit GetFileHandleForProcess(
    base::PlatformFile file,
    base::ProcessHandle process, 
    bool close_source_handle);  

参数解释:
base::PlatformFile file, // 当前进程打开的文件句柄
base::ProcessHandle process, // 目标process
bool close_source_handle); // 是否会关闭当前的文件句柄,如果不会,就需要多创建当前文件句柄的副本,以避免IPC传递时出现异常。否则就复用当前的文件描述符(File descriptor,Windows下为Handle)。

IPC_EXPORT PlatformFileForTransit TakeFileHandleForProcess(
    base::File file,
    base::ProcessHandle process);

这个版本就是GetFileHandleForProcess第三个参数(close_source_handle)为true的情况,这时当前进程不需要再持有这个文件句柄,看起来像是将所有权也转移到目标进程。

使用示例

// MHTMLGenerationManager (Browser)
void MHTMLGenerationManager::StreamMHTML(
    WebContents* web_contents,
    base::File browser_file, // 传入一个文件句柄browser_file
    const GenerateMHTMLCallback& callback) {

   // 转换到跨进程的FD, 并不释放所有权,所以第三个参数传递的是false。
   PC::PlatformFileForTransit renderer_file =
       IPC::GetFileHandleForProcess(browser_file.GetPlatformFile(),
                                  renderer_process, false);

   // 随后在FileAvailable函数将renderer_file传递出去。
   rvh->Send(new ViewMsg_SavePageAsMHTML(rvh->GetRoutingID(), job_id,
                                        renderer_file));
}

经过IPC,传递到Renderer进程。

// MHTMLGenerator (Renderer)
void MHTMLGenerator::OnSavePageAsMHTML(int job_id, IPC::PlatformFileForTransit file_for_transit) {
  // 从消息中的FD,转换到base::File, 可以进行相关的文件操作了。
  base::File file_ = IPC::PlatformFileForTransitToFile(file_for_transit);
  int bytes_written = file_.Write(total_bytes_written,
                                    data + total_bytes_written, copy_size);

  file_.Close();

注意多进程下,只是共享了文件描述符,可以理解共享了对相同的读写操作,但不是共享文件句柄,所以各个进程仍然要独立地进行半闭的操作 (打开时是在发起进程完成的。)

版权声明:本文首发在云栖社区,遵循云栖社区版权声明:本文内容由互联网用户自发贡献,版权归用户作者所有,云栖社区不为本文内容承担相关法律责任。云栖社区已升级为阿里云开发者社区。如果您发现本文中有涉嫌抄袭的内容,欢迎发送邮件至:developer2020@service.aliyun.com 进行举报,并提供相关证据,一经查实,阿里云开发者社区将协助删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章