blob: 8b8651b1e80a04c7ccca79e6fc8119f119fb0343 [file] [log] [blame] [view]
# zx_port_wait
## NAME
port_wait - wait for a packet arrival in a port
## SYNOPSIS
```
#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
**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**). 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 sources of packets: manually queued packets with **port_queue**() and packets
generated by kernel when objects registered with **object_wait_async**() 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;
int32_t status;
union {
zx_packet_user_t user;
zx_packet_signal_t signal;
zx_packet_exception_t exception;
};
};
```
In the case of packets generated via **port_queue**() *key* is the key in the
input packet, *type* is set to **ZX_PKT_TYPE_USER** and the union is of 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;
```
The caller of **port_queue**() controls all the values in the structure.
In the case of packets generated via **object_wait_async**() *key* is the key passed to the
syscall, *type* is set to either **ZX_PKT_TYPE_SIGNAL_ONE** or **ZX_PKT_TYPE_SIGNAL_REP**
and the union is of type **zx_packet_signal_t**:
```
typedef struct zx_packet_signal {
zx_signals_t trigger;
zx_signals_t observed;
uint64_t count;
} zx_packet_signal_t;
```
for **ZX_WAIT_ASYNC_ONCE** and **ZX_WAIT_ASYNC_REPEATING**: *trigger* is the signals
used in the call to **object_wait_async**() and *count* is a per object defined count
of pending operations. Use *key* to track what object this packet corresponds to and
therefore match *count* with the operation.
See [object_wait_async](object_wait_async.md) for more details.
## RIGHTS
TODO(ZX-2399)
## RETURN VALUE
**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_WRITE** and may
not be waited upon.
**ZX_ERR_TIMED_OUT** *deadline* passed and no packet was available.
## SEE ALSO
[port_create](port_create.md).
[port_queue](port_queue.md).
[object_wait_async](object_wait_async.md).