zx_object_wait_async

摘要

订阅对象上的信号。

声明

#include <zircon/syscalls.h>

zx_status_t zx_object_wait_async(zx_handle_t handle,
                                 zx_handle_t port,
                                 uint64_t key,
                                 zx_signals_t signals,
                                 uint32_t options);

说明

zx_object_wait_async() 是一个非阻塞系统调用,当 handle 指定的对象有一条或多条指定的信号被断言时,会导致数据包加入 port 队列。使用 zx_port_wait() 检索数据包。

handle 指向要监控以检测更改的对象,并且必须是可等待的对象。

options 实参可以是 0,也可以是以下一项或多项

  • ZX_WAIT_ASYNC_TIMESTAMP,这会导致系统在触发等待时捕获单调时间戳。
  • ZX_WAIT_ASYNC_BOOT_TIMESTAMP,这会导致系统在触发等待时捕获启动时间戳。
  • ZX_WAIT_ASYNC_EDGE 会导致端口不会为 zx_object_wait_async() 调用时处于活动状态的信号加入队列。

请注意,同时传递 ZX_WAIT_ASYNC_TIMESTAMP 和 ZX_WAIT_ASYNC_BOOT_TIMESTAMP 无效,将返回 ZX_ERR_INVALID_ARGS。

signals 参数是一个位掩码,用于指示由 handle 指定的对象上的哪些信号会导致将数据包加入队列。

如果不使用 ZX_WAIT_ASYNC_EDGE,当调用 zx_object_wait_async()signals 中的 any 信号处于活动状态或之后变为活动状态,系统会将数据包加入 port 队列。

如果使用 ZX_WAIT_ASYNC_EDGE,则只有在 signals 中的一个或多个信号从非活跃状态变为活跃状态后,数据包才会在 port 上加入队列。使用此选项时,请注意在调用 zx_object_wait_async() 完成之前,未启用信号意外变为启用状态的情况。在这种情况下,系统可能会错过转换,并且永远不会将数据包加入到该端口的队列中。例如,这通常在执行非阻塞 I/O 之前使用,直到信号变为非活动状态,从而确保随后从非活动状态转换为活动状态会导致将数据包加入队列。

加入队列时,数据包将包含当前断言的所有信号(而不仅仅是 signals 参数中列出的信号)。数据包加入队列后 异步等待就结束了系统不会再将其他数据包加入队列。请注意,信号会与端口维护的状态进行 OR 运算,因此当 zx_port_wait() 返回时,您可能会看到请求的信号的任意组合。

每次调用 zx_object_wait_async() 时,系统都会创建一个新的异步等待操作或观察器。这些操作不会以任何方式删除重复项。也就是说,如果使用相同的参数调用 zx_object_wait_async() 两次,系统会创建两个操作。如果断言的信号与这些操作匹配,系统会将两个数据包加入队列,每个操作对应一个数据包。

每个充电桩可执行的操作数量有限。超出限制时,超出限制的进程会引发作业政策异常 (ZX_EXCP_POLICY_CODE_PORT_TOO_MANY_OBSERVERS)。

zx_port_cancel() 会终止具有指定句柄端口的所有异步等待操作。此外,队列中由这些操作生成的所有数据包都将从队列中移除。

如果 handle 被关闭,与其关联的操作也会终止,但队列中已有的数据包不会受到影响。

通过此系统调用生成的数据包将类型设为 ZX_PKT_TYPE_SIGNAL_ONE,并且联合体类型为 zx_packet_signal_t

typedef struct zx_packet_signal {
    zx_signals_t trigger;
    zx_signals_t observed;
    uint64_t count;
    zx_instant_mono_t timestamp;       // depends on ZX_WAIT_ASYNC_TIMESTAMP
    uint64_t reserved1;
} zx_packet_signal_t;

trigger 是调用 zx_object_wait_async() 中使用的信号,obob 是实际观测到的信号,timestamp 是对象状态转换为符合触发条件时的时钟单调时间。如果 options 不包含 ZX_WAIT_ASYNC_TIMESTAMP,则时间戳会报告为 0。

使用 zx_port_packet_tkey 成员跟踪此数据包对应的对象。

权限

handle 必须包含 ZX_RIGHT_WAIT

port 必须为 ZX_OBJ_TYPE_PORT 类型且具有 ZX_RIGHT_WRITE

返回值

如果订阅成功,zx_object_wait_async() 会返回 ZX_OK

错误

ZX_ERR_INVALID_ARGS在两种情况下,会返回此值。第一个是 options 是否设置了 ZX_WAIT_ASYNC_TIMESTAMPZX_WAIT_ASYNC_BOOT_TIMESTAMPZX_WAIT_ASYNC_EDGE 以外的位。如果同时设置了 ZX_WAIT_ASYNC_TIMESTAMPZX_WAIT_ASYNC_BOOT_TIMESTAMP,则为秒。

ZX_ERR_BAD_HANDLE handle 不是有效的句柄,或 port 不是有效的句柄。

ZX_ERR_WRONG_TYPE port 不是端口句柄。

ZX_ERR_ACCESS_DENIED 句柄没有 ZX_RIGHT_WAIT,或者端口没有 ZX_RIGHT_WRITE

ZX_ERR_NOT_SUPPORTED handle 是一个无法等待的句柄。

ZX_ERR_NO_MEMORY 因内存不足而失败。 用户空间没有很好的方式来处理这种(不太可能发生的)错误。 在未来的 build 中,此错误将不再出现。

备注

如需详细了解信号及其术语,请参阅信号

另请参阅