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