| # Channel | |
| ## NAME | |
| channel - Bidirectional interprocess communication | |
| ## SYNOPSIS | |
| A channel is a bidirectional transport of messages consisting of some | |
| amount of byte data and some number of handles. | |
| ## DESCRIPTION | |
| Channels have two endpoints. Each endpoint, logically, maintains an ordered | |
| queue of messages to be read. Writing to an endpoint enqueues a message in the | |
| other endpoint's queue. When the last handle to an endpoint is closed the unread | |
| messages in that endpoint's queue are destroyed. Because destroying a message | |
| closes any handles contained by the message, closing a channel endpoint may have | |
| a recursive effect (e.g. channel contains a message, which contains a channel, | |
| which contains a message, and so on). | |
| Closing the last handle to a channel has no impact on the lifetime of messages | |
| previously written to that channel. This gives channels "fire and forget" | |
| semantics. | |
| A message consists of some amount of data and some number of handles. A call to | |
| [`zx_channel_write()`] enqueues one message, and a call to [`zx_channel_read()`] | |
| dequeues one message (if any are queued). A thread can block until messages are | |
| pending via [`zx_object_wait_one()`] or other waiting mechanisms. | |
| Alternatively, a call to [`zx_channel_call()`] enqueues a message in one | |
| direction of the channel, waits for a corresponding response, and | |
| dequeues the response message. In call mode, corresponding responses | |
| are identified via the first 4 bytes of the message, called the | |
| transaction ID. The kernel supplies distinct transaction IDs (always with the | |
| high bit set) for messages written with [`zx_channel_call()`]. | |
| The process of sending a message via a channel has two steps. The first is to | |
| atomically write the data into the channel and move ownership of all handles in | |
| the message into this channel. This operation always consumes the handles: at | |
| the end of the call, all handles either are all in the channel or are all | |
| discarded. The second operation, channel read, is similar: on success | |
| all the handles in the next message are atomically moved into the | |
| receiving process' handle table. On failure, the channel retains | |
| ownership unless the **ZX_CHANNEL_READ_MAY_DISCARD** option | |
| is specified, then they are dropped. | |
| Unlike many other kernel object types, channels are not duplicatable. Thus, there | |
| is only ever one handle associated with a channel endpoint, and the process holding | |
| that handle is considered the owner. Only the owner can read or write messages or send | |
| the channel endpoint to another process. | |
| When ownership of a channel endpoint moves from one process to another, | |
| messages will not be reordered or truncated, even if a write is in progress. | |
| Messages before the transfer event belong to the previous owner and messages | |
| after the transfer belong to the new owner. | |
| The same applies if a read is in progress when the endpoint is transferred. | |
| The above sequential guarantee is not provided for other kernel objects, even if | |
| the last remaining handle is stripped of the **ZX_RIGHT_DUPLICATE** right. | |
| ## SYSCALLS | |
| - [`zx_channel_call()`] - synchronously send a message and receive a reply | |
| - [`zx_channel_create()`] - create a new channel | |
| - [`zx_channel_read()`] - receive a message from a channel | |
| - [`zx_channel_write()`] - write a message to a channel | |
| <br> | |
| - [`zx_object_wait_one()`] - wait for signals on one object | |
| ## SEE ALSO | |
| + [Zircon concepts](/docs/concepts/kernel/concepts.md) | |
| + [Handles](/docs/concepts/kernel/handles.md) | |
| [`zx_channel_call()`]: /reference/syscalls/channel_call.md | |
| [`zx_channel_create()`]: /reference/syscalls/channel_create.md | |
| [`zx_channel_read()`]: /reference/syscalls/channel_read.md | |
| [`zx_channel_write()`]: /reference/syscalls/channel_write.md | |
| [`zx_object_wait_one()`]: /reference/syscalls/object_wait_one.md |