Reference#
C++ API reference#
pw_channel: Async, zero-copy API for sending and receiving bytes or datagrams
-
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.
-
template<Property... kProperties>
using ByteChannelImpl = ChannelImpl<DataType::kByte, kProperties...># Implement a byte-oriented
Channel
with the specified properties.
-
template<Property... kProperties>
using DatagramChannelImpl = ChannelImpl<DataType::kDatagram, kProperties...># Implement a datagram-oriented
Channel
with the specified properties.
-
template<DataType kDataType, Property... kProperties>
class Channel# 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.To implement a
Channel
, inherit fromChannelImpl
with the specified properties.Subclassed by pw::bluetooth::low_energy::Channel
Public Functions
-
constexpr bool is_read_open() const#
True if the channel type supports and is open for reading. Always false for write-only channels.
-
constexpr bool is_write_open() const#
True if the channel type supports and is open for writing. Always false for read-only channels.
-
inline constexpr bool is_read_or_write_open() const#
True if the channel is open for reading or writing.
-
async2::Poll<Result<multibuf::MultiBuf>> PendRead(async2::Context &cx)#
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.
-
async2::Poll<Status> PendReadyToWrite(pw::async2::Context &cx)#
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.
-
Status StageWrite(multibuf::MultiBuf &&data)#
Writes using a previously allocated MultiBuf. Returns a token that refers to this write. These tokens are monotonically increasing, and PendWrite() returns the value of the latest token it has flushed.
The
MultiBuf
argument toWrite
may consist of either: (1) A singleMultiBuf
allocated byPendAllocateWriteBuffer
that has not been combined with any otherMultiBuf
s orChunk
s OR (2) AMultiBuf
containing any combination of buffers from sources other thanPendAllocateWriteBuffer
.This requirement allows for more efficient use of memory in case (1). For example, a ring-buffer implementation of a
Channel
may specializePendAllocateWriteBuffer
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.
-
async2::Poll<Status> PendWrite(async2::Context &cx)#
Completes pending writes.
Returns a
async2::Poll
indicating whether or the write has completed.Ready(OK) - All data has been successfully written.
Ready(UNIMPLEMENTED) - The channel does not support writing.
Ready(FAILED_PRECONDITION) - The channel is closed.
Pending - Writing is not complete.
-
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.
-
template<typename Sibling, typename = internal::EnableIfConversionIsValid<Channel, Sibling>>
inline constexpr operator Sibling&( Channels may be implicitly converted to other compatible channel types.
-
template<typename Sibling>
inline Sibling &as()# Returns a reference to this channel as another compatible channel type.
-
template<Property... kOtherChannelProperties>
inline auto &as()# Returns a reference to this channel as another channel with the specified properties, which must be compatible.
Public Static Functions
-
static inline constexpr DataType data_type()#
Returns the data type of this channel.
-
static inline constexpr bool reliable()#
Returns whether the channel type is reliable.
-
static inline constexpr bool seekable()#
Returns whether the channel type is seekable.
-
static inline constexpr bool readable()#
Returns whether the channel type is readable.
-
static inline constexpr bool writable()#
Returns whether the channel type is writable.
-
constexpr bool is_read_open() const#
-
class AnyChannel : private pw::channel::Channel<DataType::kByte, kReadable>, private pw::channel::Channel<DataType::kByte, kWritable>, private pw::channel::Channel<DataType::kByte, kReadable, kWritable>, private pw::channel::Channel<DataType::kByte, kReliable, kReadable>, private pw::channel::Channel<DataType::kByte, kReliable, kWritable>, private pw::channel::Channel<DataType::kByte, kReliable, kReadable, kWritable>, private pw::channel::Channel<DataType::kDatagram, kReadable>, private pw::channel::Channel<DataType::kDatagram, kWritable>, private pw::channel::Channel<DataType::kDatagram, kReadable, kWritable>, private pw::channel::Channel<DataType::kDatagram, kReliable, kReadable>, private pw::channel::Channel<DataType::kDatagram, kReliable, kWritable>, private pw::channel::Channel<DataType::kDatagram, kReliable, kReadable, kWritable>#
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. Notably, this means that it is not possible to read from the channel in one task while writing to it from another task: a single task must own and operate the channel. In the future, a wrapper will be offered which will allow the channel to be split into a read half and a write half which can be used from independent tasks.To implement a
Channel
, inherit fromChannelImpl
with the specified properties.Public Functions
-
inline constexpr DataType data_type() const#
Returns the data type of the channel implementation.
-
inline constexpr bool reliable() const#
Returns whether the channel implementation is reliable.
-
inline constexpr bool seekable() const#
Returns whether the channel implementation is seekable.
-
inline constexpr bool readable() const#
Returns whether the channel implementation is readable.
-
inline constexpr bool writable() const#
Returns whether the channel implementation is writable.
-
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 constexpr bool is_read_or_write_open() const#
True if the channel is open for either reading or writing.
-
inline async2::Poll<Result<multibuf::MultiBuf>> PendRead(async2::Context &cx)#
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)#
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 async2::Poll<std::optional<multibuf::MultiBuf>> PendAllocateWriteBuffer(async2::Context &cx, size_t min_bytes)#
Attempts to allocate a write buffer of at least
min_bytes
bytes.On success, returns a
MultiBuf
of at leastmin_bytes
. This buffer should be filled with data and then passed back intoStageWrite
. The user may shrink or fragment theMultiBuf
during its own usage of the buffer, but theMultiBuf
should be restored to its original shape before it is passed toStageWrite
.Users should not wait on the result of
PendAllocateWriteBuffer
while holding an existingMultiBuf
fromPendAllocateWriteBuffer
, as this can result in deadlocks.This method will return:
Ready(buffer) - A buffer of the requested size is provided.
Ready(std::nullopt) -
min_bytes
is larger than the maximum buffer size this channel can allocate.Pending - No buffer of at least
min_bytes
is available. The task associated with the providedpw::async2::Context
will be awoken when a sufficiently-sized buffer becomes available.
-
inline Status StageWrite(multibuf::MultiBuf &&data)#
Writes using a previously allocated MultiBuf. Returns a token that refers to this write. These tokens are monotonically increasing, and PendWrite() returns the value of the latest token it has flushed.
The
MultiBuf
argument toWrite
may consist of either: (1) A singleMultiBuf
allocated byPendAllocateWriteBuffer
that has not been combined with any otherMultiBuf
s orChunk
s OR (2) AMultiBuf
containing any combination of buffers from sources other thanPendAllocateWriteBuffer
.This requirement allows for more efficient use of memory in case (1). For example, a ring-buffer implementation of a
Channel
may specializePendAllocateWriteBuffer
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<Status> PendWrite(async2::Context &cx)#
Completes pending writes.
Returns a
async2::Poll
indicating whether or the write has completed.Ready(OK) - All data has been successfully written.
Ready(UNIMPLEMENTED) - The channel does not support writing.
Ready(FAILED_PRECONDITION) - The channel is closed.
Pending - Writing is not complete.
-
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 constexpr DataType data_type() const#
-
template<DataType kDataType, Property... kProperties>
class ChannelImpl# Extend
ChannelImpl
to implement a channel with the specified properties. Unavailable methods on the channel will be stubbed out.Alternately, inherit from
pw::channel::Implement
with a channel reader/writer alias as the template parameter.A
ChannelImpl
has a correspondingChannel
type (ChannelImpl<>::Channel
). Call thechannel()
method to convert theChannelImpl
to its correspondingChannel
.
-
template<typename ChannelType>
class Implement# Implement the specified
Channel
type. This is intended for use with the reader/writer aliases:class MyChannel : public pw::channel::Implement<pw::channel::ByteReader> {};
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> &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.
-
template<DataType kType>
class LoopbackChannel#
-
class EpollChannel : public pw::channel::Implement<ByteReaderWriter>#
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 &read_allocator,
- pw::multibuf::MultiBufAllocator &write_allocator,
Initializes and returns a reference to a channel that speaks over rp2’s stdio.
-
ByteReaderWriter &Rp2StdioChannelInit(pw::multibuf::MultiBufAllocator &allocator)#
DEPRECATED: prefer the two-allocator version of this API to avoid deadlocks due to the read or write side of the API attempting to acquire more memory while the other holds it.
Initializes and returns a reference to a channel that speaks over rp2’s stdio.
-
class StreamChannel : public pw::channel::Implement<channel::ByteReaderWriter>#
A channel which delegates to an underlying reader and writer stream.
NOTE: this channel as well as its
reader
andwriter
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
andStream::Write
are blocking. The stream reading and writing threaads may be blocked onRead
orWrite
calls, and therefore cannot cleanly be shutdown.