fidl_next_protocol/
transport.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use core::error::Error;
6use core::pin::Pin;
7use core::task::{Context, Poll};
8
9use fidl_next_codec::{Decoder, Encoder};
10
11/// A transport layer which can send and receive messages.
12///
13/// The futures provided by this trait should be cancel-safe, which constrains
14/// their behavior:
15///
16/// - Operations should not partially complete.
17/// - Operations should only complete during polling.
18///
19/// `SendFuture` should return `Poll::Ready` with an error when polled after the
20/// transport is closed.
21pub trait Transport {
22    /// The error type for the transport.
23    type Error: Clone + Error + Send + Sync + 'static;
24
25    /// Splits the transport into shared and exclusive pieces.
26    fn split(self) -> (Self::Shared, Self::Exclusive);
27
28    /// The shared part of the transport. It is provided by shared reference
29    /// while sending and receiving. For an MPSC, this would contain a sender.
30    type Shared: Send + Sync;
31    /// The exclusive part of the transport. It is provided by mutable reference
32    /// only while receiving. For an MPSC, this would contain a receiver.
33    type Exclusive: Send;
34
35    /// The buffer type for sending.
36    type SendBuffer: Encoder + Send;
37    /// The future state for send operations.
38    type SendFutureState: Send;
39
40    /// Acquires an empty send buffer for the transport.
41    fn acquire(shared: &Self::Shared) -> Self::SendBuffer;
42
43    /// Begins sending a `SendBuffer` over this transport.
44    ///
45    /// Returns the state for a future which can be polled with `poll_send`.
46    fn begin_send(shared: &Self::Shared, buffer: Self::SendBuffer) -> Self::SendFutureState;
47
48    /// Polls a `SendFutureState` for completion with the shared part of the
49    /// transport.
50    ///
51    /// When ready, polling returns one of three values:
52    /// - `Ok(())` if the buffer was successfully sent.
53    /// - `Err(None)` if the connection was terminated normally (e.g. with
54    ///   `PEER_CLOSED`).
55    /// - `Err(Some(error))` if the connection was terminated abnormally.
56    fn poll_send(
57        future: Pin<&mut Self::SendFutureState>,
58        cx: &mut Context<'_>,
59        shared: &Self::Shared,
60    ) -> Poll<Result<(), Option<Self::Error>>>;
61
62    /// The future state for receive operations.
63    type RecvFutureState: Send;
64    /// The buffer type for receivers.
65    type RecvBuffer: Decoder + Send;
66
67    /// Begins receiving a `RecvBuffer` over this transport.
68    ///
69    /// Returns the state for a future which can be polled with `poll_recv`.
70    fn begin_recv(shared: &Self::Shared, exclusive: &mut Self::Exclusive) -> Self::RecvFutureState;
71
72    /// Polls a `RecvFutureState` for completion with a receiver.
73    ///
74    /// When ready, polling returns one of three values:
75    /// - `Ok(buffer)` if `buffer` was successfully received.
76    /// - `Err(None)` if the connection was terminated normally (e.g. with
77    ///   `PEER_CLOSED`).
78    /// - `Err(Some(error))` if the connection was terminated abnormally.
79    fn poll_recv(
80        future: Pin<&mut Self::RecvFutureState>,
81        cx: &mut Context<'_>,
82        shared: &Self::Shared,
83        exclusive: &mut Self::Exclusive,
84    ) -> Poll<Result<Self::RecvBuffer, Option<Self::Error>>>;
85}
86
87/// A transport layer which can send messages without blocking.
88///
89/// Because failed sends return immediately without waiting for an epitaph to be
90/// read, `send_immediately` may observe transport closure prematurely.
91///
92/// Non-blocking send operations cannot apply backpressure, which can cause
93/// memory exhaustion across the system. `NonBlockingTransport` is intended for
94/// use only while porting existing code.
95pub trait NonBlockingTransport: Transport {
96    /// Completes a `SendFutureState` with the shared part of the transport
97    /// without blocking.
98    fn send_immediately(
99        future_state: &mut Self::SendFutureState,
100        shared: &Self::Shared,
101    ) -> Result<(), Option<Self::Error>>;
102}