blob: 2866ea4a0ece78ffabd17c9ac8d925fc2df9e33f [file] [log] [blame] [view]
# zx_port_wait
## NAME
<!-- Updated by update-docs-from-fidl, do not edit. -->
Wait for a packet arrival in a port.
## SYNOPSIS
<!-- Updated by update-docs-from-fidl, do not edit. -->
```c
#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);
```
## DESCRIPTION
`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** or **ZX_PKT_TYPE_SIGNAL_REP** - 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.
## RIGHTS
<!-- Updated by update-docs-from-fidl, do not edit. -->
*handle* must be of type **ZX_OBJ_TYPE_PORT** and have **ZX_RIGHT_READ**.
## RETURN VALUE
`zx_port_wait()` returns **ZX_OK** on successful packet dequeuing.
## ERRORS
**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.
## SEE ALSO
- [timer slack](/docs/concepts/kernel/timer_slack.md)
- [`zx_object_wait_async()`]
- [`zx_port_create()`]
- [`zx_port_queue()`]
<!-- References updated by update-docs-from-fidl, do not edit. -->
[`zx_guest_set_trap()`]: guest_set_trap.md
[`zx_interrupt_bind()`]: interrupt_bind.md
[`zx_object_wait_async()`]: object_wait_async.md
[`zx_object_wait_many()`]: object_wait_many.md
[`zx_object_wait_one()`]: object_wait_one.md
[`zx_pager_create_vmo()`]: pager_create_vmo.md
[`zx_port_create()`]: port_create.md
[`zx_port_queue()`]: port_queue.md