Zircon Handles


英文原文快照


基础

句柄是允许用户程序引用内核对象引用的一种内核结构,它可以被认为是与特定内核对象的会话或连接。

通常情况,多个进程可通过不同的句柄同时访问同一个对象。 但是,单个句柄只能绑定到单个进程或绑定到内核中。

当它被绑定到内核时,我们称其为“传输(in-transit)”状态。

在用户空间中,句柄简单地以某些系统调用返回的特定数字值表示。 并且只有非“传输”状态的句柄对用户空间是可见的。

表示句柄的整型数值仅在该进程中是有意义的。 另一个进程中的相同数字可能不表示任何句柄,也可能表示为指向完全不同的内核对象的句柄。

表示句柄的整型值是除了ZX_HANDLE_INVALID对应的值之外的任何32位数。

在内核模式下,句柄是一个包含三个逻辑字段的C++对象: <!— + A reference to a kernel object

  • The rights to the kernel object
  • The process it is bound to (or if it’s bound to kernel) —>
  • 内核对象的引用
  • 内核对象的权限
  • 它绑定的进程(或表示它绑定到内核)

权限”指定了可以对内核对象执行哪些操作的特权。 同一个进程可以为同一内核对象提供两个具有不同权限的句柄。

使用句柄

有多个系统调用的功能是创建一个新的内核对象,并返回一个句柄。 以下面几个例子为例:

这些调用同时创建了内核对象和指向它的第一个句柄。 句柄绑定到发出系统调用的进程中,权限是该类型内核对象的默认权限。

只有下列一个系统调用可以创建句柄的副本,新句柄指向同一个内核对象并绑定到发出系统调用的进程中:

另有一个系统调用可用于创建一个等效的句柄(可能具有较少的权限),并同时使原始句柄无效:

以下系统调用仅用于销毁一个句柄:

以下两个系统调用将一个句柄绑定到调用进程并将其绑定到内核(将句柄置于“传输”状态):

以下三个系统调用适用“传输”状态的句柄并将其绑定到调用进程:

上述的channel和socket系统调用用于将句柄从一个进程传输到另一个进程。 例如,如果使用channel连接两个进程,源进程调用zx_channel_writezx_channel_call发送句柄,然后目标进程在同一channel上调用zx_channel_read接收句柄。

最后,以下系统调用为新创建的进程提供引导句柄,即它是可以用来请求获取其他句柄的句柄:

引导句柄可以是任何可传输的内核对象,但最合理的使用方式是它指向channel的一端,使得通过该初始的channel可以将更多句柄发送到新进程中。

垃圾回收

如果句柄有效,则可它指向的内核对象一定是有效的。 这是可以保证的,因为内核对象采用引用计数(ref-count)的方式被追踪,而每个句柄都包含对其内核对象的引用。

但相反的情况却并不成立。 当句柄被销毁时,并不意味着它引用的对象一定会被销毁。 可能有其他句柄指向该对象,或者内核本身可能持有对内核对象的引用。 这其中一个例子是指向线程的句柄,线程的最后一个句柄被关闭并不意味着该线程将被终止。

当释放对内核对象的最后一个引用时,内核对象被销毁或者内核将该对象标记为可垃圾回收,当对象的当前排队中的操作全部完成以后将销毁该对象。

特别情况

  • 当句柄处于“传输”状态且它被写入的channel或socket被销毁时,该句柄将被关闭。
  • 调试会话(和调试器)可能具有特殊的系统调用来访问句柄。

无效句柄和句柄重用

传递以下句柄值给除zx_object_get_info以外的任何系统调用,都将产生错误: <!—

  • A handle value that corresponds to a closed handle
  • The ZX_HANDLE_INVALID value, except for zx_handle_close syscall —>
  • 与已关闭句柄对应的句柄值
  • 对于除了zx_handle_close之外的其他系统调用而言,ZX_HANDLE_INVALID

内核可以自由地为新创建的对象重用已关闭句柄的整型值。 因此,请务必确保遵守正确的句柄使用规则:

  • 请勿在一个线程关闭给定的句柄时,另一个线程以竞争的方式使用相同的句柄,即使第二个线程也在关闭它。
  • 请勿忽略ZX_ERR_BAD_HANDLE的返回码,它们通常意味着代码存在逻辑错误。

通过使用带有ZX_POL_ACTION_EXCEPTION标志位的ZX_POL_BAD_HANDLE作业策略,可以自动检测无效句柄的使用情况,以便使此类作业对象下的进程在尝试任何上述无效情况时产生异常。

另见

Objects, Rights