port_wait - wait for a packet arrival in a port


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

mx_status_t mx_port_wait(mx_handle_t handle, mx_time_t deadline, void* packet, size_t size);


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 size argument should be set to zero and the packet argument should be memory of at least sizeof(mx_port_packet_t) bytes.

The deadline indicates when to stop waiting for a packet (with respect to MX_CLOCK_MONOTONIC). If no packet has arrived by the deadline, MX_ERR_TIMED_OUT is returned. The value MX_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 mx_object_wait_one() and mx_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 mx_port_packet_t:

struct mx_port_packet_t {
    uint64_t key;
    uint32_t type;
    int32_t status;
    union {
        mx_packet_user_t user;
        mx_packet_signal_t signal;
        mx_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 MX_PKT_TYPE_USER and the union is of type mx_packet_user_t.

typedef union mx_packet_user {
    uint64_t u64[4];
    uint32_t u32[8];
    uint16_t u16[16];
    uint8_t   c8[32];
} mx_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 MX_PKT_TYPE_SIGNAL_ONE or MX_PKT_TYPE_SIGNAL_REP and the union is of type mx_packet_signal_t:

typedef struct mx_packet_signal {
    mx_signals_t trigger;
    mx_signals_t observed;
    uint64_t count;
} mx_packet_signal_t;

for MX_WAIT_ASYNC_ONCE and MX_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 for more details.


port_wait() returns MX_OK on successful packet dequeuing.


MX_ERR_BAD_HANDLE handle is not a valid handle.

MX_ERR_INVALID_ARGS handle isn‘t a valid handle or packet isn’t a valid pointer or size is an invalid packet size.

MX_ERR_ACCESS_DENIED handle does not have MX_RIGHT_WRITE and may not be waited upon.

MX_ERR_TIMED_OUT deadline passed and no packet was available.


port_create. port_queue. object_wait_async.