总结
订阅对象的信号。
声明
#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_EDGE 会导致端口在调用
zx_object_wait_async()
时不会将数据包加入队列以处理活动信号。
signals 参数是一个位掩码,指示 handle 指定的对象上的哪些信号会导致数据包加入队列。
如果没有 ZX_WAIT_ASYNC_EDGE
,如果在调用 zx_object_wait_async()
时信号中 any
的信号处于活动状态,或者之后变为活动状态,则数据包将在端口上加入队列。
使用 ZX_WAIT_ASYNC_EDGE
时,仅当信号中的一个或多个信号从非活跃状态转换为活跃状态后,数据包才会在端口加入队列。使用此选项时,应注意在调用 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()
会使用具有指定 key 的 handle 和 port 终止所有异步等待操作。此外,这些操作生成的队列中的所有数据包都将从队列中移除。
如果 handle 关闭,与其关联的操作也将终止,但队列中已有的数据包不会受到影响。
通过此系统调用生成的数据包会将 type 设置为 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_time_t timestamp; // depends on ZX_WAIT_ASYNC_TIMESTAMP
uint64_t reserved1;
} zx_packet_signal_t;
trigger 是 zx_object_wait_async()
调用中使用的信号,观察到的信号是实际观察到的信号,timestamp 是对象状态转换为满足触发条件时的时钟单调时间。如果选项不包含 ZX_WAIT_ASYNC_TIMESTAMP,则时间戳会报告为 0。
使用 zx_port_packet_t
的 key 成员可跟踪此数据包对应的对象。
权限
handle 必须具有 ZX_RIGHT_WAIT
。
port 必须为 ZX_OBJ_TYPE_PORT
类型且具有 ZX_RIGHT_WRITE
。
返回值
如果订阅成功,zx_object_wait_async()
会返回 ZX_OK
。
错误
ZX_ERR_INVALID_ARGS
选项设置了除 ZX_WAIT_ASYNC_TIMESTAMP
和 ZX_WAIT_ASYNC_EDGE
以外的位。
ZX_ERR_BAD_HANDLE
句柄不是有效的句柄,或 port 不是有效的句柄。
ZX_ERR_WRONG_TYPE
port 不是端口句柄。
ZX_ERR_ACCESS_DENIED
句柄没有 ZX_RIGHT_WAIT
或端口没有 ZX_RIGHT_WRITE
。
ZX_ERR_NOT_SUPPORTED
句柄是无法等待的句柄。
ZX_ERR_NO_MEMORY
由于内存不足而失败。
用户空间没有什么方法来处理此(不太可能)错误。在以后的 build 中,此错误不会再发生。
备注
如需详细了解信号及其术语,请参阅信号。