Skip to content

Commit 6df3594

Browse files
djkoloskiCQ Bot
authored andcommitted
[fidl][rust] Remove GATs from Transport trait
We ran into several edge cases with the trait solver when using GATs. By separating the lifetime-dependent code out into a separate future, we can avoid using GATs altogether. Change-Id: I45832054c84d12107bf867e2db3f3140a0a04093 Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/1219444 Reviewed-by: Ian McKellar <[email protected]> Fuchsia-Auto-Submit: David Koloski <[email protected]> Commit-Queue: David Koloski <[email protected]>
1 parent d2c2074 commit 6df3594

24 files changed

+464
-432
lines changed

src/lib/fidl/rust_next/fidl_next/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323

2424
pub use ::fidl_next_bind::*;
2525
pub use ::fidl_next_codec::*;
26-
pub use ::fidl_next_protocol::{self as protocol, ProtocolError, Transport};
26+
pub use ::fidl_next_protocol::{
27+
self as protocol, ProtocolError, RecvFuture, SendFuture, Transport,
28+
};
2729

2830
/// Fuchsia-specific FIDL extensions.
2931
#[cfg(target_os = "fuchsia")]

src/lib/fidl/rust_next/fidl_next_bind/src/server.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use core::marker::PhantomData;
66

77
use fidl_next_codec::{Encode, EncodeError};
8-
use fidl_next_protocol::{self as protocol, ProtocolError, Transport};
8+
use fidl_next_protocol::{self as protocol, ProtocolError, SendFuture, Transport};
99

1010
use super::{Method, ServerEnd};
1111

@@ -167,7 +167,7 @@ impl<M> Responder<M> {
167167
self,
168168
server: &'s ServerSender<T, P>,
169169
response: &mut R,
170-
) -> Result<T::SendFuture<'s>, EncodeError>
170+
) -> Result<SendFuture<'s, T>, EncodeError>
171171
where
172172
T: Transport,
173173
M: Method<Protocol = P>,

src/lib/fidl/rust_next/fidl_next_protocol/src/client.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::sync::{Arc, Mutex};
1212
use fidl_next_codec::{Encode, EncodeError, EncoderExt};
1313

1414
use crate::lockers::Lockers;
15-
use crate::{decode_header, encode_header, ProtocolError, Transport};
15+
use crate::{decode_header, encode_header, ProtocolError, SendFuture, Transport, TransportExt};
1616

1717
use super::lockers::LockerError;
1818

@@ -43,7 +43,7 @@ impl<T: Transport> ClientSender<T> {
4343
&self,
4444
ordinal: u64,
4545
request: &mut M,
46-
) -> Result<T::SendFuture<'_>, EncodeError>
46+
) -> Result<SendFuture<'_, T>, EncodeError>
4747
where
4848
M: Encode<T::SendBuffer>,
4949
{
@@ -80,7 +80,7 @@ impl<T: Transport> ClientSender<T> {
8080
txid: u32,
8181
ordinal: u64,
8282
message: &mut M,
83-
) -> Result<T::SendFuture<'_>, EncodeError>
83+
) -> Result<SendFuture<'_, T>, EncodeError>
8484
where
8585
M: Encode<T::SendBuffer>,
8686
{
@@ -97,8 +97,8 @@ impl<T: Transport> Clone for ClientSender<T> {
9797
}
9898
}
9999

100-
enum ResponseFutureState<'a, T: 'a + Transport> {
101-
Sending(T::SendFuture<'a>),
100+
enum ResponseFutureState<'a, T: Transport> {
101+
Sending(SendFuture<'a, T>),
102102
Receiving,
103103
// We store the completion state locally so that we can free the locker during poll, instead of
104104
// waiting until the future is dropped.

src/lib/fidl/rust_next/fidl_next_protocol/src/fuchsia/channel.rs

Lines changed: 93 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
//! A transport implementation which uses Zircon channels.
66
7-
use core::future::Future;
87
use core::mem::replace;
98
use core::pin::Pin;
109
use core::ptr::NonNull;
@@ -123,111 +122,21 @@ impl HandleEncoder for Buffer {
123122
}
124123
}
125124

126-
/// A channel send future.
127-
#[must_use = "futures do nothing unless polled"]
128-
pub struct SendFuture<'s> {
129-
shared: &'s Shared,
125+
/// The state for a channel send future.
126+
pub struct SendFutureState {
130127
buffer: Buffer,
131128
}
132129

133-
impl Future for SendFuture<'_> {
134-
type Output = Result<(), Status>;
135-
136-
fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
137-
let this = Pin::into_inner(self);
138-
139-
let result = unsafe {
140-
zx_channel_write(
141-
this.shared.channel.get_ref().raw_handle(),
142-
0,
143-
this.buffer.chunks.as_ptr().cast::<u8>(),
144-
(this.buffer.chunks.len() * CHUNK_SIZE) as u32,
145-
this.buffer.handles.as_ptr().cast(),
146-
this.buffer.handles.len() as u32,
147-
)
148-
};
149-
150-
if result == ZX_OK {
151-
// Handles were written to the channel, so we must not drop them.
152-
unsafe {
153-
this.buffer.handles.set_len(0);
154-
}
155-
Poll::Ready(Ok(()))
156-
} else {
157-
Poll::Ready(Err(Status::from_raw(result)))
158-
}
159-
}
160-
}
161-
162130
/// A channel receiver.
163131
pub struct Receiver {
164132
shared: Arc<Shared>,
165133
}
166134

167-
/// A channel receive future.
168-
#[must_use = "futures do nothing unless polled"]
169-
pub struct RecvFuture<'r> {
170-
shared: &'r Shared,
135+
/// The state for a channel receive future.
136+
pub struct RecvFutureState {
171137
buffer: Option<Buffer>,
172138
}
173139

174-
impl Future for RecvFuture<'_> {
175-
type Output = Result<Option<RecvBuffer>, Status>;
176-
177-
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
178-
let this = Pin::into_inner(self);
179-
let buffer = this.buffer.as_mut().unwrap();
180-
181-
let mut actual_bytes = 0;
182-
let mut actual_handles = 0;
183-
184-
loop {
185-
let result = unsafe {
186-
zx_channel_read(
187-
this.shared.channel.get_ref().raw_handle(),
188-
0,
189-
buffer.chunks.as_mut_ptr().cast(),
190-
buffer.handles.as_mut_ptr().cast(),
191-
(buffer.chunks.capacity() * CHUNK_SIZE) as u32,
192-
buffer.handles.capacity() as u32,
193-
&mut actual_bytes,
194-
&mut actual_handles,
195-
)
196-
};
197-
198-
match result {
199-
ZX_OK => {
200-
unsafe {
201-
buffer.chunks.set_len(actual_bytes as usize / CHUNK_SIZE);
202-
buffer.handles.set_len(actual_handles as usize);
203-
}
204-
return Poll::Ready(Ok(Some(RecvBuffer {
205-
buffer: this.buffer.take().unwrap(),
206-
chunks_taken: 0,
207-
handles_taken: 0,
208-
})));
209-
}
210-
ZX_ERR_PEER_CLOSED => return Poll::Ready(Ok(None)),
211-
ZX_ERR_BUFFER_TOO_SMALL => {
212-
let min_chunks = (actual_bytes as usize).div_ceil(CHUNK_SIZE);
213-
buffer.chunks.reserve(min_chunks - buffer.chunks.capacity());
214-
buffer.handles.reserve(actual_handles as usize - buffer.handles.capacity());
215-
}
216-
ZX_ERR_SHOULD_WAIT => {
217-
if matches!(this.shared.channel.need_readable(cx)?, Poll::Pending) {
218-
this.shared.closed_waker.register(cx.waker());
219-
if this.shared.is_closed.load(Ordering::Relaxed) {
220-
return Poll::Ready(Ok(None));
221-
}
222-
return Poll::Pending;
223-
}
224-
}
225-
raw => return Poll::Ready(Err(Status::from_raw(raw))),
226-
}
227-
}
228-
}
229-
}
230-
231140
/// A channel receive buffer.
232141
pub struct RecvBuffer {
233142
buffer: Buffer,
@@ -311,26 +220,109 @@ impl Transport for Channel {
311220

312221
type Sender = Sender;
313222
type SendBuffer = Buffer;
314-
type SendFuture<'s> = SendFuture<'s>;
223+
type SendFutureState = SendFutureState;
315224

316225
fn acquire(_: &Self::Sender) -> Self::SendBuffer {
317226
Buffer::new()
318227
}
319228

320-
fn send(sender: &Self::Sender, buffer: Self::SendBuffer) -> Self::SendFuture<'_> {
321-
SendFuture { shared: &sender.shared, buffer }
229+
fn begin_send(_: &Self::Sender, buffer: Self::SendBuffer) -> Self::SendFutureState {
230+
SendFutureState { buffer }
231+
}
232+
233+
fn poll_send(
234+
mut future_state: Pin<&mut Self::SendFutureState>,
235+
_: &mut Context<'_>,
236+
sender: &Self::Sender,
237+
) -> Poll<Result<(), Self::Error>> {
238+
let result = unsafe {
239+
zx_channel_write(
240+
sender.shared.channel.get_ref().raw_handle(),
241+
0,
242+
future_state.buffer.chunks.as_ptr().cast::<u8>(),
243+
(future_state.buffer.chunks.len() * CHUNK_SIZE) as u32,
244+
future_state.buffer.handles.as_ptr().cast(),
245+
future_state.buffer.handles.len() as u32,
246+
)
247+
};
248+
249+
if result == ZX_OK {
250+
// Handles were written to the channel, so we must not drop them.
251+
unsafe {
252+
future_state.buffer.handles.set_len(0);
253+
}
254+
Poll::Ready(Ok(()))
255+
} else {
256+
Poll::Ready(Err(Status::from_raw(result)))
257+
}
322258
}
323259

324260
fn close(sender: &Self::Sender) {
325261
sender.shared.close();
326262
}
327263

328264
type Receiver = Receiver;
329-
type RecvFuture<'r> = RecvFuture<'r>;
265+
type RecvFutureState = RecvFutureState;
330266
type RecvBuffer = RecvBuffer;
331267

332-
fn recv(receiver: &mut Self::Receiver) -> Self::RecvFuture<'_> {
333-
RecvFuture { shared: &receiver.shared, buffer: Some(Buffer::new()) }
268+
fn begin_recv(_: &mut Self::Receiver) -> Self::RecvFutureState {
269+
RecvFutureState { buffer: Some(Buffer::new()) }
270+
}
271+
272+
fn poll_recv(
273+
mut future_state: Pin<&mut Self::RecvFutureState>,
274+
cx: &mut Context<'_>,
275+
receiver: &mut Self::Receiver,
276+
) -> Poll<Result<Option<Self::RecvBuffer>, Self::Error>> {
277+
let buffer = future_state.buffer.as_mut().unwrap();
278+
279+
let mut actual_bytes = 0;
280+
let mut actual_handles = 0;
281+
282+
loop {
283+
let result = unsafe {
284+
zx_channel_read(
285+
receiver.shared.channel.get_ref().raw_handle(),
286+
0,
287+
buffer.chunks.as_mut_ptr().cast(),
288+
buffer.handles.as_mut_ptr().cast(),
289+
(buffer.chunks.capacity() * CHUNK_SIZE) as u32,
290+
buffer.handles.capacity() as u32,
291+
&mut actual_bytes,
292+
&mut actual_handles,
293+
)
294+
};
295+
296+
match result {
297+
ZX_OK => {
298+
unsafe {
299+
buffer.chunks.set_len(actual_bytes as usize / CHUNK_SIZE);
300+
buffer.handles.set_len(actual_handles as usize);
301+
}
302+
return Poll::Ready(Ok(Some(RecvBuffer {
303+
buffer: future_state.buffer.take().unwrap(),
304+
chunks_taken: 0,
305+
handles_taken: 0,
306+
})));
307+
}
308+
ZX_ERR_PEER_CLOSED => return Poll::Ready(Ok(None)),
309+
ZX_ERR_BUFFER_TOO_SMALL => {
310+
let min_chunks = (actual_bytes as usize).div_ceil(CHUNK_SIZE);
311+
buffer.chunks.reserve(min_chunks - buffer.chunks.capacity());
312+
buffer.handles.reserve(actual_handles as usize - buffer.handles.capacity());
313+
}
314+
ZX_ERR_SHOULD_WAIT => {
315+
if matches!(receiver.shared.channel.need_readable(cx)?, Poll::Pending) {
316+
receiver.shared.closed_waker.register(cx.waker());
317+
if receiver.shared.is_closed.load(Ordering::Relaxed) {
318+
return Poll::Ready(Ok(None));
319+
}
320+
return Poll::Pending;
321+
}
322+
}
323+
raw => return Poll::Ready(Err(Status::from_raw(raw))),
324+
}
325+
}
334326
}
335327
}
336328

0 commit comments

Comments
 (0)