# 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).
