Wait for a packet arrival in a port.


#include <zircon/syscalls.h>
#include <zircon/syscalls/port.h>

zx_status_t zx_port_wait(zx_handle_t handle,
                         zx_time_t deadline,
                         zx_port_packet_t* packet);


zx_port_wait() is a blocking syscall which causes the caller to wait until at least one packet is available.

Upon return, if successful packet will contain the earliest (in FIFO order) available packet data.

The deadline indicates when to stop waiting for a packet (with respect to ZX_CLOCK_MONOTONIC) and will be automatically adjusted according to the job's [timer slack] policy. If no packet has arrived by the deadline, ZX_ERR_TIMED_OUT is returned. The value ZX_TIME_INFINITE will result in waiting forever. A value in the past will result in an immediate timeout, unless a packet is already available for reading.

Unlike zx_object_wait_one() and zx_object_wait_many() only one waiting thread is released (per available packet) which makes ports amenable to be serviced by thread pools.

There are two classes of packets: packets queued by userspace with zx_port_queue() and packets queued by the kernel when objects a port is registered with change state. In both cases the packet is always of type zx_port_packet_t:

struct zx_port_packet_t {
    uint64_t key;
    uint32_t type;
    zx_status_t status;
    union {
        zx_packet_user_t user;
        zx_packet_signal_t signal;
        zx_packet_guest_bell_t guest_bell;
        zx_packet_guest_mem_t guest_mem;
        zx_packet_guest_io_t guest_io;
        zx_packet_guest_vcpu_t guest_vcpu;
        zx_packet_interrupt_t interrupt;
        zx_packet_page_request_t page_request;

In the case of packets generated via zx_port_queue(), type will be set to ZX_PKT_TYPE_USER, and the caller of zx_port_queue() controls all other values in the zx_port_packet_t structure. Access to the packet data is provided by the user member, with type zx_packet_user_t:

typedef union zx_packet_user {
    uint64_t u64[4];
    uint32_t u32[8];
    uint16_t u16[16];
    uint8_t   c8[32];
} zx_packet_user_t;

For packets generated by the kernel, type can be one of the following values:

ZX_PKT_TYPE_SIGNAL_ONE - generated by objects registered via zx_object_wait_async().

ZX_PKT_TYPE_GUEST_BELL, ZX_PKT_TYPE_GUEST_MEM, ZX_PKT_TYPE_GUEST_IO, or ZX_PKT_TYPE_GUEST_VCPU - generated by objects registered via zx_guest_set_trap().

ZX_PKT_TYPE_INTERRUPT - generated by objects registered via zx_interrupt_bind().

ZX_PKT_TYPE_PAGE_REQUEST - generated by objects registered via zx_pager_create_vmo().

All kernel queued packets will have status set to ZX_OK and key set to the value provided to the registration syscall. For details on how to interpret the union, see the corresponding registration syscall.


handle must be of type ZX_OBJ_TYPE_PORT and have ZX_RIGHT_READ.


zx_port_wait() returns ZX_OK on successful packet dequeuing.


ZX_ERR_BAD_HANDLE handle is not a valid handle.

ZX_ERR_INVALID_ARGS packet isn't a valid pointer

ZX_ERR_ACCESS_DENIED handle does not have ZX_RIGHT_READ and may not be waited upon.

ZX_ERR_TIMED_OUT deadline passed and no packet was available.