Reference#

C++ API reference#

pw_channel: Async, zero-copy API for sending and receiving bytes or datagrams

enum Property#

Basic properties of a Channel. A Channel type can convert to any other Channel for which it supports the required properties. For example, a kReadable and kWritable channel may be passed to an API that only requires kReadable.

Values:

enumerator kReliable#

All data is guaranteed to be delivered in order. The channel is closed if data is lost.

enumerator kReadable#

The channel supports reading.

enumerator kWritable#

The channel supports writing.

enumerator kSeekable#

The channel supports seeking (changing the read/write position).

enum class DataType : uint8_t#

The type of data exchanged in Channel read and write calls. Unlike Property, Channels with different DataTypes cannot be used interchangeably.

Values:

enumerator kByte#
enumerator kDatagram#
enum Whence#

Positions from which to seek.

Values:

enumerator kBeginning#

Seek from the beginning of the channel. The offset is a direct offset into the data.

enumerator kCurrent#

Seek from the current position in the channel. The offset is added to the current position. Use a negative offset to seek backwards.

Implementations may only support seeking within a limited range from the current position.

enumerator kEnd#

Seek from the end of the channel. The offset is added to the end position. Use a negative offset to seek backwards from the end.

template<Property... kProperties>
using ByteChannel = Channel<DataType::kByte, kProperties...>#

A ByteChannel exchanges data as a stream of bytes.

template<Property... kProperties>
using DatagramChannel = Channel<DataType::kDatagram, kProperties...>#

A DatagramChannel exchanges data as a series of datagrams.

using ByteReader = ByteChannel<kReadable>#

Unreliable byte-oriented Channel that supports reading.

using ByteWriter = ByteChannel<kWritable>#

Unreliable byte-oriented Channel that supports writing.

using ByteReaderWriter = ByteChannel<kReadable, kWritable>#

Unreliable byte-oriented Channel that supports reading and writing.

using ReliableByteReader = ByteChannel<kReliable, kReadable>#

Reliable byte-oriented Channel that supports reading.

using ReliableByteWriter = ByteChannel<kReliable, kWritable>#

Reliable byte-oriented Channel that supports writing.

using ReliableByteReaderWriter = ByteChannel<kReliable, kReadable, kWritable>#

Reliable byte-oriented Channel that supports reading and writing.

using DatagramReader = DatagramChannel<kReadable>#

Unreliable datagram-oriented Channel that supports reading.

using DatagramWriter = DatagramChannel<kWritable>#

Unreliable datagram-oriented Channel that supports writing.

using DatagramReaderWriter = DatagramChannel<kReadable, kWritable>#

Unreliable datagram-oriented Channel that supports reading and writing.

using ReliableDatagramReader = DatagramChannel<kReliable, kReadable>#

Reliable datagram-oriented Channel that supports reading.

using ReliableDatagramWriter = DatagramChannel<kReliable, kWritable>#

Reliable datagram-oriented Channel that supports writing.

using ReliableDatagramReaderWriter = DatagramChannel<kReliable, kReadable, kWritable>#

Reliable datagram-oriented Channel that supports reading and writing.

class WriteToken#

Represents a write operation. WriteToken can be used to track whether a particular write has been flushed.

class AnyChannel#

A generic data channel that may support reading or writing bytes or datagrams.

Note that this channel should be used from only one pw::async::Task at a time, as the Pend methods are only required to remember the latest pw::async2::Context that was provided.

Subclassed by pw::channel::Channel< kDataType, kProperties >

Public Functions

inline constexpr bool is_read_open() const#

True if the channel is open for reading. Always false for write-only channels.

inline constexpr bool is_write_open() const#

True if the channel is open for writing. Always false for read-only channels.

inline async2::Poll<Result<multibuf::MultiBuf>> PendRead(async2::Context &cx)#

Read API.

Returns a pw::multibuf::MultiBuf with read data, if available. If data is not available, invokes cx.waker() when it becomes available.

For datagram channels, each successful read yields one complete datagram, which may contain zero or more bytes. For byte stream channels, each successful read yields one or more bytes.

Channels only support one read operation / waker at a time.

Returns:

Code

Description

OK

Data was read into a MultiBuf.

UNIMPLEMENTED

The channel does not support reading.

FAILED_PRECONDITION

The channel is closed.

OUT_OF_RANGE

The end of the stream was reached. This may be though of as reaching the end of a file. Future reads may succeed after Seek ing backwards, but no more new data will be produced. The channel is still open; writes and seeks may succeed.

inline async2::Poll<Status> PendReadyToWrite(pw::async2::Context &cx)#

Write API.

Checks whether a writeable channel is currently writeable.

This should be called before attempting to Write, and may be called before allocating a write buffer if trying to reduce memory pressure.

This method will return:

  • Ready(OK) - The channel is currently writeable, and a single caller may proceed to Write.

  • Ready(UNIMPLEMENTED) - The channel does not support writing.

  • Ready(FAILED_PRECONDITION) - The channel is closed for writing.

  • Pending - cx will be awoken when the channel becomes writeable again.

Note: this method will always return Ready for non-writeable channels.

inline multibuf::MultiBufAllocator &GetWriteAllocator()#

Gives access to an allocator for write buffers. The MultiBufAllocator provides an asynchronous API for obtaining a buffer.

This allocator must only be used to allocate the next argument to Write. The allocator must be used at most once per call to Write, and the returned MultiBuf must not be combined with any other MultiBuf s or Chunk s.

This method must not be called on channels which do not support writing.

inline Result<WriteToken> Write(multibuf::MultiBuf &&data)#

Writes using a previously allocated MultiBuf. Returns a token that refers to this write. These tokens are monotonically increasing, and PendFlush() returns the value of the latest token it has flushed.

The MultiBuf argument to Write may consist of either: (1) A single MultiBuf allocated by GetWriteAllocator() that has not been combined with any other MultiBuf s or Chunks OR (2) A MultiBuf containing any combination of buffers from sources other than GetWriteAllocator.

This requirement allows for more efficient use of memory in case (1). For example, a ring-buffer implementation of a Channel may specialize GetWriteAllocator to return the next section of the buffer available for writing.

Returns:

May fail with the following error codes:

Code

Description

OK

Data was accepted by the channel.

UNIMPLEMENTED

The channel does not support writing.

UNAVAILABLE

The write failed due to a transient error (only applies to unreliable channels).

FAILED_PRECONDITION

The channel is closed.

inline async2::Poll<Result<WriteToken>> PendFlush(async2::Context &cx)#

Flushes pending writes.

Returns a async2::Poll indicating whether or not flushing has completed.

  • Ready(OK) - All data has been successfully flushed.

  • Ready(UNIMPLEMENTED) - The channel does not support writing.

  • Ready(FAILED_PRECONDITION) - The channel is closed.

  • Pending - Data remains to be flushed.

Status Seek(async2::Context &cx, ptrdiff_t position, Whence whence)#

Seek changes the position in the stream.

TODO: b/323622630 - Seek and Position are not yet implemented.

Any PendRead or Write calls following a call to Seek will be relative to the new position. Already-written data still being flushed will be output relative to the old position.

Returns:

Code

Description

OK

The current position was successfully changed.

UNIMPLEMENTED

The channel does not support seeking.

FAILED_PRECONDITION

The channel is closed.

NOT_FOUND

The seek was to a valid position, but the channel is no longer capable of seeking to this position (partially seekable channels only).

OUT_OF_RANGE

The seek went beyond the end of the stream.

size_t Position() const#

Returns the current position in the stream, or kUnknownPosition if unsupported.

TODO: b/323622630 - Seek and Position are not yet implemented.

inline async2::Poll<pw::Status> PendClose(async2::Context &cx)#

Closes the channel, flushing any data.

Returns:

Code

Description

OK

The channel was closed and all data was sent successfully.

DATA_LOSS

The channel was closed, but not all previously written data was delivered.

FAILED_PRECONDITION

Channel was already closed, which can happen out-of-band due to errors.

template<DataType kDataType, Property... kProperties>
class Channel : public pw::channel::AnyChannel#

The basic Channel type. Unlike AnyChannel, the Channel’s properties are expressed in template parameters and thus reflected in the type.

Properties must be specified in order (kDatagram, kReliable, kReadable, kWritable, kSeekable) and without duplicates.

Subclassed by pw::channel::EpollChannel, pw::channel::LoopbackChannel< DataType::kByte >, pw::channel::LoopbackChannel< DataType::kDatagram >, pw::channel::StreamChannel, pw::channel::internal::ForwardingChannel< DataType::kByte >, pw::channel::internal::ForwardingChannel< DataType::kDatagram >

Channel implementations#

using ForwardingDatagramChannelPair = ForwardingChannelPair<DataType::kDatagram>#

Alias for a pair of forwarding datagram channels.

using ForwardingByteChannelPair = ForwardingChannelPair<DataType::kByte>#

Alias for a pair of forwarding byte channels.

template<DataType kType>
class ForwardingChannelPair#

Forwards either datagrams or bytes between two channels. Writes to the first channel appear as reads on the second, and vice versa.

ForwardingChannelPair enables connecting two subsystems that communicate with channels without implementing a custom channel.

Public Functions

inline Channel<kType, kReliable, kReadable, kWritable> &first()#

Returns the first channel in the pair.

inline const Channel<kType, kReliable, kReadable, kWritable> &first() const#

Returns a const reference to the first channel in the pair.

inline Channel<kType, kReliable, kReadable, kWritable> &second()#

Returns the second channel in the pair.

inline const Channel<kType, kReliable, kReadable, kWritable> &second() const#

Returns a const reference to the second channel in the pair.

using LoopbackDatagramChannel = LoopbackChannel<DataType::kDatagram>#

Alias for a loopback channel that sends and receives datagrams.

using LoopbackByteChannel = LoopbackChannel<DataType::kByte>#

Alias for a loopback channel that sends and receives bytes.

template<DataType kType>
class LoopbackChannel#
class EpollChannel : public pw::channel::Channel<kReadable, kWritable>#

Channel implementation which writes to and reads from a file descriptor, backed by Linux’s epoll notification system.

This channel depends on APIs provided by the EpollDispatcher and cannot be used with any other dispatcher backend.

An instantiated EpollChannel takes ownership of the file descriptor it is given, and will close it if the channel is closed or destroyed. Users should not close a channel’s file descriptor from outside.

ByteReaderWriter &Rp2StdioChannelInit(pw::multibuf::MultiBufAllocator &allocator)#

Initializes and returns a reference to a channel that speaks over rp2’s stdio.

class StreamChannel : public pw::channel::Channel<kReadable, kWritable>#

A channel which delegates to an underlying reader and writer stream.

NOTE: this channel as well as its reader and writer must all continue to exist for the duration of the program, as they are referenced by other threads.

This unfortunate requirement is due to the fact that Stream::Read and Stream::Write are blocking. The stream reading and writing threaads may be blocked on Read or Write calls, and therefore cannot cleanly be shutdown.