1use fidl_fuchsia_fdomain as proto;
6use fidl_message::TransactionHeader;
7use fuchsia_sync::Mutex;
8use futures::FutureExt;
9use futures::channel::oneshot::Sender as OneshotSender;
10use futures::stream::Stream as StreamTrait;
11use std::collections::{HashMap, HashSet, VecDeque};
12use std::convert::Infallible;
13use std::future::Future;
14use std::num::NonZeroU32;
15use std::pin::Pin;
16use std::sync::{Arc, LazyLock, Weak};
17use std::task::{Context, Poll, Waker, ready};
18
19mod channel;
20mod event;
21mod event_pair;
22mod handle;
23mod responder;
24mod socket;
25mod vmo;
26
27#[cfg(test)]
28mod test;
29
30pub mod fidl;
31pub mod fidl_next;
32
33use responder::Responder;
34
35pub use channel::{
36 AnyHandle, Channel, ChannelMessageStream, ChannelWriter, HandleInfo, HandleOp, MessageBuf,
37};
38pub use event::Event;
39pub use event_pair::Eventpair as EventPair;
40pub use handle::unowned::Unowned;
41pub use handle::{
42 AsHandleRef, Handle, HandleBased, HandleRef, NullableHandle, OnFDomainSignals, Peered,
43};
44pub use proto::{Error as FDomainError, VmoOptions, WriteChannelError, WriteSocketError};
45pub use socket::{Socket, SocketDisposition, SocketReadStream, SocketWriter};
46pub use vmo::Vmo;
47
48#[rustfmt::skip]
50pub use Handle as Clock;
51#[rustfmt::skip]
52pub use Handle as Exception;
53#[rustfmt::skip]
54pub use Handle as Fifo;
55#[rustfmt::skip]
56pub use Handle as Iob;
57#[rustfmt::skip]
58pub use Handle as Job;
59#[rustfmt::skip]
60pub use Handle as Process;
61#[rustfmt::skip]
62pub use Handle as Resource;
63#[rustfmt::skip]
64pub use Handle as Stream;
65#[rustfmt::skip]
66pub use Handle as Thread;
67#[rustfmt::skip]
68pub use Handle as Vmar;
69#[rustfmt::skip]
70pub use Handle as Counter;
71#[rustfmt::skip]
72pub use Handle as Port;
73
74use proto::f_domain_ordinals as ordinals;
75
76fn write_fdomain_error(error: &FDomainError, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77 match error {
78 FDomainError::TargetError(e) => {
79 let e = zx_status::Status::err_from_raw(*e);
80 write!(f, "Target-side error {e}")
81 }
82 FDomainError::BadHandleId(proto::BadHandleId { id }) => {
83 write!(f, "Tried to use invalid handle id {id}")
84 }
85 FDomainError::WrongHandleType(proto::WrongHandleType { expected, got }) => write!(
86 f,
87 "Tried to use handle as {expected:?} but target reported handle was of type {got:?}"
88 ),
89 FDomainError::StreamingReadInProgress(proto::StreamingReadInProgress {}) => {
90 write!(f, "Handle is occupied delivering streaming reads")
91 }
92 FDomainError::NoReadInProgress(proto::NoReadInProgress {}) => {
93 write!(f, "No streaming read was in progress")
94 }
95 FDomainError::NewHandleIdOutOfRange(proto::NewHandleIdOutOfRange { id }) => {
96 write!(
97 f,
98 "Tried to create a handle with id {id}, which is outside the valid range for client handles"
99 )
100 }
101 FDomainError::NewHandleIdReused(proto::NewHandleIdReused { id, same_call }) => {
102 if *same_call {
103 write!(f, "Tried to create two or more new handles with the same id {id}")
104 } else {
105 write!(
106 f,
107 "Tried to create a new handle with id {id}, which is already the id of an existing handle"
108 )
109 }
110 }
111 FDomainError::WroteToSelf(proto::WroteToSelf {}) => {
112 write!(f, "Tried to write a channel into itself")
113 }
114 FDomainError::ClosedDuringRead(proto::ClosedDuringRead {}) => {
115 write!(f, "Handle closed while being read")
116 }
117 FDomainError::SignalsUnknown(signals_unknown) => {
118 write!(f, "Unknown signals: {:x}", signals_unknown.signals)
119 }
120 FDomainError::RightsUnknown(rights_unknown) => {
121 write!(f, "Unknown rights: {:x}", rights_unknown.rights)
122 }
123 FDomainError::SocketDispositionUnknown(socket_disposition_unknown) => {
124 write!(f, "Unknown socket disposition: {:?}", socket_disposition_unknown.disposition)
125 }
126 FDomainError::SocketTypeUnknown(socket_type_unknown) => {
127 write!(f, "Unknown socket type: {:?}", socket_type_unknown.type_)
128 }
129 e => write!(f, "Unknown FDomain error: {e:?}"),
130 }
131}
132
133pub type Result<T, E = Error> = std::result::Result<T, E>;
135
136#[derive(Clone)]
138pub enum Error {
139 SocketWrite(WriteSocketError),
140 ChannelWrite(WriteChannelError),
141 FDomain(FDomainError),
142 Protocol(::fidl::Error),
143 ProtocolObjectTypeIncompatible,
144 ProtocolRightsIncompatible,
145 ProtocolSignalsIncompatible,
146 ProtocolStreamEventIncompatible,
147 Transport(Option<Arc<std::io::Error>>),
148 ConnectionMismatch,
149 StreamingAborted,
150}
151
152impl std::fmt::Display for Error {
153 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
154 match self {
155 Self::SocketWrite(proto::WriteSocketError { error, wrote }) => {
156 write!(f, "While writing socket (after {wrote} bytes written successfully): ")?;
157 write_fdomain_error(error, f)
158 }
159 Self::ChannelWrite(proto::WriteChannelError::Error(error)) => {
160 write!(f, "While writing channel: ")?;
161 write_fdomain_error(error, f)
162 }
163 Self::ChannelWrite(proto::WriteChannelError::OpErrors(errors)) => {
164 write!(f, "Couldn't write all handles into a channel:")?;
165 for (pos, error) in
166 errors.iter().enumerate().filter_map(|(num, x)| x.as_ref().map(|y| (num, &**y)))
167 {
168 write!(f, "\n Handle in position {pos}: ")?;
169 write_fdomain_error(error, f)?;
170 }
171 Ok(())
172 }
173 Self::ProtocolObjectTypeIncompatible => {
174 write!(
175 f,
176 "The FDomain protocol received an unrecognized or incompatible object type"
177 )
178 }
179 Self::ProtocolRightsIncompatible => {
180 write!(
181 f,
182 "The FDomain protocol received unrecognized or incompatible handle rights"
183 )
184 }
185 Self::ProtocolSignalsIncompatible => {
186 write!(f, "The FDomain protocol received unrecognized or incompatible signals")
187 }
188 Self::ProtocolStreamEventIncompatible => {
189 write!(
190 f,
191 "The FDomain protocol received an unrecognized or incompatible streaming IO event"
192 )
193 }
194 Self::FDomain(e) => write_fdomain_error(e, f),
195 Self::Protocol(e) => write!(f, "Protocol error: {e}"),
196 Self::Transport(Some(e)) => write!(f, "Transport error: {e}"),
197 Self::Transport(None) => {
198 write!(f, "Transport error: Connection to the device has been lost")
199 }
200 Self::ConnectionMismatch => {
201 write!(
202 f,
203 "Tried to use an FDomain handle with a different connection than the one it was created on"
204 )
205 }
206 Self::StreamingAborted => write!(f, "Streaming on this channel has been aborted"),
207 }
208 }
209}
210
211impl std::fmt::Debug for Error {
212 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
213 match self {
214 Self::SocketWrite(e) => f.debug_tuple("SocketWrite").field(e).finish(),
215 Self::ChannelWrite(e) => f.debug_tuple("ChannelWrite").field(e).finish(),
216 Self::FDomain(e) => f.debug_tuple("FDomain").field(e).finish(),
217 Self::Protocol(e) => f.debug_tuple("Protocol").field(e).finish(),
218 Self::Transport(e) => f.debug_tuple("Transport").field(e).finish(),
219 Self::ProtocolObjectTypeIncompatible => write!(f, "ProtocolObjectTypeIncompatible "),
220 Self::ProtocolRightsIncompatible => write!(f, "ProtocolRightsIncompatible "),
221 Self::ProtocolSignalsIncompatible => write!(f, "ProtocolSignalsIncompatible "),
222 Self::ProtocolStreamEventIncompatible => write!(f, "ProtocolStreamEventIncompatible"),
223 Self::ConnectionMismatch => write!(f, "ConnectionMismatch"),
224 Self::StreamingAborted => write!(f, "StreamingAborted"),
225 }
226 }
227}
228
229impl std::error::Error for Error {}
230
231impl From<FDomainError> for Error {
232 fn from(other: FDomainError) -> Self {
233 Self::FDomain(other)
234 }
235}
236
237impl From<::fidl::Error> for Error {
238 fn from(other: ::fidl::Error) -> Self {
239 Self::Protocol(other)
240 }
241}
242
243impl From<WriteSocketError> for Error {
244 fn from(other: WriteSocketError) -> Self {
245 Self::SocketWrite(other)
246 }
247}
248
249impl From<WriteChannelError> for Error {
250 fn from(other: WriteChannelError) -> Self {
251 Self::ChannelWrite(other)
252 }
253}
254
255#[derive(Clone)]
259enum InnerError {
260 Protocol(::fidl::Error),
261 ProtocolStreamEventIncompatible,
262 Transport(Option<Arc<std::io::Error>>),
263}
264
265impl From<InnerError> for Error {
266 fn from(other: InnerError) -> Self {
267 match other {
268 InnerError::Protocol(p) => Error::Protocol(p),
269 InnerError::ProtocolStreamEventIncompatible => Error::ProtocolStreamEventIncompatible,
270 InnerError::Transport(t) => Error::Transport(t),
271 }
272 }
273}
274
275impl From<::fidl::Error> for InnerError {
276 fn from(other: ::fidl::Error) -> Self {
277 InnerError::Protocol(other)
278 }
279}
280
281pub trait FDomainTransport: StreamTrait<Item = Result<Box<[u8]>, std::io::Error>> + Send {
291 fn poll_send_message(
294 self: Pin<&mut Self>,
295 msg: &[u8],
296 ctx: &mut Context<'_>,
297 ) -> Poll<Result<(), Option<std::io::Error>>>;
298
299 fn debug_fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
301 Ok(())
302 }
303
304 fn has_debug_fmt(&self) -> bool {
306 false
307 }
308}
309
310enum Transport {
316 Transport(Pin<Box<dyn FDomainTransport>>, VecDeque<Box<[u8]>>, Vec<Waker>),
317 Error(InnerError),
318}
319
320impl Transport {
321 fn error(&self) -> Option<InnerError> {
323 match self {
324 Transport::Transport(_, _, _) => None,
325 Transport::Error(inner_error) => Some(inner_error.clone()),
326 }
327 }
328
329 fn push_msg(&mut self, msg: Box<[u8]>) -> Result<(), InnerError> {
331 match self {
332 Transport::Transport(_, v, w) => {
333 v.push_back(msg);
334 w.drain(..).for_each(Waker::wake);
335 Ok(())
336 }
337 Transport::Error(e) => Err(e.clone()),
338 }
339 }
340
341 fn poll_send_messages(&mut self, ctx: &mut Context<'_>) -> Poll<InnerError> {
343 match self {
344 Transport::Error(e) => Poll::Ready(e.clone()),
345 Transport::Transport(t, v, w) => {
346 while let Some(msg) = v.front() {
347 match t.as_mut().poll_send_message(msg, ctx) {
348 Poll::Ready(Ok(())) => {
349 v.pop_front();
350 }
351 Poll::Ready(Err(e)) => {
352 let e = e.map(Arc::new);
353 return Poll::Ready(InnerError::Transport(e));
354 }
355 Poll::Pending => return Poll::Pending,
356 }
357 }
358
359 if v.is_empty() {
360 w.push(ctx.waker().clone());
361 } else {
362 ctx.waker().wake_by_ref();
363 }
364 Poll::Pending
365 }
366 }
367 }
368
369 fn poll_next(&mut self, ctx: &mut Context<'_>) -> Poll<Result<Box<[u8]>, InnerError>> {
371 match self {
372 Transport::Error(e) => Poll::Ready(Err(e.clone())),
373 Transport::Transport(t, _, _) => match ready!(t.as_mut().poll_next(ctx)) {
374 Some(Ok(x)) => Poll::Ready(Ok(x)),
375 Some(Err(e)) => Poll::Ready(Err(InnerError::Transport(Some(Arc::new(e))))),
376 Option::None => Poll::Ready(Err(InnerError::Transport(None))),
377 },
378 }
379 }
380}
381
382impl Drop for Transport {
383 fn drop(&mut self) {
384 if let Transport::Transport(_, _, wakers) = self {
385 wakers.drain(..).for_each(Waker::wake);
386 }
387 }
388}
389
390struct SocketReadState {
392 wakers: Vec<Waker>,
393 queued: VecDeque<Result<SocketReadChunk, Error>>,
394 read_request_pending: bool,
395 is_streaming: bool,
396}
397
398#[derive(Debug)]
399struct SocketReadChunk {
400 data: proto::SocketData,
401 offset: usize,
402}
403
404impl SocketReadChunk {
405 fn new(data: proto::SocketData) -> Self {
406 Self { data, offset: 0 }
407 }
408}
409
410impl SocketReadState {
411 fn handle_incoming_message(&mut self, msg: Result<proto::SocketData, Error>) -> Vec<Waker> {
414 self.queued.push_back(msg.map(SocketReadChunk::new));
415 std::mem::replace(&mut self.wakers, Vec::new())
416 }
417}
418
419struct ChannelReadState {
421 wakers: Vec<Waker>,
422 queued: VecDeque<Result<proto::ChannelMessage, Error>>,
423 read_request_pending: bool,
424 is_streaming: bool,
425}
426
427impl ChannelReadState {
428 fn handle_incoming_message(&mut self, msg: Result<proto::ChannelMessage, Error>) -> Vec<Waker> {
431 self.queued.push_back(msg);
432 std::mem::replace(&mut self.wakers, Vec::new())
433 }
434}
435
436struct ClientInner {
438 transport: Transport,
439 transactions: HashMap<NonZeroU32, responder::Responder>,
440 channel_read_states: HashMap<proto::HandleId, ChannelReadState>,
441 socket_read_states: HashMap<proto::HandleId, SocketReadState>,
442 handles: HashSet<proto::HandleId>,
443 next_tx_id: u32,
444 waiting_to_close: Vec<proto::HandleId>,
445 waiting_to_close_waker: Waker,
446
447 wakers_to_wake: Vec<Waker>,
453}
454
455impl ClientInner {
456 fn new_hid(&mut self) -> proto::NewHandleId {
458 self.process_waiting_to_close();
459 loop {
460 let id = rand::random::<u32>() >> 1;
461 let hid = proto::HandleId { id };
462 if id != 0 && self.handles.insert(hid) {
463 return proto::NewHandleId { id };
464 }
465 }
466 }
467
468 fn request<S: fidl_message::Body>(&mut self, ordinal: u64, request: S, responder: Responder) {
470 if ordinal != ordinals::CLOSE {
471 self.process_waiting_to_close();
472 }
473 let tx_id = self.next_tx_id;
474
475 let header = TransactionHeader::new(tx_id, ordinal, fidl_message::DynamicFlags::FLEXIBLE);
476 let msg = fidl_message::encode_message(header, request).expect("Could not encode request!");
477 self.next_tx_id += 1;
478 if let Err(e) = self.transport.push_msg(msg.into()) {
479 let _ = responder.handle(self, Err(e.into()));
480 } else {
481 assert!(
482 self.transactions.insert(tx_id.try_into().unwrap(), responder).is_none(),
483 "Allocated same tx id twice!"
484 );
485 }
486 }
487
488 fn process_waiting_to_close(&mut self) {
489 if !self.waiting_to_close.is_empty() {
490 let handles = std::mem::replace(&mut self.waiting_to_close, Vec::new());
491 for handle in &handles {
494 let _ = self.channel_read_states.remove(handle);
495 let _ = self.socket_read_states.remove(handle);
496 self.handles.remove(handle);
497 }
498 self.request(
499 ordinals::CLOSE,
500 proto::FDomainCloseRequest { handles },
501 Responder::Ignore,
502 );
503 }
504 }
505
506 fn try_poll_transport(
509 &mut self,
510 ctx: &mut Context<'_>,
511 ) -> Poll<Result<Infallible, InnerError>> {
512 self.process_waiting_to_close();
513
514 self.waiting_to_close_waker = ctx.waker().clone();
515
516 loop {
517 if let Poll::Ready(e) = self.transport.poll_send_messages(ctx) {
518 return Poll::Ready(Err(e));
519 }
520 let Poll::Ready(result) = self.transport.poll_next(ctx) else {
521 return Poll::Pending;
522 };
523 let data = result?;
524 let (header, data) = fidl_message::decode_transaction_header(&data)?;
525
526 let Some(tx_id) = NonZeroU32::new(header.tx_id) else {
527 let wakers = self.process_event(header, data)?;
528 self.wakers_to_wake.extend(wakers);
529 continue;
530 };
531
532 let tx = self.transactions.remove(&tx_id).ok_or(::fidl::Error::InvalidResponseTxid)?;
533 tx.handle(self, Ok((header, data)))?;
534 }
535 }
536
537 fn process_event(
539 &mut self,
540 header: TransactionHeader,
541 data: &[u8],
542 ) -> Result<Vec<Waker>, InnerError> {
543 match header.ordinal {
544 ordinals::ON_SOCKET_STREAMING_DATA => {
545 let msg = fidl_message::decode_message::<proto::SocketOnSocketStreamingDataRequest>(
546 header, data,
547 )?;
548 let o =
549 self.socket_read_states.entry(msg.handle).or_insert_with(|| SocketReadState {
550 wakers: Vec::new(),
551 queued: VecDeque::new(),
552 is_streaming: false,
553 read_request_pending: false,
554 });
555 match msg.socket_message {
556 proto::SocketMessage::Data(data) => Ok(o.handle_incoming_message(Ok(data))),
557 proto::SocketMessage::Stopped(proto::AioStopped { error }) => {
558 let ret = if let Some(error) = error {
559 o.handle_incoming_message(Err(Error::FDomain(*error)))
560 } else {
561 Vec::new()
562 };
563 o.is_streaming = false;
564 Ok(ret)
565 }
566 _ => Err(InnerError::ProtocolStreamEventIncompatible),
567 }
568 }
569 ordinals::ON_CHANNEL_STREAMING_DATA => {
570 let msg = fidl_message::decode_message::<
571 proto::ChannelOnChannelStreamingDataRequest,
572 >(header, data)?;
573 let o = self.channel_read_states.entry(msg.handle).or_insert_with(|| {
574 ChannelReadState {
575 wakers: Vec::new(),
576 queued: VecDeque::new(),
577 is_streaming: false,
578 read_request_pending: false,
579 }
580 });
581 match msg.channel_sent {
582 proto::ChannelSent::Message(data) => Ok(o.handle_incoming_message(Ok(data))),
583 proto::ChannelSent::Stopped(proto::AioStopped { error }) => {
584 let ret = if let Some(error) = error {
585 o.handle_incoming_message(Err(Error::FDomain(*error)))
586 } else {
587 Vec::new()
588 };
589 o.is_streaming = false;
590 Ok(ret)
591 }
592 _ => Err(InnerError::ProtocolStreamEventIncompatible),
593 }
594 }
595 _ => Err(::fidl::Error::UnknownOrdinal {
596 ordinal: header.ordinal,
597 protocol_name:
598 <proto::FDomainMarker as ::fidl::endpoints::ProtocolMarker>::DEBUG_NAME,
599 }
600 .into()),
601 }
602 }
603
604 fn poll_transport(&mut self, ctx: &mut Context<'_>) -> Poll<()> {
608 if let Poll::Ready(Err(e)) = self.try_poll_transport(ctx) {
609 for (_, v) in std::mem::take(&mut self.transactions) {
610 let _ = v.handle(self, Err(e.clone()));
611 }
612 for mut state in std::mem::take(&mut self.socket_read_states).into_values() {
613 state.queued.push_back(Err(Error::from(e.clone())));
614 self.wakers_to_wake.extend(state.wakers);
615 }
616 for (_, mut state) in self.channel_read_states.drain() {
617 state.queued.push_back(Err(Error::from(e.clone())));
618 self.wakers_to_wake.extend(state.wakers);
619 }
620 if matches!(self.transport, Transport::Transport(_, _, _)) {
621 self.transport = Transport::Error(e);
622 }
623
624 Poll::Ready(())
625 } else {
626 Poll::Pending
627 }
628 }
629
630 pub(crate) fn handle_socket_read_response(
632 &mut self,
633 msg: Result<proto::SocketData, Error>,
634 id: proto::HandleId,
635 ) {
636 let state = self.socket_read_states.entry(id).or_insert_with(|| SocketReadState {
637 wakers: Vec::new(),
638 queued: VecDeque::new(),
639 is_streaming: false,
640 read_request_pending: false,
641 });
642 let wakers = state.handle_incoming_message(msg);
643 self.wakers_to_wake.extend(wakers);
644 state.read_request_pending = false;
645 }
646
647 pub(crate) fn handle_channel_read_response(
649 &mut self,
650 msg: Result<proto::ChannelMessage, Error>,
651 id: proto::HandleId,
652 ) {
653 let state = self.channel_read_states.entry(id).or_insert_with(|| ChannelReadState {
654 wakers: Vec::new(),
655 queued: VecDeque::new(),
656 is_streaming: false,
657 read_request_pending: false,
658 });
659 let wakers = state.handle_incoming_message(msg);
660 self.wakers_to_wake.extend(wakers);
661 state.read_request_pending = false;
662 }
663}
664
665impl Drop for ClientInner {
666 fn drop(&mut self) {
667 let responders = self.transactions.drain().map(|x| x.1).collect::<Vec<_>>();
668 for responder in responders {
669 let _ = responder.handle(self, Err(InnerError::Transport(None)));
670 }
671 for state in self.channel_read_states.values_mut() {
672 state.wakers.drain(..).for_each(Waker::wake);
673 }
674 for state in self.socket_read_states.values_mut() {
675 state.wakers.drain(..).for_each(Waker::wake);
676 }
677 self.waiting_to_close_waker.wake_by_ref();
678 self.wakers_to_wake.drain(..).for_each(Waker::wake);
679 }
680}
681
682pub struct Client(pub(crate) Mutex<ClientInner>);
689
690impl std::fmt::Debug for Client {
691 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
692 let inner = self.0.lock();
693 match &inner.transport {
694 Transport::Transport(transport, ..) if transport.has_debug_fmt() => {
695 write!(f, "Client(")?;
696 transport.debug_fmt(f)?;
697 write!(f, ")")
698 }
699 Transport::Error(error) => {
700 let error = Error::from(error.clone());
701 write!(f, "Client(Failed: {error})")
702 }
703 _ => f.debug_tuple("Client").field(&"<transport>").finish(),
704 }
705 }
706}
707
708pub(crate) static DEAD_CLIENT: LazyLock<Arc<Client>> = LazyLock::new(|| {
712 Arc::new(Client(Mutex::new(ClientInner {
713 transport: Transport::Error(InnerError::Transport(None)),
714 transactions: HashMap::new(),
715 channel_read_states: HashMap::new(),
716 socket_read_states: HashMap::new(),
717 handles: HashSet::new(),
718 next_tx_id: 1,
719 waiting_to_close: Vec::new(),
720 waiting_to_close_waker: std::task::Waker::noop().clone(),
721 wakers_to_wake: Vec::new(),
722 })))
723});
724
725pub struct ClientLoop {
731 client: Weak<Client>,
732 fut: Pin<Box<dyn Future<Output = ()> + Send + 'static>>,
733}
734
735impl Future for ClientLoop {
736 type Output = ();
737 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
738 self.fut.as_mut().poll(cx)
739 }
740}
741
742impl Drop for ClientLoop {
743 fn drop(&mut self) {
744 let Some(client) = self.client.upgrade() else {
745 return;
746 };
747
748 let (channel_read_states, socket_read_states, deferred_wakers) = {
749 let mut inner = client.0.lock();
750 if matches!(inner.transport, Transport::Transport(_, _, _)) {
751 inner.transport = Transport::Error(InnerError::Transport(None));
752 }
753
754 let transactions = std::mem::take(&mut inner.transactions);
755 log::debug!("ClientLoop dropped, failing {} transactions", transactions.len());
756 for (_, v) in transactions {
757 let _ = v.handle(&mut *inner, Err(InnerError::Transport(None)));
758 }
759
760 let channel_read_states = std::mem::take(&mut inner.channel_read_states);
761 let socket_read_states = std::mem::take(&mut inner.socket_read_states);
762
763 let deferred_wakers = std::mem::replace(&mut inner.wakers_to_wake, Vec::new());
764
765 (channel_read_states, socket_read_states, deferred_wakers)
766 };
767
768 log::debug!("Failing reads on {} channels", channel_read_states.len());
769 for (_, mut state) in channel_read_states {
770 state.queued.push_back(Err(Error::Transport(None)));
771 state.wakers.into_iter().for_each(Waker::wake);
772 }
773
774 log::debug!("Failing reads on {} sockets", socket_read_states.len());
775 for (_, mut state) in socket_read_states {
776 state.queued.push_back(Err(Error::Transport(None)));
777 state.wakers.into_iter().for_each(Waker::wake);
778 }
779
780 deferred_wakers.into_iter().for_each(Waker::wake);
781 }
782}
783
784impl Client {
785 pub fn transport_status(&self) -> Result<()> {
786 match &self.0.lock().transport {
787 Transport::Error(e) => Err(e.clone().into()),
788 Transport::Transport(_, _, _) => Ok(()),
789 }
790 }
791 pub fn new(
798 transport: impl FDomainTransport + 'static,
799 ) -> (Arc<Self>, impl Future<Output = ()> + Send + 'static) {
800 let ret = Arc::new(Client(Mutex::new(ClientInner {
801 transport: Transport::Transport(Box::pin(transport), VecDeque::new(), Vec::new()),
802 transactions: HashMap::new(),
803 socket_read_states: HashMap::new(),
804 channel_read_states: HashMap::new(),
805 handles: HashSet::new(),
806 next_tx_id: 1,
807 waiting_to_close: Vec::new(),
808 waiting_to_close_waker: std::task::Waker::noop().clone(),
809 wakers_to_wake: Vec::new(),
810 })));
811
812 let client_weak = Arc::downgrade(&ret);
813 let fut = futures::future::poll_fn(move |ctx| {
814 let Some(client) = client_weak.upgrade() else {
815 return Poll::Ready(());
816 };
817
818 let (ret, deferred_wakers) = {
819 let mut inner = client.0.lock();
820 let ret = inner.poll_transport(ctx);
821 let deferred_wakers = std::mem::replace(&mut inner.wakers_to_wake, Vec::new());
822 (ret, deferred_wakers)
823 };
824 deferred_wakers.into_iter().for_each(Waker::wake);
825 ret
826 });
827
828 let client_loop = ClientLoop { client: Arc::downgrade(&ret), fut: Box::pin(fut) };
829
830 (ret, client_loop)
831 }
832
833 pub async fn namespace(self: &Arc<Self>) -> Result<Channel, Error> {
835 let new_handle = self.new_hid();
836 let channel = Channel(Handle { id: new_handle.id, client: Arc::downgrade(self) });
837 self.transaction(
838 ordinals::GET_NAMESPACE,
839 proto::FDomainGetNamespaceRequest { new_handle },
840 Responder::Namespace,
841 )
842 .await?;
843 Ok(channel)
844 }
845
846 pub fn create_channel(self: &Arc<Self>) -> (Channel, Channel) {
848 let id_a = self.new_hid();
849 let id_b = self.new_hid();
850 let fut = self.transaction(
851 ordinals::CREATE_CHANNEL,
852 proto::ChannelCreateChannelRequest { handles: [id_a, id_b] },
853 Responder::CreateChannel,
854 );
855
856 fuchsia_async::Task::spawn(async move {
857 if let Err(e) = fut.await {
858 log::debug!("FDomain channel creation failed: {e}");
859 }
860 })
861 .detach();
862
863 (
864 Channel(Handle { id: id_a.id, client: Arc::downgrade(self) }),
865 Channel(Handle { id: id_b.id, client: Arc::downgrade(self) }),
866 )
867 }
868
869 pub fn channel_from_handle_id(self: &Arc<Self>, id: proto::HandleId) -> Channel {
871 Channel(Handle { id: id.id, client: Arc::downgrade(self) })
872 }
873
874 pub fn create_endpoints<F: crate::fidl::ProtocolMarker>(
876 self: &Arc<Self>,
877 ) -> (crate::fidl::ClientEnd<F>, crate::fidl::ServerEnd<F>) {
878 let (client, server) = self.create_channel();
879 let client_end = crate::fidl::ClientEnd::<F>::new(client);
880 let server_end = crate::fidl::ServerEnd::new(server);
881 (client_end, server_end)
882 }
883
884 pub fn create_proxy<F: crate::fidl::ProtocolMarker>(
886 self: &Arc<Self>,
887 ) -> (F::Proxy, crate::fidl::ServerEnd<F>) {
888 let (client_end, server_end) = self.create_endpoints::<F>();
889 (client_end.into_proxy(), server_end)
890 }
891
892 pub fn create_proxy_and_stream<F: crate::fidl::ProtocolMarker>(
894 self: &Arc<Self>,
895 ) -> (F::Proxy, F::RequestStream) {
896 let (client_end, server_end) = self.create_endpoints::<F>();
897 (client_end.into_proxy(), server_end.into_stream())
898 }
899
900 pub fn create_request_stream<F: crate::fidl::ProtocolMarker>(
902 self: &Arc<Self>,
903 ) -> (crate::fidl::ClientEnd<F>, F::RequestStream) {
904 let (client_end, server_end) = self.create_endpoints::<F>();
905 (client_end, server_end.into_stream())
906 }
907
908 fn create_socket(self: &Arc<Self>, options: proto::SocketType) -> (Socket, Socket) {
910 let id_a = self.new_hid();
911 let id_b = self.new_hid();
912 let fut = self.transaction(
913 ordinals::CREATE_SOCKET,
914 proto::SocketCreateSocketRequest { handles: [id_a, id_b], options },
915 Responder::CreateSocket,
916 );
917
918 fuchsia_async::Task::spawn(async move {
919 if let Err(e) = fut.await {
920 log::debug!("FDomain socket creation failed: {e}");
921 }
922 })
923 .detach();
924
925 (
926 Socket(Handle { id: id_a.id, client: Arc::downgrade(self) }),
927 Socket(Handle { id: id_b.id, client: Arc::downgrade(self) }),
928 )
929 }
930
931 pub fn create_stream_socket(self: &Arc<Self>) -> (Socket, Socket) {
933 self.create_socket(proto::SocketType::Stream)
934 }
935
936 pub fn create_datagram_socket(self: &Arc<Self>) -> (Socket, Socket) {
938 self.create_socket(proto::SocketType::Datagram)
939 }
940
941 pub fn create_event_pair(self: &Arc<Self>) -> (EventPair, EventPair) {
943 let id_a = self.new_hid();
944 let id_b = self.new_hid();
945 let fut = self.transaction(
946 ordinals::CREATE_EVENT_PAIR,
947 proto::EventPairCreateEventPairRequest { handles: [id_a, id_b] },
948 Responder::CreateEventPair,
949 );
950
951 fuchsia_async::Task::spawn(async move {
952 if let Err(e) = fut.await {
953 log::debug!("FDomain event pair creation failed: {e}");
954 }
955 })
956 .detach();
957
958 (
959 EventPair(Handle { id: id_a.id, client: Arc::downgrade(self) }),
960 EventPair(Handle { id: id_b.id, client: Arc::downgrade(self) }),
961 )
962 }
963
964 pub fn create_event(self: &Arc<Self>) -> Event {
966 let id = self.new_hid();
967 let fut = self.transaction(
968 ordinals::CREATE_EVENT,
969 proto::EventCreateEventRequest { handle: id },
970 Responder::CreateEvent,
971 );
972
973 fuchsia_async::Task::spawn(async move {
974 if let Err(e) = fut.await {
975 log::debug!("FDomain event creation failed: {e}");
976 }
977 })
978 .detach();
979
980 Event(Handle { id: id.id, client: Arc::downgrade(self) })
981 }
982
983 pub fn create_vmo(self: &Arc<Self>, options: proto::VmoOptions, size: u64) -> Vmo {
985 let id = self.new_hid();
986 let fut = self.transaction(
987 ordinals::CREATE_VMO,
988 proto::VmoCreateVmoRequest { handle: id, size, options },
989 Responder::CreateVmo,
990 );
991
992 fuchsia_async::Task::spawn(async move {
993 if let Err(e) = fut.await {
994 log::debug!("FDomain vmo creation failed: {e}");
995 }
996 })
997 .detach();
998
999 Vmo(Handle { id: id.id, client: Arc::downgrade(self) })
1000 }
1001
1002 pub(crate) fn new_hid(&self) -> proto::NewHandleId {
1004 self.0.lock().new_hid()
1005 }
1006
1007 pub(crate) fn transaction<S: fidl_message::Body, R: 'static, F>(
1013 self: &Arc<Self>,
1014 ordinal: u64,
1015 request: S,
1016 f: F,
1017 ) -> impl Future<Output = Result<R, Error>> + 'static + use<S, R, F>
1018 where
1019 F: Fn(OneshotSender<Result<R, Error>>) -> Responder,
1020 {
1021 let mut inner = self.0.lock();
1022
1023 let (sender, receiver) = futures::channel::oneshot::channel();
1024 inner.request(ordinal, request, f(sender));
1025 receiver.map(|x| x.expect("Oneshot went away without reply!"))
1026 }
1027
1028 pub(crate) fn start_socket_streaming(&self, id: proto::HandleId) -> Result<(), Error> {
1030 let mut inner = self.0.lock();
1031 if let Some(e) = inner.transport.error() {
1032 return Err(e.into());
1033 }
1034
1035 let state = inner.socket_read_states.entry(id).or_insert_with(|| SocketReadState {
1036 wakers: Vec::new(),
1037 queued: VecDeque::new(),
1038 is_streaming: false,
1039 read_request_pending: false,
1040 });
1041
1042 assert!(!state.is_streaming, "Initiated streaming twice!");
1043 state.is_streaming = true;
1044
1045 inner.request(
1046 ordinals::READ_SOCKET_STREAMING_START,
1047 proto::SocketReadSocketStreamingStartRequest { handle: id },
1048 Responder::Ignore,
1049 );
1050 Ok(())
1051 }
1052
1053 pub(crate) fn stop_socket_streaming(&self, id: proto::HandleId) {
1057 let mut inner = self.0.lock();
1058 if let Some(state) = inner.socket_read_states.get_mut(&id) {
1059 if state.is_streaming {
1060 state.is_streaming = false;
1061 let _ = inner.request(
1063 ordinals::READ_SOCKET_STREAMING_STOP,
1064 proto::SocketReadSocketStreamingStopRequest { handle: id },
1065 Responder::Ignore,
1066 );
1067 }
1068 }
1069 }
1070
1071 pub(crate) fn start_channel_streaming(&self, id: proto::HandleId) -> Result<(), Error> {
1073 let mut inner = self.0.lock();
1074 if let Some(e) = inner.transport.error() {
1075 return Err(e.into());
1076 }
1077 let state = inner.channel_read_states.entry(id).or_insert_with(|| ChannelReadState {
1078 wakers: Vec::new(),
1079 queued: VecDeque::new(),
1080 is_streaming: false,
1081 read_request_pending: false,
1082 });
1083
1084 assert!(!state.is_streaming, "Initiated streaming twice!");
1085 state.is_streaming = true;
1086
1087 inner.request(
1088 ordinals::READ_CHANNEL_STREAMING_START,
1089 proto::ChannelReadChannelStreamingStartRequest { handle: id },
1090 Responder::Ignore,
1091 );
1092
1093 Ok(())
1094 }
1095
1096 pub(crate) fn stop_channel_streaming(&self, id: proto::HandleId) {
1100 let mut inner = self.0.lock();
1101 if let Some(state) = inner.channel_read_states.get_mut(&id) {
1102 if state.is_streaming {
1103 state.is_streaming = false;
1104 let _ = inner.request(
1106 ordinals::READ_CHANNEL_STREAMING_STOP,
1107 proto::ChannelReadChannelStreamingStopRequest { handle: id },
1108 Responder::Ignore,
1109 );
1110 }
1111 }
1112 }
1113
1114 pub(crate) fn poll_socket(
1116 &self,
1117 id: proto::HandleId,
1118 ctx: &mut Context<'_>,
1119 out: &mut [u8],
1120 ) -> Poll<Result<usize, Error>> {
1121 let mut inner = self.0.lock();
1122 if let Some(error) = inner.transport.error() {
1123 return Poll::Ready(Err(error.into()));
1124 }
1125
1126 let state = inner.socket_read_states.entry(id).or_insert_with(|| SocketReadState {
1127 wakers: Vec::new(),
1128 queued: VecDeque::new(),
1129 is_streaming: false,
1130 read_request_pending: false,
1131 });
1132
1133 let mut total_read = 0;
1134 while let Some(got) = state.queued.pop_front() {
1135 match got {
1136 Ok(mut chunk) => {
1137 let available = &chunk.data.data[chunk.offset..];
1138 let remaining_out = &mut out[total_read..];
1139 let read_size = std::cmp::min(available.len(), remaining_out.len());
1140 remaining_out[..read_size].copy_from_slice(&available[..read_size]);
1141 total_read += read_size;
1142 chunk.offset += read_size;
1143
1144 let is_datagram = chunk.data.is_datagram;
1145 let is_done = chunk.offset == chunk.data.data.len() || is_datagram;
1146
1147 if !is_done {
1148 state.queued.push_front(Ok(chunk));
1149 }
1150
1151 if is_datagram || total_read == out.len() {
1152 break;
1153 }
1154 }
1155 Err(err) => {
1156 if total_read > 0 {
1157 state.queued.push_front(Err(err));
1158 break;
1159 }
1160 return Poll::Ready(Err(err));
1161 }
1162 }
1163 }
1164
1165 if total_read > 0 {
1166 return Poll::Ready(Ok(total_read));
1167 } else if !state.wakers.iter().any(|x| ctx.waker().will_wake(x)) {
1168 state.wakers.push(ctx.waker().clone());
1169 }
1170
1171 if !state.read_request_pending && !state.is_streaming {
1172 state.read_request_pending = true;
1173 inner.request(
1174 ordinals::READ_SOCKET,
1175 proto::SocketReadSocketRequest { handle: id, max_bytes: out.len() as u64 },
1176 Responder::ReadSocket(id),
1177 );
1178 }
1179
1180 Poll::Pending
1181 }
1182
1183 pub(crate) fn poll_channel(
1185 &self,
1186 id: proto::HandleId,
1187 ctx: &mut Context<'_>,
1188 for_stream: bool,
1189 ) -> Poll<Option<Result<proto::ChannelMessage, Error>>> {
1190 let mut inner = self.0.lock();
1191 if let Some(error) = inner.transport.error() {
1192 return Poll::Ready(Some(Err(error.into())));
1193 }
1194
1195 let state = inner.channel_read_states.entry(id).or_insert_with(|| ChannelReadState {
1196 wakers: Vec::new(),
1197 queued: VecDeque::new(),
1198 is_streaming: false,
1199 read_request_pending: false,
1200 });
1201
1202 if let Some(got) = state.queued.pop_front() {
1203 return Poll::Ready(Some(got));
1204 } else if for_stream && !state.is_streaming {
1205 return Poll::Ready(None);
1206 } else if !state.wakers.iter().any(|x| ctx.waker().will_wake(x)) {
1207 state.wakers.push(ctx.waker().clone());
1208 }
1209
1210 if !state.read_request_pending && !state.is_streaming {
1211 state.read_request_pending = true;
1212 inner.request(
1213 ordinals::READ_CHANNEL,
1214 proto::ChannelReadChannelRequest { handle: id },
1215 Responder::ReadChannel(id),
1216 );
1217 }
1218
1219 Poll::Pending
1220 }
1221
1222 pub(crate) fn channel_is_streaming(&self, id: proto::HandleId) -> bool {
1224 let inner = self.0.lock();
1225 let Some(state) = inner.channel_read_states.get(&id) else {
1226 return false;
1227 };
1228 state.is_streaming
1229 }
1230
1231 pub(crate) fn clear_handles_for_transfer(&self, handles: &proto::Handles) {
1234 let mut inner = self.0.lock();
1235 match handles {
1236 proto::Handles::Handles(handles) => {
1237 for handle in handles {
1238 assert!(
1239 !(inner.channel_read_states.contains_key(handle)
1240 || inner.socket_read_states.contains_key(handle)),
1241 "Tried to transfer handle after reading"
1242 );
1243 inner.handles.remove(handle);
1244 }
1245 }
1246 proto::Handles::Dispositions(dispositions) => {
1247 for disposition in dispositions {
1248 match &disposition.handle {
1249 proto::HandleOp::Move_(handle) => {
1250 assert!(
1251 !(inner.channel_read_states.contains_key(handle)
1252 || inner.socket_read_states.contains_key(handle)),
1253 "Tried to transfer handle after reading"
1254 );
1255 inner.handles.remove(handle);
1256 }
1257 proto::HandleOp::Duplicate(_) => (),
1259 }
1260 }
1261 }
1262 }
1263 }
1264}