xref: /aosp_15_r20/external/pigweed/seed/0114.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _seed-0114:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker==============
4*61c4878aSAndroid Build Coastguard Worker0114: Channels
5*61c4878aSAndroid Build Coastguard Worker==============
6*61c4878aSAndroid Build Coastguard Worker.. seed::
7*61c4878aSAndroid Build Coastguard Worker   :number: 114
8*61c4878aSAndroid Build Coastguard Worker   :name: Channels
9*61c4878aSAndroid Build Coastguard Worker   :status: Accepted
10*61c4878aSAndroid Build Coastguard Worker   :proposal_date: 2023-10-10
11*61c4878aSAndroid Build Coastguard Worker   :cl: 175471
12*61c4878aSAndroid Build Coastguard Worker   :authors: Wyatt Hepler
13*61c4878aSAndroid Build Coastguard Worker   :facilitator: Carlos Chinchilla
14*61c4878aSAndroid Build Coastguard Worker
15*61c4878aSAndroid Build Coastguard Worker-------
16*61c4878aSAndroid Build Coastguard WorkerSummary
17*61c4878aSAndroid Build Coastguard Worker-------
18*61c4878aSAndroid Build Coastguard WorkerThis document proposes a new ``pw_channel`` module and
19*61c4878aSAndroid Build Coastguard Worker:cpp:class:`pw::channel::Channel` class. The module is similar to
20*61c4878aSAndroid Build Coastguard Workerpw_stream, with three key changes:
21*61c4878aSAndroid Build Coastguard Worker
22*61c4878aSAndroid Build Coastguard Worker- Supports byte stream or datagram semantics (:ref:`module-pw_stream` is a
23*61c4878aSAndroid Build Coastguard Worker  subset of ``pw_channel``).
24*61c4878aSAndroid Build Coastguard Worker- Provides an asynchronous API (:ref:`SEED-0112`).
25*61c4878aSAndroid Build Coastguard Worker- Uses the :ref:`SEED-0109` buffers system, which enables zero-copy
26*61c4878aSAndroid Build Coastguard Worker  and vectored I/O.
27*61c4878aSAndroid Build Coastguard Worker
28*61c4878aSAndroid Build Coastguard Worker``pw_channel`` will provide the data transmit and receive API for the upcoming
29*61c4878aSAndroid Build Coastguard Workersocket abstraction.
30*61c4878aSAndroid Build Coastguard Worker
31*61c4878aSAndroid Build Coastguard Worker--------
32*61c4878aSAndroid Build Coastguard WorkerProposal
33*61c4878aSAndroid Build Coastguard Worker--------
34*61c4878aSAndroid Build Coastguard WorkerThis SEED proposes the following:
35*61c4878aSAndroid Build Coastguard Worker
36*61c4878aSAndroid Build Coastguard Worker- Introduce a new ``pw_channel`` module.
37*61c4878aSAndroid Build Coastguard Worker- Introduce a :cpp:class:`pw::channel::Channel` virtual interface.
38*61c4878aSAndroid Build Coastguard Worker  Implementors of this interface may expose byte stream or datagram semantics.
39*61c4878aSAndroid Build Coastguard Worker  All operations in this interface are async and use :ref:`seed-0109` buffers
40*61c4878aSAndroid Build Coastguard Worker  to provide zero-copy operations.
41*61c4878aSAndroid Build Coastguard Worker- Use ``pw_channel`` as the basis for the upcoming Pigweed sockets API.
42*61c4878aSAndroid Build Coastguard Worker- Replace ``pw_stream`` with ``pw_channel`` to the extent possible.
43*61c4878aSAndroid Build Coastguard Worker
44*61c4878aSAndroid Build Coastguard Worker----------
45*61c4878aSAndroid Build Coastguard WorkerMotivation
46*61c4878aSAndroid Build Coastguard Worker----------
47*61c4878aSAndroid Build Coastguard WorkerOne of the fundamental operations of computing is sending data from one place to
48*61c4878aSAndroid Build Coastguard Workeranother. Examples include exchanging data with
49*61c4878aSAndroid Build Coastguard Worker
50*61c4878aSAndroid Build Coastguard Worker- an in-memory data structure,
51*61c4878aSAndroid Build Coastguard Worker- a file in a filesystem,
52*61c4878aSAndroid Build Coastguard Worker- a hardware peripheral,
53*61c4878aSAndroid Build Coastguard Worker- another process, or
54*61c4878aSAndroid Build Coastguard Worker- a device across a network.
55*61c4878aSAndroid Build Coastguard Worker
56*61c4878aSAndroid Build Coastguard WorkerThere are many interfaces for data exchange. Pigweed provides
57*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_stream`, which is a simple synchronous API for transmitting and
58*61c4878aSAndroid Build Coastguard Workerreceiving data. ``pw_stream``'s simple model has made it prevalent in Pigweed.
59*61c4878aSAndroid Build Coastguard Worker
60*61c4878aSAndroid Build Coastguard WorkerThe Pigweed team is revamping its communications systems (see :ref:`seed-0107`).
61*61c4878aSAndroid Build Coastguard WorkerThe new sockets API will be a critical piece of that story. The core job of a
62*61c4878aSAndroid Build Coastguard Workersocket is to exchange data with another node in the network. ``pw_stream``'s
63*61c4878aSAndroid Build Coastguard Workerpurpose is to facilitate data exchange, but it is too limited for sockets.
64*61c4878aSAndroid Build Coastguard Workerpw_stream is missing support for several features, including:
65*61c4878aSAndroid Build Coastguard Worker
66*61c4878aSAndroid Build Coastguard Worker- Datagrams – Data is a byte stream. Datagrams are not supported.
67*61c4878aSAndroid Build Coastguard Worker- Unreliability – Sockets may not guarantee delivery of data. ``pw_stream``
68*61c4878aSAndroid Build Coastguard Worker  assumes no data is lost if ``Write`` returns ``OK``.
69*61c4878aSAndroid Build Coastguard Worker- Asynchronous operations – All functions block until the operation completes.
70*61c4878aSAndroid Build Coastguard Worker- Zero copy operations – All reads and writes require data to be copied.
71*61c4878aSAndroid Build Coastguard Worker- Vectored I/O – All reads and writes use a single contiguous buffer.
72*61c4878aSAndroid Build Coastguard Worker- Backpressure – There is no mechanism for a stream to notify the producer that
73*61c4878aSAndroid Build Coastguard Worker  it needs more time to process data.
74*61c4878aSAndroid Build Coastguard Worker
75*61c4878aSAndroid Build Coastguard WorkerThese features are fairly complex and may be exposed in a variety of ways in an
76*61c4878aSAndroid Build Coastguard WorkerAPI. This SEED proposes a new ``pw_stream``-like ``Channel`` data exchange API.
77*61c4878aSAndroid Build Coastguard Worker``Channel`` provides a standard I/O interface with these advanced features.
78*61c4878aSAndroid Build Coastguard WorkerLike ``pw_stream``, this API will be used anywhere data needs to be read and/or
79*61c4878aSAndroid Build Coastguard Workerwritten.
80*61c4878aSAndroid Build Coastguard Worker
81*61c4878aSAndroid Build Coastguard Worker---------
82*61c4878aSAndroid Build Coastguard WorkerUse cases
83*61c4878aSAndroid Build Coastguard Worker---------
84*61c4878aSAndroid Build Coastguard Workerpw_rpc
85*61c4878aSAndroid Build Coastguard Worker======
86*61c4878aSAndroid Build Coastguard Workerpw_rpc is a communications protocol that enables calling procedures on different
87*61c4878aSAndroid Build Coastguard Workernodes (i.e. RPCs), and sharing data between them. RPCs can be sent using
88*61c4878aSAndroid Build Coastguard Workerpw_stream APIs, which are blocking.
89*61c4878aSAndroid Build Coastguard Worker
90*61c4878aSAndroid Build Coastguard WorkerSockets
91*61c4878aSAndroid Build Coastguard Worker=======
92*61c4878aSAndroid Build Coastguard WorkerSockets are a communications channel between two endpoints in a network.
93*61c4878aSAndroid Build Coastguard WorkerSockets support exchanging data:
94*61c4878aSAndroid Build Coastguard Worker
95*61c4878aSAndroid Build Coastguard Worker- as datagrams or a stream or bytes, and
96*61c4878aSAndroid Build Coastguard Worker- reliably or unreliably.
97*61c4878aSAndroid Build Coastguard Worker
98*61c4878aSAndroid Build Coastguard Workerpw_stream
99*61c4878aSAndroid Build Coastguard Worker=========
100*61c4878aSAndroid Build Coastguard Worker``Channel`` should support all use cases addressed by ``pw_stream``. These
101*61c4878aSAndroid Build Coastguard Workerinclude:
102*61c4878aSAndroid Build Coastguard Worker
103*61c4878aSAndroid Build Coastguard Worker- :cpp:class:`pw::stream::NullStream` -- ``NullStream`` ignores all bytes
104*61c4878aSAndroid Build Coastguard Worker  written to it and produces no bytes when read. This is used when no input or
105*61c4878aSAndroid Build Coastguard Worker  output is needed.
106*61c4878aSAndroid Build Coastguard Worker- :cpp:class:`pw::stream::CountingNullStream` -- Counts bytes written to it.
107*61c4878aSAndroid Build Coastguard Worker  Used to to determine the size of an encoded object before it is encoded to its
108*61c4878aSAndroid Build Coastguard Worker  final destination.
109*61c4878aSAndroid Build Coastguard Worker- :cpp:class:`pw::stream::MemoryReader` / :cpp:class:`pw::stream::MemoryWriter`
110*61c4878aSAndroid Build Coastguard Worker  -- Writes data to or reads data from a fixed, contiguous memory buffer.
111*61c4878aSAndroid Build Coastguard Worker  Example uses include encoding a protobuf for transport.
112*61c4878aSAndroid Build Coastguard Worker- :cpp:class:`pw::stream::SocketStream` -- Supports reading from and writing to
113*61c4878aSAndroid Build Coastguard Worker  a TCP socket.
114*61c4878aSAndroid Build Coastguard Worker- :cpp:class:`pw::blob_store::BlobStore::Reader` /
115*61c4878aSAndroid Build Coastguard Worker  :cpp:class:`pw::blob_store::BlobStore::Writer` -- ``pw_blob_store`` uses a
116*61c4878aSAndroid Build Coastguard Worker  stream interface for reading and writing. This is similar to a file object.
117*61c4878aSAndroid Build Coastguard Worker
118*61c4878aSAndroid Build Coastguard WorkerHardware interfaces
119*61c4878aSAndroid Build Coastguard Worker===================
120*61c4878aSAndroid Build Coastguard WorkerIt is often necessary to exchange data with hardware I/O blocks.
121*61c4878aSAndroid Build Coastguard WorkerThe ``Channel`` API could be used to abstract communications with I/O
122*61c4878aSAndroid Build Coastguard Workerinterfaces.
123*61c4878aSAndroid Build Coastguard Worker
124*61c4878aSAndroid Build Coastguard Worker------------------
125*61c4878aSAndroid Build Coastguard WorkerExisting solutions
126*61c4878aSAndroid Build Coastguard Worker------------------
127*61c4878aSAndroid Build Coastguard Worker
128*61c4878aSAndroid Build Coastguard Workerpw_stream
129*61c4878aSAndroid Build Coastguard Worker=========
130*61c4878aSAndroid Build Coastguard Workerpw_stream provides for a synchronous, reliable byte-oriented stream.
131*61c4878aSAndroid Build Coastguard Worker
132*61c4878aSAndroid Build Coastguard WorkerSee :ref:`module-pw_stream`.
133*61c4878aSAndroid Build Coastguard Worker
134*61c4878aSAndroid Build Coastguard WorkerC++
135*61c4878aSAndroid Build Coastguard Worker===
136*61c4878aSAndroid Build Coastguard WorkerC++ provides an I/O stream family of classes.
137*61c4878aSAndroid Build Coastguard Worker
138*61c4878aSAndroid Build Coastguard WorkerJava
139*61c4878aSAndroid Build Coastguard Worker====
140*61c4878aSAndroid Build Coastguard WorkerJava provides a hierarchy of channel classes with a variety of flavors. The
141*61c4878aSAndroid Build Coastguard Worker`Channel interface
142*61c4878aSAndroid Build Coastguard Worker<https://docs.oracle.com/javase/8/docs/api/java/nio/channels/Channel.html>`_
143*61c4878aSAndroid Build Coastguard Workerprovides just two methods: ``isOpen()`` and ``close()``. Various I/O operations
144*61c4878aSAndroid Build Coastguard Workerare mixed in through different interfaces. ``Channel`` supports `byte stream
145*61c4878aSAndroid Build Coastguard Worker<https://docs.oracle.com/javase/8/docs/api/java/nio/channels/ByteChannel.html>`_,
146*61c4878aSAndroid Build Coastguard Worker`datagram
147*61c4878aSAndroid Build Coastguard Worker<https://docs.oracle.com/javase/8/docs/api/java/nio/channels/DatagramChannel.html>`_,
148*61c4878aSAndroid Build Coastguard Worker`asynchronous <https://docs.oracle.com/javase/8/docs/api/java/nio/channels/AsynchronousChannel.html>`_,
149*61c4878aSAndroid Build Coastguard Workerand `scatter <https://docs.oracle.com/javase/8/docs/api/java/nio/channels/ScatteringByteChannel.html>`_/
150*61c4878aSAndroid Build Coastguard Worker`gather <https://docs.oracle.com/javase/8/docs/api/java/nio/channels/GatheringByteChannel.html>`_ IO.
151*61c4878aSAndroid Build Coastguard Worker
152*61c4878aSAndroid Build Coastguard WorkerC#
153*61c4878aSAndroid Build Coastguard Worker==
154*61c4878aSAndroid Build Coastguard WorkerThe C# programming language offers a stream class similar to pw_stream and the
155*61c4878aSAndroid Build Coastguard Workerproposed pw_channel module. It supports synchronous and asynchronous operations
156*61c4878aSAndroid Build Coastguard Workeron a stream of bytes.
157*61c4878aSAndroid Build Coastguard Workerhttps://learn.microsoft.com/en-us/dotnet/api/system.io.stream?view=net-7.0
158*61c4878aSAndroid Build Coastguard Worker
159*61c4878aSAndroid Build Coastguard WorkerC#’s Channel API has a different intent than pw_channel. Its purpose is to
160*61c4878aSAndroid Build Coastguard Workersynchronize objects between endpoints, and is somewhat different from what is
161*61c4878aSAndroid Build Coastguard Workerproposed here.
162*61c4878aSAndroid Build Coastguard Workerhttps://learn.microsoft.com/en-us/dotnet/api/system.threading.channels?view=net-7.0
163*61c4878aSAndroid Build Coastguard Worker
164*61c4878aSAndroid Build Coastguard Worker------------
165*61c4878aSAndroid Build Coastguard WorkerRequirements
166*61c4878aSAndroid Build Coastguard Worker------------
167*61c4878aSAndroid Build Coastguard Worker* Support data transmission for the upcoming sockets API (:ref:`seed-0107`):
168*61c4878aSAndroid Build Coastguard Worker
169*61c4878aSAndroid Build Coastguard Worker  - reliable byte stream (``SOCK_STREAM``)
170*61c4878aSAndroid Build Coastguard Worker  - unreliable datagram (``SOCK_DGRAM``)
171*61c4878aSAndroid Build Coastguard Worker  - reliable datagram (``SOCK_SEQPACKET``)
172*61c4878aSAndroid Build Coastguard Worker
173*61c4878aSAndroid Build Coastguard Worker* Asynchronous operations.
174*61c4878aSAndroid Build Coastguard Worker* Efficient, minimally copying buffer with ``MultiBuf`` (:ref:`seed-0109`).
175*61c4878aSAndroid Build Coastguard Worker
176*61c4878aSAndroid Build Coastguard Worker------
177*61c4878aSAndroid Build Coastguard WorkerDesign
178*61c4878aSAndroid Build Coastguard Worker------
179*61c4878aSAndroid Build Coastguard WorkerConceptually, a channel is a sequence of bytes or datagrams exchanged between
180*61c4878aSAndroid Build Coastguard Workertwo endpoints. An endpoint can be anything that produces or consumes data, such
181*61c4878aSAndroid Build Coastguard Workeras an in-memory data structure, a file in a filesystem, a hardware peripheral,
182*61c4878aSAndroid Build Coastguard Workeror a network socket. Both endpoints may be ``Channel`` implementations, or the
183*61c4878aSAndroid Build Coastguard Worker``Channel`` may simply forward to something that provides compatible semantics,
184*61c4878aSAndroid Build Coastguard Workere.g. a memory buffer or OS socket.
185*61c4878aSAndroid Build Coastguard Worker
186*61c4878aSAndroid Build Coastguard WorkerIn Unix, "everything is a file". File descriptors provide a common I/O interface
187*61c4878aSAndroid Build Coastguard Workerused for everything from files to pipes to sockets to hardware devices. Channels
188*61c4878aSAndroid Build Coastguard Workerfill a similar role as POSIX file descriptors.
189*61c4878aSAndroid Build Coastguard Worker
190*61c4878aSAndroid Build Coastguard WorkerChannel semantics
191*61c4878aSAndroid Build Coastguard Worker=================
192*61c4878aSAndroid Build Coastguard Workerpw_channel will provide the data exchange API for Pigweed’s upcoming network
193*61c4878aSAndroid Build Coastguard Workersockets. To this end, ``Channel`` supports the following socket semantics:
194*61c4878aSAndroid Build Coastguard Worker
195*61c4878aSAndroid Build Coastguard Worker- reliable byte stream (``SOCK_STREAM``)
196*61c4878aSAndroid Build Coastguard Worker- unreliable datagram (``SOCK_DGRAM``)
197*61c4878aSAndroid Build Coastguard Worker- reliable datagram (``SOCK_SEQPACKET``)
198*61c4878aSAndroid Build Coastguard Worker
199*61c4878aSAndroid Build Coastguard WorkerReliability and data type (stream versus datagram) are essential aspects of
200*61c4878aSAndroid Build Coastguard Workerchannel semantics. These properties affect how code that uses the APIs is
201*61c4878aSAndroid Build Coastguard Workerwritten. A channel with different semantics cannot be swapped for another
202*61c4878aSAndroid Build Coastguard Workerwithout updating the assumptions in the surrounding code.
203*61c4878aSAndroid Build Coastguard Worker
204*61c4878aSAndroid Build Coastguard WorkerData type: datagrams & byte streams
205*61c4878aSAndroid Build Coastguard Worker-----------------------------------
206*61c4878aSAndroid Build Coastguard WorkerFundamentally, a channel involves sending data from one endpoint to another.
207*61c4878aSAndroid Build Coastguard WorkerThe endpoints might both be ``Channel`` instances (e.g. two sockets). Or, one
208*61c4878aSAndroid Build Coastguard Workerendpoint could be a ``Channel`` while the other is an in-memory data structure,
209*61c4878aSAndroid Build Coastguard Workerfile in a file system, or hardware peripheral.
210*61c4878aSAndroid Build Coastguard Worker
211*61c4878aSAndroid Build Coastguard WorkerThe data type dictates the basic unit of data transmission. Datagram channels
212*61c4878aSAndroid Build Coastguard Workersend and receive datagrams: "self-contained, independent entit[ies] of data"
213*61c4878aSAndroid Build Coastguard Worker(`RFC 1594 <https://www.rfc-editor.org/rfc/rfc1594.txt>`_). Datagrams contain a
214*61c4878aSAndroid Build Coastguard Workerpayload of zero or more bytes. pw_channel does not define a maximum payload size
215*61c4878aSAndroid Build Coastguard Workerfor datagrams.
216*61c4878aSAndroid Build Coastguard Worker
217*61c4878aSAndroid Build Coastguard WorkerByte stream channels send and receive an arbitrary sequence of bytes.
218*61c4878aSAndroid Build Coastguard WorkerZero-length byte stream writes are no-ops and may not result in any bytes being
219*61c4878aSAndroid Build Coastguard Workertransmitted.
220*61c4878aSAndroid Build Coastguard Worker
221*61c4878aSAndroid Build Coastguard WorkerIn terms of the channels API, ``Read``, ``Write``, and ``Seek`` functions have
222*61c4878aSAndroid Build Coastguard Workerdifferent meanings for byte and and datagram channels. For byte stream channels,
223*61c4878aSAndroid Build Coastguard Workerthese functions work with an arbitrary number of bytes. For datagram channels,
224*61c4878aSAndroid Build Coastguard Worker``Read``, ``Write``, and ``Seek`` are in terms of datagrams.
225*61c4878aSAndroid Build Coastguard Worker
226*61c4878aSAndroid Build Coastguard WorkerReliable channels
227*61c4878aSAndroid Build Coastguard Worker-----------------
228*61c4878aSAndroid Build Coastguard WorkerReliable channels guarantee that their data is received in order and without
229*61c4878aSAndroid Build Coastguard Workerloss. The API user does not have to do anything to ensure this. After a write is
230*61c4878aSAndroid Build Coastguard Workeraccepted, the user will never have to retry it. Reads always provide data in
231*61c4878aSAndroid Build Coastguard Workerorder without loss. The channel implementation is responsible for this.
232*61c4878aSAndroid Build Coastguard Worker
233*61c4878aSAndroid Build Coastguard WorkerFor some channels, reliability is trivial; for others it requires significant
234*61c4878aSAndroid Build Coastguard Workerwork:
235*61c4878aSAndroid Build Coastguard Worker
236*61c4878aSAndroid Build Coastguard Worker- A memory channel that writes to a buffer is trivially reliable.
237*61c4878aSAndroid Build Coastguard Worker- A socket communicating across a network will require a complex protocol such
238*61c4878aSAndroid Build Coastguard Worker  as TCP to guarantee that the data is delivered.
239*61c4878aSAndroid Build Coastguard Worker
240*61c4878aSAndroid Build Coastguard WorkerInitially, only reliable byte-oriented channels will be supported. Unreliable
241*61c4878aSAndroid Build Coastguard Workerbyte streams are not commonly supported, and would be difficult to apply in many
242*61c4878aSAndroid Build Coastguard Workeruse cases. There are circumstances where unreliable byte streams do makes sense,
243*61c4878aSAndroid Build Coastguard Workersuch as reading time-sensitive sensor data, where the consumer only wants the
244*61c4878aSAndroid Build Coastguard Workervery latest data regardless of drops. Unreliable byte streams may be added in
245*61c4878aSAndroid Build Coastguard Workerthe future.
246*61c4878aSAndroid Build Coastguard Worker
247*61c4878aSAndroid Build Coastguard WorkerData loss
248*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^
249*61c4878aSAndroid Build Coastguard WorkerData is never silently lost in a reliable channel. Unrecoverable data loss
250*61c4878aSAndroid Build Coastguard Workeralways results in the eventual closure of the channel, since a fundamental
251*61c4878aSAndroid Build Coastguard Workerinvariant of the channel cannot be maintained.
252*61c4878aSAndroid Build Coastguard Worker
253*61c4878aSAndroid Build Coastguard WorkerA few examples:
254*61c4878aSAndroid Build Coastguard Worker
255*61c4878aSAndroid Build Coastguard Worker- A write to a TCP channel fails because of a transient hardware issue. The
256*61c4878aSAndroid Build Coastguard Worker  channel and underlying TCP connection are closed.
257*61c4878aSAndroid Build Coastguard Worker- A TCP channel times out on a retry. The channel and underlying TCP connection
258*61c4878aSAndroid Build Coastguard Worker  are closed.
259*61c4878aSAndroid Build Coastguard Worker- A write to a channel that fills a ring buffer is requested. A ``MultiBuf`` for
260*61c4878aSAndroid Build Coastguard Worker  the write is not provided immediately because the ring buffer is full. The
261*61c4878aSAndroid Build Coastguard Worker  channel stays open, but the write is delayed until the ring buffer has
262*61c4878aSAndroid Build Coastguard Worker  sufficient space.
263*61c4878aSAndroid Build Coastguard Worker
264*61c4878aSAndroid Build Coastguard WorkerReliability & connections
265*61c4878aSAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^^^^^^^
266*61c4878aSAndroid Build Coastguard WorkerReliable channels operate as if they have a connection, even if the underlying
267*61c4878aSAndroid Build Coastguard Workerimplementation does not establish a connection. This specifically means that:
268*61c4878aSAndroid Build Coastguard Worker
269*61c4878aSAndroid Build Coastguard Worker- It is assumed that the peer endpoint will receive data for which the write
270*61c4878aSAndroid Build Coastguard Worker  call succeeded.
271*61c4878aSAndroid Build Coastguard Worker- If data is lost, the error will be reported in some form and the channel will
272*61c4878aSAndroid Build Coastguard Worker  be closed.
273*61c4878aSAndroid Build Coastguard Worker
274*61c4878aSAndroid Build Coastguard WorkerFor example, a TCP socket channel would maintain an explicit connection, while a
275*61c4878aSAndroid Build Coastguard Workerring buffer channel would not.
276*61c4878aSAndroid Build Coastguard Worker
277*61c4878aSAndroid Build Coastguard WorkerUnreliable channels
278*61c4878aSAndroid Build Coastguard Worker-------------------
279*61c4878aSAndroid Build Coastguard WorkerUnreliable datagram channels make no guarantees about whether datagrams are
280*61c4878aSAndroid Build Coastguard Workerdelivered and in what order they arrive. Users are responsible for tracking
281*61c4878aSAndroid Build Coastguard Workerdrops and ordering if required.
282*61c4878aSAndroid Build Coastguard Worker
283*61c4878aSAndroid Build Coastguard WorkerUnreliable channels should report read and write failures whenever possible,
284*61c4878aSAndroid Build Coastguard Workerbut an ``OK`` write does not indicate that the data is received by the other
285*61c4878aSAndroid Build Coastguard Workerendpoint.
286*61c4878aSAndroid Build Coastguard Worker
287*61c4878aSAndroid Build Coastguard WorkerFlow control, backpressure, and ``ConservativeLimit``
288*61c4878aSAndroid Build Coastguard Worker=====================================================
289*61c4878aSAndroid Build Coastguard WorkerA channel may provide backpressure through its async write API. The
290*61c4878aSAndroid Build Coastguard Worker``PollWritable`` method should be used to ensure that the channel is ready
291*61c4878aSAndroid Build Coastguard Workerto receive calls to ``Write``. Additionally, the ``MultiBufAllocator`` may wait
292*61c4878aSAndroid Build Coastguard Workerto provide a ``MultiBuf`` for writing until memory becomes available.
293*61c4878aSAndroid Build Coastguard Worker
294*61c4878aSAndroid Build Coastguard Workerpw_stream offered a notion of flow control through the
295*61c4878aSAndroid Build Coastguard Worker:cpp:func:`pw::stream::Stream::ConservativeWriteLimit` function. Code using a
296*61c4878aSAndroid Build Coastguard Workerstream could check the write limit prior to writing data to determine if the
297*61c4878aSAndroid Build Coastguard Workerstream is ready to receive more. This function will not be provided in
298*61c4878aSAndroid Build Coastguard Worker``pw_channel``.
299*61c4878aSAndroid Build Coastguard Worker
300*61c4878aSAndroid Build Coastguard WorkerOpenness / closedness
301*61c4878aSAndroid Build Coastguard Worker=====================
302*61c4878aSAndroid Build Coastguard Workerpw_channel will have an explicit open/closed concept that ``pw_stream`` lacks.
303*61c4878aSAndroid Build Coastguard WorkerReads and writes may succeed when the channel is open. Reads and writes never
304*61c4878aSAndroid Build Coastguard Workersucceed when the channel is closed.
305*61c4878aSAndroid Build Coastguard Worker
306*61c4878aSAndroid Build Coastguard WorkerThe channel API supports closing a channel, but does not support opening a
307*61c4878aSAndroid Build Coastguard Workerchannel. Channels are opened by interacting with a concrete class.
308*61c4878aSAndroid Build Coastguard Worker
309*61c4878aSAndroid Build Coastguard WorkerReliable channels are closed if unrecoverable data loss occurs. Unreliable
310*61c4878aSAndroid Build Coastguard Workerchannels may be closed when reads or writes are known to fail (e.g. a
311*61c4878aSAndroid Build Coastguard Workercable was unplugged), but this is not required.
312*61c4878aSAndroid Build Coastguard Worker
313*61c4878aSAndroid Build Coastguard WorkerSynchronous APIs
314*61c4878aSAndroid Build Coastguard Worker================
315*61c4878aSAndroid Build Coastguard WorkerThe ``pw_channel`` class may provide synchronous versions of its functions,
316*61c4878aSAndroid Build Coastguard Workerimplementated in terms of the asynchronous API. These will poll the asynchronous
317*61c4878aSAndroid Build Coastguard WorkerAPI until it completes, blocking on a binary semaphore or similar primitive if
318*61c4878aSAndroid Build Coastguard Workersupported. This will leverage a ``pw_async`` helper for this purpose.
319*61c4878aSAndroid Build Coastguard Worker
320*61c4878aSAndroid Build Coastguard WorkerChannel Class Capabilities
321*61c4878aSAndroid Build Coastguard Worker==========================
322*61c4878aSAndroid Build Coastguard Worker``Channel`` s may offer any of five capabilities:
323*61c4878aSAndroid Build Coastguard Worker
324*61c4878aSAndroid Build Coastguard Worker.. list-table::
325*61c4878aSAndroid Build Coastguard Worker   :header-rows: 1
326*61c4878aSAndroid Build Coastguard Worker
327*61c4878aSAndroid Build Coastguard Worker   * - Capability
328*61c4878aSAndroid Build Coastguard Worker     - Description
329*61c4878aSAndroid Build Coastguard Worker   * - ``kReliable``
330*61c4878aSAndroid Build Coastguard Worker     - Data is guaranteed to arrive in order, without loss.
331*61c4878aSAndroid Build Coastguard Worker   * - ``kSeekable``
332*61c4878aSAndroid Build Coastguard Worker     - The read/write position may be changed via the ``Seek`` method.
333*61c4878aSAndroid Build Coastguard Worker   * - ``kDatagram``
334*61c4878aSAndroid Build Coastguard Worker     - Data is guaranteed to be received in whole packets matching the size and
335*61c4878aSAndroid Build Coastguard Worker       contents of a single ``Write`` call.
336*61c4878aSAndroid Build Coastguard Worker   * - ``kReadable``
337*61c4878aSAndroid Build Coastguard Worker     - Supports reading data.
338*61c4878aSAndroid Build Coastguard Worker   * - ``kWritable``
339*61c4878aSAndroid Build Coastguard Worker     - Supports writing data
340*61c4878aSAndroid Build Coastguard Worker
341*61c4878aSAndroid Build Coastguard WorkerThese capabilities are expressed as generic arguments to the ``Channel`` class,
342*61c4878aSAndroid Build Coastguard Workere.g. ``Channel<kReadable | kReliable>`` for a ``Channel`` that is readable and
343*61c4878aSAndroid Build Coastguard Workerreliable. Aliases are provided for common combinations, such as ``ByteStream``
344*61c4878aSAndroid Build Coastguard Workerfor a reliable non-seekable non-datagram stream of bytes (such as a TCP stream).
345*61c4878aSAndroid Build Coastguard WorkerCertain nonsensical combinations, such as a channel that is ``kSeekable`` but
346*61c4878aSAndroid Build Coastguard Workernot ``kReadable`` or ``kWritable`` are disallowed via ``static_assert``.
347*61c4878aSAndroid Build Coastguard Worker
348*61c4878aSAndroid Build Coastguard WorkerConversion
349*61c4878aSAndroid Build Coastguard Worker----------
350*61c4878aSAndroid Build Coastguard WorkerChannels may be freely converted to channels with fewer capabilities, e.g.
351*61c4878aSAndroid Build Coastguard Worker``Channel<kReadable | kWritable>`` may be used as a ``Channel<kReadable>``.
352*61c4878aSAndroid Build Coastguard WorkerThis allows Channels with compatible semantics to be substituted for one another
353*61c4878aSAndroid Build Coastguard Workersafely.
354*61c4878aSAndroid Build Coastguard Worker
355*61c4878aSAndroid Build Coastguard WorkerShared Base Class for Minimal Code Size
356*61c4878aSAndroid Build Coastguard Worker---------------------------------------
357*61c4878aSAndroid Build Coastguard Worker``Channel`` also inherits from an ``AnyChannel`` base class which provides the
358*61c4878aSAndroid Build Coastguard Workerunderlying ``virtual`` interface.  Sharing a single base class avoids multiple
359*61c4878aSAndroid Build Coastguard Workerinheritance, minimizing vtable overhead.
360*61c4878aSAndroid Build Coastguard Worker
361*61c4878aSAndroid Build Coastguard WorkerPrototype Demonstrating Channel Capabilities
362*61c4878aSAndroid Build Coastguard Worker--------------------------------------------
363*61c4878aSAndroid Build Coastguard WorkerA prototype demonstrating this interface can be seen `here
364*61c4878aSAndroid Build Coastguard Worker<https://godbolt.org/z/3c4M3Y17r>`_.
365*61c4878aSAndroid Build Coastguard Worker
366*61c4878aSAndroid Build Coastguard WorkerAPI sketch
367*61c4878aSAndroid Build Coastguard Worker==========
368*61c4878aSAndroid Build Coastguard WorkerAn outline of the ``AnyChannel`` base class follows. ``AnyChannel`` will rarely
369*61c4878aSAndroid Build Coastguard Workerbe used directly, since it makes no guarantees about any channel capabilities or
370*61c4878aSAndroid Build Coastguard Workerthe data type. The function signatures and comments apply to all derived classes,
371*61c4878aSAndroid Build Coastguard Workerhowever.
372*61c4878aSAndroid Build Coastguard Worker
373*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
374*61c4878aSAndroid Build Coastguard Worker
375*61c4878aSAndroid Build Coastguard Worker   namespace pw::channel {
376*61c4878aSAndroid Build Coastguard Worker
377*61c4878aSAndroid Build Coastguard Worker   /// A generic data channel that may support reading or writing bytes.
378*61c4878aSAndroid Build Coastguard Worker   ///
379*61c4878aSAndroid Build Coastguard Worker   /// Note that this channel should be used from only one ``pw::async::Task``
380*61c4878aSAndroid Build Coastguard Worker   /// at a time, as the ``Poll`` methods are only required to remember the
381*61c4878aSAndroid Build Coastguard Worker   /// latest ``pw::async::Context`` that was provided.
382*61c4878aSAndroid Build Coastguard Worker   class AnyChannel {
383*61c4878aSAndroid Build Coastguard Worker    public:
384*61c4878aSAndroid Build Coastguard Worker     // Properties
385*61c4878aSAndroid Build Coastguard Worker     [[nodiscard]] bool reliable() const;
386*61c4878aSAndroid Build Coastguard Worker     [[nodiscard]] DataType data_type() const;
387*61c4878aSAndroid Build Coastguard Worker     [[nodiscard]] bool readable() const;
388*61c4878aSAndroid Build Coastguard Worker     [[nodiscard]] bool writable() const;
389*61c4878aSAndroid Build Coastguard Worker     [[nodiscard]] Seekability seekable() const;
390*61c4878aSAndroid Build Coastguard Worker
391*61c4878aSAndroid Build Coastguard Worker     [[nodiscard]] bool is_open() const;
392*61c4878aSAndroid Build Coastguard Worker
393*61c4878aSAndroid Build Coastguard Worker     // Write API
394*61c4878aSAndroid Build Coastguard Worker
395*61c4878aSAndroid Build Coastguard Worker     // Checks whether a writeable channel is *currently* writeable.
396*61c4878aSAndroid Build Coastguard Worker     //
397*61c4878aSAndroid Build Coastguard Worker     // This should be called before attempting to ``Write``, and may be called
398*61c4878aSAndroid Build Coastguard Worker     // before allocating a write buffer if trying to reduce memory pressure.
399*61c4878aSAndroid Build Coastguard Worker     //
400*61c4878aSAndroid Build Coastguard Worker     // If ``Ready`` is returned, a *single* caller may proceed to ``Write``.
401*61c4878aSAndroid Build Coastguard Worker     //
402*61c4878aSAndroid Build Coastguard Worker     // If ``Pending`` is returned, ``cx`` will be awoken when the channel
403*61c4878aSAndroid Build Coastguard Worker     // becomes writeable again.
404*61c4878aSAndroid Build Coastguard Worker     //
405*61c4878aSAndroid Build Coastguard Worker     // Note: this method will always return ``Ready`` for non-writeable
406*61c4878aSAndroid Build Coastguard Worker     // channels.
407*61c4878aSAndroid Build Coastguard Worker     MaybeReady<> PollWritable(pw::async::Context& cx);
408*61c4878aSAndroid Build Coastguard Worker
409*61c4878aSAndroid Build Coastguard Worker     // Gives access to an allocator for write buffers. The MultiBufAllocator
410*61c4878aSAndroid Build Coastguard Worker     // provides an asynchronous API for obtaining a buffer.
411*61c4878aSAndroid Build Coastguard Worker     //
412*61c4878aSAndroid Build Coastguard Worker     // This allocator must *only* be used to allocate the next argument to
413*61c4878aSAndroid Build Coastguard Worker     // ``Write``. The allocator must be used at most once per call to
414*61c4878aSAndroid Build Coastguard Worker     // ``Write``, and the returned ``MultiBuf`` must not be combined with
415*61c4878aSAndroid Build Coastguard Worker     // any other ``MultiBuf`` s or ``Chunk`` s.
416*61c4878aSAndroid Build Coastguard Worker     //
417*61c4878aSAndroid Build Coastguard Worker     // Write allocation attempts will always return ``std::nullopt`` for
418*61c4878aSAndroid Build Coastguard Worker     // channels that do not support writing.
419*61c4878aSAndroid Build Coastguard Worker     MultiBufAllocator& GetWriteAllocator();
420*61c4878aSAndroid Build Coastguard Worker
421*61c4878aSAndroid Build Coastguard Worker     // Writes using a previously allocated MultiBuf. Returns a token that
422*61c4878aSAndroid Build Coastguard Worker     // refers to this write. These tokens are monotonically increasing, and
423*61c4878aSAndroid Build Coastguard Worker     // FlushPoll() returns the value of the latest token it has flushed.
424*61c4878aSAndroid Build Coastguard Worker     //
425*61c4878aSAndroid Build Coastguard Worker     // The ``MultiBuf`` argument to ``Write`` may consist of either:
426*61c4878aSAndroid Build Coastguard Worker     //   (1) A single ``MultiBuf`` allocated by ``GetWriteAllocator()``
427*61c4878aSAndroid Build Coastguard Worker     //       that has not been combined with any other ``MultiBuf`` s
428*61c4878aSAndroid Build Coastguard Worker     //       or ``Chunk``s OR
429*61c4878aSAndroid Build Coastguard Worker     //   (2) A ``MultiBuf`` containing any combination of buffers from sources
430*61c4878aSAndroid Build Coastguard Worker     //       other than ``GetWriteAllocator``.
431*61c4878aSAndroid Build Coastguard Worker     //
432*61c4878aSAndroid Build Coastguard Worker     // This requirement allows for more efficient use of memory in case (1).
433*61c4878aSAndroid Build Coastguard Worker     // For example, a ring-buffer implementation of a ``Channel`` may
434*61c4878aSAndroid Build Coastguard Worker     // specialize ``GetWriteAllocator`` to return the next section of the
435*61c4878aSAndroid Build Coastguard Worker     // buffer available for writing.
436*61c4878aSAndroid Build Coastguard Worker     //
437*61c4878aSAndroid Build Coastguard Worker     // May fail with the following error codes:
438*61c4878aSAndroid Build Coastguard Worker     //
439*61c4878aSAndroid Build Coastguard Worker     // * OK - Data was accepted by the channel
440*61c4878aSAndroid Build Coastguard Worker     // * UNIMPLEMENTED - The channel does not support writing.
441*61c4878aSAndroid Build Coastguard Worker     // * UNAVAILABLE - The write failed due to a transient error (only applies
442*61c4878aSAndroid Build Coastguard Worker     //   to unreliable channels).
443*61c4878aSAndroid Build Coastguard Worker     // * FAILED_PRECONDITION - The channel is closed.
444*61c4878aSAndroid Build Coastguard Worker     Result<WriteToken> Write(MultiBuf&&);
445*61c4878aSAndroid Build Coastguard Worker
446*61c4878aSAndroid Build Coastguard Worker     // Flushes pending writes.
447*61c4878aSAndroid Build Coastguard Worker     //
448*61c4878aSAndroid Build Coastguard Worker     // Returns a ``MaybeReady`` indicating whether or not flushing has
449*61c4878aSAndroid Build Coastguard Worker     // completed.
450*61c4878aSAndroid Build Coastguard Worker     //
451*61c4878aSAndroid Build Coastguard Worker     // After this call, ``LastFlushed`` may be used to discover which
452*61c4878aSAndroid Build Coastguard Worker     // ``Write`` calls have successfully finished flushing.
453*61c4878aSAndroid Build Coastguard Worker     //
454*61c4878aSAndroid Build Coastguard Worker     // * Ready(OK) - All data has been successfully flushed.
455*61c4878aSAndroid Build Coastguard Worker     // * Ready(UNIMPLEMENTED) - The channel does not support writing.
456*61c4878aSAndroid Build Coastguard Worker     // * Ready(FAILED_PRECONDITION) - The channel is closed.
457*61c4878aSAndroid Build Coastguard Worker     // * Pending - Data remains to be flushed.
458*61c4878aSAndroid Build Coastguard Worker     [[nodiscard]] MaybeReady<pw::Status> PollFlush(async::Context& cx);
459*61c4878aSAndroid Build Coastguard Worker
460*61c4878aSAndroid Build Coastguard Worker     // Returns the latest ```WriteToken``` that was successfully flushed.
461*61c4878aSAndroid Build Coastguard Worker     //
462*61c4878aSAndroid Build Coastguard Worker     // Note that a ``Write`` being flushed does not necessarily mean that the
463*61c4878aSAndroid Build Coastguard Worker     // data was received by the remote. For unreliable channels, flushing may
464*61c4878aSAndroid Build Coastguard Worker     // simply mean that data was written out, not that it was received.
465*61c4878aSAndroid Build Coastguard Worker     [[nodiscard]] WriteToken LastFlushed() const;
466*61c4878aSAndroid Build Coastguard Worker
467*61c4878aSAndroid Build Coastguard Worker     // Read API
468*61c4878aSAndroid Build Coastguard Worker
469*61c4878aSAndroid Build Coastguard Worker     // Returns a MultiBuf read data, if available. If data is not available,
470*61c4878aSAndroid Build Coastguard Worker     // invokes cx.waker() when it becomes available.
471*61c4878aSAndroid Build Coastguard Worker     //
472*61c4878aSAndroid Build Coastguard Worker     // For datagram channels, each successful read yields one complete
473*61c4878aSAndroid Build Coastguard Worker     // datagram. For byte stream channels, each successful read yields some
474*61c4878aSAndroid Build Coastguard Worker     // number of bytes.
475*61c4878aSAndroid Build Coastguard Worker     //
476*61c4878aSAndroid Build Coastguard Worker     // Channels only support one read operation / waker at a time.
477*61c4878aSAndroid Build Coastguard Worker     //
478*61c4878aSAndroid Build Coastguard Worker     // * OK - Data was read into a MultiBuf.
479*61c4878aSAndroid Build Coastguard Worker     // * UNIMPLEMENTED - The channel does not support reading.
480*61c4878aSAndroid Build Coastguard Worker     // * FAILED_PRECONDITION - The channel is closed.
481*61c4878aSAndroid Build Coastguard Worker     // * OUT_OF_RANGE - The end of the stream was reached. This may be though
482*61c4878aSAndroid Build Coastguard Worker     //   of as reaching the end of a file. Future reads may succeed after
483*61c4878aSAndroid Build Coastguard Worker     //   ``Seek`` ing backwards, but no more new data will be produced. The
484*61c4878aSAndroid Build Coastguard Worker     //   channel is still open; writes and seeks may succeed.
485*61c4878aSAndroid Build Coastguard Worker     MaybeReady<Result<MultiBuf>> PollRead(async::Context& cx);
486*61c4878aSAndroid Build Coastguard Worker
487*61c4878aSAndroid Build Coastguard Worker     // On byte stream channels, reads up to max_bytes from the channel.
488*61c4878aSAndroid Build Coastguard Worker     // This function is hidden on datagram-oriented channels.
489*61c4878aSAndroid Build Coastguard Worker     MaybeReady<Result<MultiBuf>> PollRead(async::Context& cx, size_t max_bytes);
490*61c4878aSAndroid Build Coastguard Worker
491*61c4878aSAndroid Build Coastguard Worker     // Changes the position in the stream.
492*61c4878aSAndroid Build Coastguard Worker     //
493*61c4878aSAndroid Build Coastguard Worker     // Any ``PollRead`` or ``Write`` calls following a call to ``Seek`` will be
494*61c4878aSAndroid Build Coastguard Worker     // relative to the new position. Already-written data still being flushed
495*61c4878aSAndroid Build Coastguard Worker     // will be output relative to the old position.
496*61c4878aSAndroid Build Coastguard Worker     //
497*61c4878aSAndroid Build Coastguard Worker     // * OK - The current position was successfully changed.
498*61c4878aSAndroid Build Coastguard Worker     // * UNIMPLEMENTED - The channel does not support seeking.
499*61c4878aSAndroid Build Coastguard Worker     // * FAILED_PRECONDITION - The channel is closed.
500*61c4878aSAndroid Build Coastguard Worker     // * NOT_FOUND - The seek was to a valid position, but the channel is no
501*61c4878aSAndroid Build Coastguard Worker     //   longer capable of seeking to this position (partially seekable
502*61c4878aSAndroid Build Coastguard Worker     //   channels only).
503*61c4878aSAndroid Build Coastguard Worker     // * OUT_OF_RANGE - The seek went beyond the end of the stream.
504*61c4878aSAndroid Build Coastguard Worker     Status Seek(ptrdiff_t position, Whence whence);
505*61c4878aSAndroid Build Coastguard Worker
506*61c4878aSAndroid Build Coastguard Worker     // Returns the current position in the stream, or kUnknownPosition if
507*61c4878aSAndroid Build Coastguard Worker     // unsupported.
508*61c4878aSAndroid Build Coastguard Worker     size_t Position() const;
509*61c4878aSAndroid Build Coastguard Worker
510*61c4878aSAndroid Build Coastguard Worker     // Closes the channel, flushing any data.
511*61c4878aSAndroid Build Coastguard Worker     //
512*61c4878aSAndroid Build Coastguard Worker     // * OK - The channel was closed and all data was sent successfully.
513*61c4878aSAndroid Build Coastguard Worker     // * DATA_LOSS - The channel was closed, but not all previously written
514*61c4878aSAndroid Build Coastguard Worker     //   data was delivered.
515*61c4878aSAndroid Build Coastguard Worker     // * FAILED_PRECONDITION - Channel was already closed, which can happen
516*61c4878aSAndroid Build Coastguard Worker     //   out-of-band due to errors.
517*61c4878aSAndroid Build Coastguard Worker     MaybeReady<pw::Status> PollClose(async::Context& cx);
518*61c4878aSAndroid Build Coastguard Worker
519*61c4878aSAndroid Build Coastguard Worker    private:
520*61c4878aSAndroid Build Coastguard Worker     virtual bool do_reliable() const;
521*61c4878aSAndroid Build Coastguard Worker     virtual DataType do_data_type() const;
522*61c4878aSAndroid Build Coastguard Worker     virtual bool do_readable() const;
523*61c4878aSAndroid Build Coastguard Worker     virtual bool do_writable() const;
524*61c4878aSAndroid Build Coastguard Worker     virtual Seekability do_seekable() const;
525*61c4878aSAndroid Build Coastguard Worker     virtual bool do_is_open() const;
526*61c4878aSAndroid Build Coastguard Worker
527*61c4878aSAndroid Build Coastguard Worker     // Virtual interface.
528*61c4878aSAndroid Build Coastguard Worker     virtual MultiBufAllocator& DoGetWriteBufferAllocator() = 0;
529*61c4878aSAndroid Build Coastguard Worker
530*61c4878aSAndroid Build Coastguard Worker     virtual MaybeReady<> PollWritable(async::Context& cx) = 0;
531*61c4878aSAndroid Build Coastguard Worker
532*61c4878aSAndroid Build Coastguard Worker     virtual Result<WriteToken> DoWrite(MultiBuf&& buffer) = 0;
533*61c4878aSAndroid Build Coastguard Worker
534*61c4878aSAndroid Build Coastguard Worker     virtual WriteToken DoPollFlush(async::Context& cx) = 0;
535*61c4878aSAndroid Build Coastguard Worker
536*61c4878aSAndroid Build Coastguard Worker     [[nodiscard]] WriteToken LastFlushed() const = 0;
537*61c4878aSAndroid Build Coastguard Worker
538*61c4878aSAndroid Build Coastguard Worker     // The max_bytes argument is ignored for datagram-oriented channels.
539*61c4878aSAndroid Build Coastguard Worker     virtual MaybeReady<Result<MultiBuf>> DoReadPoll(
540*61c4878aSAndroid Build Coastguard Worker         async::Context& cx, size_t max_bytes) = 0;
541*61c4878aSAndroid Build Coastguard Worker
542*61c4878aSAndroid Build Coastguard Worker     virtual DoSeek(ptrdiff_t position, Whence whence) = 0;
543*61c4878aSAndroid Build Coastguard Worker
544*61c4878aSAndroid Build Coastguard Worker     virtual size_t DoPosition() const { return kUnknownPosition; }
545*61c4878aSAndroid Build Coastguard Worker
546*61c4878aSAndroid Build Coastguard Worker     virtual async::MaybeReady<Status> DoClosePoll(async::Context& cx);
547*61c4878aSAndroid Build Coastguard Worker   };
548*61c4878aSAndroid Build Coastguard Worker   }  // namespace pw::channel
549*61c4878aSAndroid Build Coastguard Worker
550*61c4878aSAndroid Build Coastguard Workerpw_channel and pw_stream
551*61c4878aSAndroid Build Coastguard Worker========================
552*61c4878aSAndroid Build Coastguard WorkerAs described, ``pw_channel`` is closely based on ``pw_stream``. It adds async,
553*61c4878aSAndroid Build Coastguard Worker``MultiBuf``, and new socket-inspired semantics.
554*61c4878aSAndroid Build Coastguard Worker
555*61c4878aSAndroid Build Coastguard Worker``pw_channel`` is intended to supersede ``pw_stream``. There are a few options
556*61c4878aSAndroid Build Coastguard Workerfor how to reconcile the two modules. From most to least ideal, these are:
557*61c4878aSAndroid Build Coastguard Worker
558*61c4878aSAndroid Build Coastguard Worker- Fully replace ``pw_stream`` with ``pw_channel`` and remove the ``pw_stream``
559*61c4878aSAndroid Build Coastguard Worker  module.
560*61c4878aSAndroid Build Coastguard Worker- Rework ``pw_stream`` so it inherits from ``pw::channel::Channel``.
561*61c4878aSAndroid Build Coastguard Worker- Keep ``pw_stream``, but provide adapters to convert between ``pw_stream`` and
562*61c4878aSAndroid Build Coastguard Worker  ``pw_channel``.
563*61c4878aSAndroid Build Coastguard Worker
564*61c4878aSAndroid Build Coastguard WorkerFully replacing ``pw_stream`` with ``pw_channel`` could be complicated due to:
565*61c4878aSAndroid Build Coastguard Worker
566*61c4878aSAndroid Build Coastguard Worker- Potential code size increase because of ``MultiBuf`` and the async poll model.
567*61c4878aSAndroid Build Coastguard Worker- The scale of migrating the all Pigweed users off of ``pw_stream``.
568*61c4878aSAndroid Build Coastguard Worker- Increased API complexity imposing a burden on Pigweed users.
569