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();

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

目录
相关文章
|
移动开发 编解码 监控
mmkv跨进程,Android开发经验的有效总结,系列篇
mmkv跨进程,Android开发经验的有效总结,系列篇
|
4月前
|
监控 安全 API
7.1 Windows驱动开发:内核监控进程与线程回调
在前面的文章中`LyShark`一直在重复的实现对系统底层模块的枚举,今天我们将展开一个新的话题,内核监控,我们以`监控进程线程`创建为例,在`Win10`系统中监控进程与线程可以使用微软提供给我们的两个新函数来实现,此类函数的原理是创建一个回调事件,当有进程或线程被创建或者注销时,系统会通过回调机制将该进程相关信息优先返回给我们自己的函数待处理结束后再转向系统层。
59 0
7.1 Windows驱动开发:内核监控进程与线程回调
|
5月前
|
存储 API Windows
4.1 Windows驱动开发:内核中进程与句柄互转
在内核开发中,经常需要进行进程和句柄之间的互相转换。进程通常由一个唯一的进程标识符(PID)来标识,而句柄是指对内核对象的引用。在Windows内核中,`EProcess`结构表示一个进程,而HANDLE是一个句柄。为了实现进程与句柄之间的转换,我们需要使用一些内核函数。对于进程PID和句柄的互相转换,可以使用函数如`OpenProcess`和`GetProcessId`。OpenProcess函数接受一个PID作为参数,并返回一个句柄。GetProcessId函数接受一个句柄作为参数,并返回该进程的PID。
48 1
4.1 Windows驱动开发:内核中进程与句柄互转
|
10月前
|
存储 API Windows
驱动开发:内核中进程与句柄互转
在内核开发中,经常需要进行进程和句柄之间的互相转换。进程通常由一个唯一的进程标识符(PID)来标识,而句柄是指对内核对象的引用。在Windows内核中,`EProcess`结构表示一个进程,而HANDLE是一个句柄。为了实现进程与句柄之间的转换,我们需要使用一些内核函数。对于进程PID和句柄的互相转换,可以使用函数如`OpenProcess`和`GetProcessId`。OpenProcess函数接受一个PID作为参数,并返回一个句柄。GetProcessId函数接受一个句柄作为参数,并返回该进程的PID。
322 0
|
11月前
|
Java 开发工具 Android开发
跨进程访问(AIDL服务)
跨进程访问(AIDL服务)
76 0
|
监控
驱动开发:内核监控进程与线程回调
在前面的文章中`LyShark`一直在重复的实现对系统底层模块的枚举,今天我们将展开一个新的话题,内核监控,我们以`监控进程线程`创建为例,在`Win10`系统中监控进程与线程可以使用微软提供给我们的两个新函数来实现,此类函数的原理是创建一个回调事件,当有进程或线程被创建或者注销时,系统会通过回调机制将该进程相关信息优先返回给我们自己的函数待处理结束后再转向系统层。
327 0
驱动开发:内核监控进程与线程回调
驱动开发:内核枚举进程与线程ObCall回调
在笔者上一篇文章`《驱动开发:内核枚举Registry注册表回调》`中我们通过特征码定位实现了对注册表回调的枚举,本篇文章`LyShark`将教大家如何枚举系统中的`ProcessObCall`进程回调以及`ThreadObCall`线程回调,之所以放在一起来讲解是因为这两中回调在枚举是都需要使用通用结构体`_OB_CALLBACK`以及`_OBJECT_TYPE`所以放在一起来讲解最好不过。
286 0
驱动开发:内核枚举进程与线程ObCall回调
|
设计模式 Java Android开发
跨进程单例 | Andorid进程通信AIDL原理及应用
设计模式中的单例模式在多进程场景下会演变成多例,存在线程安全问题。本文通过跨进程通信机制让多进程共享单例。
340 0
|
Linux Android开发
【Android 逆向】ptrace 函数 ( ptrace 函数族 | 进程附着 | 进程脱离 | 进程数据读写权限 | 进程对应的主线程寄存器读写 | 单步调试 |ptrace 函数族状态转换 )
【Android 逆向】ptrace 函数 ( ptrace 函数族 | 进程附着 | 进程脱离 | 进程数据读写权限 | 进程对应的主线程寄存器读写 | 单步调试 |ptrace 函数族状态转换 )
242 0
【Android 逆向】ptrace 函数 ( ptrace 函数族 | 进程附着 | 进程脱离 | 进程数据读写权限 | 进程对应的主线程寄存器读写 | 单步调试 |ptrace 函数族状态转换 )