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