pw_channel#
Warning
This module is in an early, experimental state. Do not rely on its APIs.
Channel attributes#
Channels may be reliable, readable, writable, or seekable. A channel may be substituted for another as long as it provides at least the same set of capabilities; additional capabilities are okay. The channel’s data type (datagram or byte) implies different read/write semantics, so datagram/byte channels cannot be used interchangeably in general.
Using datagram channels as byte channels#
For datagram channels, the exact bytes provided to a write call will appear in a read call on the other end. A zero-byte datagram write results in a zero-byte datagram read, so empty datagrams may convey information.
For byte channels, bytes written may be grouped differently when read. A zero-length byte write is meaningless and will not result in a zero-length byte read. If a zero-length byte read occurs, it is ignored.
To facilitate simple code reuse, datagram-oriented channels may used as
byte-oriented channels when appropriate. Calling
Channel::IgnoreDatagramBoundaries()
on a datagram channel returns a
byte channel reference to it. The byte view of the channel is simply the
concatenation of the contents of the datagrams.
This is only valid if, for the datagram channel:
datagram boundaries have no significance or meaning,
zero-length datagrams are not used to convey information, since they are meaningless for byte channels,
short or zero-length writes through the byte API will not result in unacceptable overhead.
API reference#
-
enum Property#
Basic properties of a
Channel
. AChannel
type can convert to any otherChannel
for which it supports the required properties. For example, akReadable
andkWritable
channel may be passed to an API that only requireskReadable
.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).
-
enumerator kReliable#
-
enum class DataType : uint8_t#
The type of data exchanged in
Channel
read and write calls. UnlikeProperty
,Channels
with differentDataType
s cannot be used interchangeably.Values:
-
enumerator kByte#
-
enumerator kDatagram#
-
enumerator kByte#
-
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.
-
enumerator kBeginning#
-
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<kReliable, kReadable>#
Reliable byte-oriented
Channel
that supports reading.
-
using ByteWriter = ByteChannel<kReliable, kWritable>#
Reliable byte-oriented
Channel
that supports writing.
-
using ByteReaderWriter = ByteChannel<kReliable, kReadable, kWritable>#
Reliable byte-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.
-
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.
-
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 thePend
methods are only required to remember the latestpw::async2::Context
that was provided.Subclassed by pw::channel::Channel< kDataType, kProperties >
Public Functions
-
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, invokescx.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
Data was read into a MultiBuf.
The channel does not support reading.
The channel is closed.
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 toWrite
, and the returnedMultiBuf
must not be combined with any otherMultiBuf
s orChunk
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 toWrite
may consist of either: (1) A singleMultiBuf
allocated byGetWriteAllocator()
that has not been combined with any otherMultiBuf
s orChunk
s OR (2) AMultiBuf
containing any combination of buffers from sources other thanGetWriteAllocator
.This requirement allows for more efficient use of memory in case (1). For example, a ring-buffer implementation of a
Channel
may specializeGetWriteAllocator
to return the next section of the buffer available for writing.- Returns:
May fail with the following error codes:
Code
Description
Data was accepted by the channel.
The channel does not support writing.
The write failed due to a transient error (only applies to unreliable channels).
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
andPosition
are not yet implemented.Any
PendRead
orWrite
calls following a call toSeek
will be relative to the new position. Already-written data still being flushed will be output relative to the old position.- Returns:
Code
Description
The current position was successfully changed.
The channel does not support seeking.
The channel is closed.
The seek was to a valid position, but the channel is no longer capable of seeking to this position (partially seekable channels only).
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
andPosition
are not yet implemented.
-
inline async2::Poll<pw::Status> PendClose(async2::Context &cx)#
Closes the channel, flushing any data.
- Returns:
Code
Description
The channel was closed and all data was sent successfully.
The channel was closed, but not all previously written data was delivered.
Channel was already closed, which can happen out-of-band due to errors.
-
inline async2::Poll<Result<multibuf::MultiBuf>> PendRead(async2::Context &cx)#
-
template<DataType kDataType, Property... kProperties>
class Channel : public pw::channel::AnyChannel# The basic
Channel
type. UnlikeAnyChannel
, theChannel
’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::LoopbackChannel< DataType::kByte >, pw::channel::LoopbackChannel< DataType::kDatagram >, 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 datagrams 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 datagram 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> &first()#
-
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.