1use fidl::AsHandleRef;
6use fidl::endpoints::ClientEnd;
7use fidl_fuchsia_fdomain as proto;
8use fidl_fuchsia_io as fio;
9#[cfg(target_os = "fuchsia")]
10use fuchsia_async as fasync;
11use futures::prelude::*;
12use replace_with::replace_with;
13use std::collections::hash_map::Entry;
14use std::collections::{HashMap, VecDeque};
15use std::num::NonZeroU32;
16use std::pin::Pin;
17use std::sync::Arc;
18use std::sync::atomic::{AtomicU32, Ordering};
19use std::task::{Context, Poll, Waker};
20
21mod handles;
22pub mod wire;
23
24#[cfg(test)]
25mod test;
26
27pub type Result<T, E = proto::Error> = std::result::Result<T, E>;
28
29use handles::{AnyHandle, HandleType as _, IsDatagramSocket};
30
31struct Queue<T>(VecDeque<T>);
34
35impl<T> Queue<T> {
36 fn new() -> Self {
38 Queue(VecDeque::new())
39 }
40
41 fn is_empty(&self) -> bool {
43 self.0.is_empty()
44 }
45
46 fn destroy_front(&mut self) {
51 assert!(self.0.pop_front().is_some(), "Expected to find a value!");
52 }
53
54 fn pop_front(&mut self) -> Option<T> {
56 self.0.pop_front()
57 }
58
59 fn push_front_no_wake(&mut self, t: T) {
66 self.0.push_front(t)
67 }
68
69 fn push_back(&mut self, t: T, waker: &Waker) {
71 self.0.push_back(t);
72 waker.wake_by_ref();
73 }
74
75 fn front_mut(&mut self) -> Option<&mut T> {
77 self.0.front_mut()
78 }
79}
80
81const ASYNC_READ_BUFSIZE: u64 = 256 * 1024;
84#[derive(Debug)]
92pub enum FDomainEvent {
93 ChannelStreamingReadStart(NonZeroU32, Result<()>),
94 ChannelStreamingReadStop(NonZeroU32, Result<()>),
95 SocketStreamingReadStart(NonZeroU32, Result<()>),
96 SocketStreamingReadStop(NonZeroU32, Result<()>),
97 WaitForSignals(NonZeroU32, Result<proto::FDomainWaitForSignalsResponse>),
98 SocketData(NonZeroU32, Result<proto::SocketData>),
99 SocketStreamingData(proto::SocketOnSocketStreamingDataRequest),
100 SocketDispositionSet(NonZeroU32, Result<()>),
101 WroteSocket(NonZeroU32, Result<proto::SocketWriteSocketResponse, proto::WriteSocketError>),
102 ChannelData(NonZeroU32, Result<proto::ChannelMessage>),
103 ChannelStreamingData(proto::ChannelOnChannelStreamingDataRequest),
104 WroteChannel(NonZeroU32, Result<(), proto::WriteChannelError>),
105 ClosedHandle(NonZeroU32, Result<()>),
106 ReplacedHandle(NonZeroU32, Result<()>),
107}
108
109enum UnprocessedFDomainEvent {
113 Ready(FDomainEvent),
114 ChannelData(NonZeroU32, fidl::MessageBufEtc),
115 ChannelStreamingData(proto::HandleId, fidl::MessageBufEtc),
116}
117
118impl From<FDomainEvent> for UnprocessedFDomainEvent {
119 fn from(other: FDomainEvent) -> UnprocessedFDomainEvent {
120 UnprocessedFDomainEvent::Ready(other)
121 }
122}
123
124enum ReadOp {
126 StreamingChannel(NonZeroU32, bool),
128 StreamingSocket(NonZeroU32, bool),
130 Socket(NonZeroU32, u64),
131 Channel(NonZeroU32),
132}
133
134struct SocketWrite {
138 tid: NonZeroU32,
139 wrote: usize,
140 to_write: Vec<u8>,
141}
142
143enum WriteOp {
145 Socket(SocketWrite),
146 Channel(NonZeroU32, Vec<u8>, HandlesToWrite),
147 SetDisposition(NonZeroU32, proto::SocketDisposition, proto::SocketDisposition),
148}
149
150enum ShuttingDownHandle {
155 InUse(proto::HandleId, HandleState),
156 Ready(AnyHandle),
157}
158
159impl ShuttingDownHandle {
160 fn poll_ready(
161 &mut self,
162 event_queue: &mut VecDeque<UnprocessedFDomainEvent>,
163 ctx: &mut Context<'_>,
164 ) -> Poll<()> {
165 replace_with(self, |this| match this {
166 this @ ShuttingDownHandle::Ready(_) => this,
167 ShuttingDownHandle::InUse(hid, mut state) => {
168 state.poll(event_queue, ctx);
169
170 if state.write_queue.is_empty() {
171 while let Some(op) = state.read_queue.pop_front() {
172 match op {
173 ReadOp::StreamingChannel(tid, start) => {
174 let err = Err(proto::Error::BadHandleId(proto::BadHandleId {
175 id: hid.id,
176 }));
177 let event = if start {
178 FDomainEvent::ChannelStreamingReadStart(tid, err)
179 } else {
180 FDomainEvent::ChannelStreamingReadStop(tid, err)
181 };
182 event_queue.push_back(event.into());
183 }
184 ReadOp::StreamingSocket(tid, start) => {
185 let err = Err(proto::Error::BadHandleId(proto::BadHandleId {
186 id: hid.id,
187 }));
188 let event = if start {
189 FDomainEvent::SocketStreamingReadStart(tid, err)
190 } else {
191 FDomainEvent::SocketStreamingReadStop(tid, err)
192 };
193 event_queue.push_back(event.into());
194 }
195 ReadOp::Channel(tid) => {
196 let err = state
197 .handle
198 .expected_type(fidl::ObjectType::CHANNEL)
199 .err()
200 .unwrap_or(proto::Error::ClosedDuringRead(
201 proto::ClosedDuringRead,
202 ));
203 event_queue
204 .push_back(FDomainEvent::ChannelData(tid, Err(err)).into());
205 }
206 ReadOp::Socket(tid, _max_bytes) => {
207 let err = state
208 .handle
209 .expected_type(fidl::ObjectType::SOCKET)
210 .err()
211 .unwrap_or(proto::Error::ClosedDuringRead(
212 proto::ClosedDuringRead,
213 ));
214 event_queue
215 .push_back(FDomainEvent::SocketData(tid, Err(err)).into());
216 }
217 }
218 }
219
220 if state.async_read_in_progress {
221 match &*state.handle {
222 AnyHandle::Channel(_) => event_queue.push_back(
223 FDomainEvent::ChannelStreamingData(
224 proto::ChannelOnChannelStreamingDataRequest {
225 handle: hid,
226 channel_sent: proto::ChannelSent::Stopped(
227 proto::AioStopped { error: None },
228 ),
229 },
230 )
231 .into(),
232 ),
233 AnyHandle::Socket(_) => event_queue.push_back(
234 FDomainEvent::SocketStreamingData(
235 proto::SocketOnSocketStreamingDataRequest {
236 handle: hid,
237 socket_message: proto::SocketMessage::Stopped(
238 proto::AioStopped { error: None },
239 ),
240 },
241 )
242 .into(),
243 ),
244 AnyHandle::EventPair(_)
245 | AnyHandle::Event(_)
246 | AnyHandle::Vmo(_)
247 | AnyHandle::Unknown(_) => unreachable!(),
248 }
249 }
250
251 state.signal_waiters.clear();
252 state.io_waiter = None;
253
254 ShuttingDownHandle::Ready(
255 Arc::into_inner(state.handle).expect("Unaccounted-for handle reference!"),
256 )
257 } else {
258 ShuttingDownHandle::InUse(hid, state)
259 }
260 }
261 });
262
263 if matches!(self, ShuttingDownHandle::Ready(_)) { Poll::Ready(()) } else { Poll::Pending }
264 }
265}
266
267enum HandlesToWrite {
271 SomeInUse(Vec<(ShuttingDownHandle, fidl::Rights)>),
272 AllReady(Vec<fidl::HandleDisposition<'static>>),
273}
274
275impl HandlesToWrite {
276 fn poll_ready(
277 &mut self,
278 event_queue: &mut VecDeque<UnprocessedFDomainEvent>,
279 ctx: &mut Context<'_>,
280 ) -> Poll<&mut Vec<fidl::HandleDisposition<'static>>> {
281 match self {
282 HandlesToWrite::AllReady(s) => Poll::Ready(s),
283 HandlesToWrite::SomeInUse(handles) => {
284 let mut ready = true;
285 for (handle, _) in handles.iter_mut() {
286 ready = ready && handle.poll_ready(event_queue, ctx).is_ready();
287 }
288
289 if !ready {
290 return Poll::Pending;
291 }
292
293 *self = HandlesToWrite::AllReady(
294 handles
295 .drain(..)
296 .map(|(handle, rights)| {
297 let ShuttingDownHandle::Ready(handle) = handle else { unreachable!() };
298
299 fidl::HandleDisposition::new(
300 fidl::HandleOp::Move(handle.into()),
301 fidl::ObjectType::NONE,
302 rights,
303 Ok(()),
304 )
305 })
306 .collect(),
307 );
308
309 let HandlesToWrite::AllReady(s) = self else { unreachable!() };
310 Poll::Ready(s)
311 }
312 }
313 }
314}
315
316struct AnyHandleRef(Arc<AnyHandle>);
317
318impl AsHandleRef for AnyHandleRef {
319 fn as_handle_ref(&self) -> fidl::HandleRef<'_> {
320 self.0.as_handle_ref()
321 }
322}
323
324#[cfg(target_os = "fuchsia")]
325type OnSignals = fasync::OnSignals<'static, AnyHandleRef>;
326
327#[cfg(not(target_os = "fuchsia"))]
328type OnSignals = fidl::OnSignalsRef<'static>;
329
330struct SignalWaiter {
333 tid: NonZeroU32,
334 waiter: Pin<Box<OnSignals>>,
335}
336
337struct HandleState {
339 handle: Arc<AnyHandle>,
341 hid: proto::HandleId,
343 is_datagram_socket: bool,
347 async_read_in_progress: bool,
352 read_queue: Queue<ReadOp>,
358 write_queue: Queue<WriteOp>,
365 signal_waiters: Vec<SignalWaiter>,
367 io_waiter: Option<Pin<Box<OnSignals>>>,
370}
371
372impl HandleState {
373 fn new(handle: AnyHandle, hid: proto::HandleId) -> Result<Self, proto::Error> {
374 let is_datagram_socket = match handle.is_datagram_socket() {
375 IsDatagramSocket::Unknown => {
376 return Err(proto::Error::SocketTypeUnknown(proto::SocketTypeUnknown {
377 type_: proto::SocketType::unknown(),
378 }));
379 }
380 other => other.is_datagram(),
381 };
382 Ok(HandleState {
383 handle: Arc::new(handle),
384 hid,
385 async_read_in_progress: false,
386 is_datagram_socket,
387 read_queue: Queue::new(),
388 write_queue: Queue::new(),
389 signal_waiters: Vec::new(),
390 io_waiter: None,
391 })
392 }
393
394 fn poll(&mut self, event_queue: &mut VecDeque<UnprocessedFDomainEvent>, ctx: &mut Context<'_>) {
397 self.signal_waiters.retain_mut(|x| {
398 let Poll::Ready(result) = x.waiter.poll_unpin(ctx) else {
399 return true;
400 };
401
402 event_queue.push_back(
403 FDomainEvent::WaitForSignals(
404 x.tid,
405 result
406 .map(|x| proto::FDomainWaitForSignalsResponse { signals: x.bits() })
407 .map_err(|e| proto::Error::TargetError(e.into_raw())),
408 )
409 .into(),
410 );
411
412 false
413 });
414
415 let read_signals = self.handle.read_signals();
416 let write_signals = self.handle.write_signals();
417
418 loop {
419 if let Some(signal_waiter) = self.io_waiter.as_mut() {
420 if let Poll::Ready(sigs) = signal_waiter.poll_unpin(ctx) {
421 if let Ok(sigs) = sigs {
422 if sigs.intersects(read_signals) {
423 self.process_read_queue(event_queue);
424 }
425 if sigs.intersects(write_signals) {
426 self.process_write_queue(event_queue, ctx);
427 }
428 }
429 } else {
430 let need_read = matches!(
431 self.read_queue.front_mut(),
432 Some(ReadOp::StreamingChannel(_, _) | ReadOp::StreamingSocket(_, _))
433 );
434 let need_write = matches!(
435 self.write_queue.front_mut(),
436 Some(WriteOp::SetDisposition(_, _, _))
437 );
438
439 self.process_read_queue(event_queue);
440 self.process_write_queue(event_queue, ctx);
441
442 if !(need_read || need_write) {
443 break;
444 }
445 }
446 }
447
448 let subscribed_signals =
449 if self.async_read_in_progress || !self.read_queue.is_empty() {
450 read_signals
451 } else {
452 fidl::Signals::NONE
453 } | if !self.write_queue.is_empty() { write_signals } else { fidl::Signals::NONE };
454
455 if !subscribed_signals.is_empty() {
456 self.io_waiter = Some(Box::pin(OnSignals::new(
457 AnyHandleRef(Arc::clone(&self.handle)),
458 subscribed_signals,
459 )));
460 } else {
461 self.io_waiter = None;
462 break;
463 }
464 }
465 }
466
467 fn try_enable_async_read(&mut self) -> Result<()> {
469 if self.async_read_in_progress {
470 Err(proto::Error::StreamingReadInProgress(proto::StreamingReadInProgress))
471 } else {
472 self.async_read_in_progress = true;
473 Ok(())
474 }
475 }
476
477 fn try_disable_async_read(&mut self) -> Result<()> {
479 if !self.async_read_in_progress {
480 Err(proto::Error::NoReadInProgress(proto::NoReadInProgress))
481 } else {
482 self.async_read_in_progress = false;
483 Ok(())
484 }
485 }
486
487 fn process_read_queue(&mut self, event_queue: &mut VecDeque<UnprocessedFDomainEvent>) {
489 while let Some(op) = self.read_queue.front_mut() {
490 match op {
491 ReadOp::StreamingChannel(tid, true) => {
492 let tid = *tid;
493 let result = self.try_enable_async_read();
494 event_queue
495 .push_back(FDomainEvent::ChannelStreamingReadStart(tid, result).into());
496 self.read_queue.destroy_front();
497 }
498 ReadOp::StreamingChannel(tid, false) => {
499 let tid = *tid;
500 let result = self.try_disable_async_read();
501 event_queue
502 .push_back(FDomainEvent::ChannelStreamingReadStop(tid, result).into());
503 self.read_queue.destroy_front();
504 }
505 ReadOp::StreamingSocket(tid, true) => {
506 let tid = *tid;
507 let result = self.try_enable_async_read();
508 event_queue
509 .push_back(FDomainEvent::SocketStreamingReadStart(tid, result).into());
510 self.read_queue.destroy_front();
511 }
512 ReadOp::StreamingSocket(tid, false) => {
513 let tid = *tid;
514 let result = self.try_disable_async_read();
515 event_queue
516 .push_back(FDomainEvent::SocketStreamingReadStop(tid, result).into());
517 self.read_queue.destroy_front();
518 }
519 ReadOp::Socket(tid, max_bytes) => {
520 let (tid, max_bytes) = (*tid, *max_bytes);
521 if let Some(event) = self.do_read_socket(tid, max_bytes) {
522 let _ = self.read_queue.pop_front();
523 event_queue.push_back(event.into());
524 } else {
525 break;
526 }
527 }
528 ReadOp::Channel(tid) => {
529 let tid = *tid;
530 if let Some(event) = self.do_read_channel(tid) {
531 let _ = self.read_queue.pop_front();
532 event_queue.push_back(event.into());
533 } else {
534 break;
535 }
536 }
537 }
538 }
539
540 if self.async_read_in_progress {
541 assert!(self.read_queue.is_empty());
544 self.process_async_read(event_queue);
545 }
546 }
547
548 fn process_async_read(&mut self, event_queue: &mut VecDeque<UnprocessedFDomainEvent>) {
549 assert!(self.async_read_in_progress);
550
551 match &*self.handle {
552 AnyHandle::Channel(_) => {
553 'read_loop: while let Some(result) = self.handle.read_channel().transpose() {
554 match result {
555 Ok(msg) => event_queue.push_back(
556 UnprocessedFDomainEvent::ChannelStreamingData(self.hid, msg),
557 ),
558 Err(e) => {
559 event_queue.push_back(
560 FDomainEvent::ChannelStreamingData(
561 proto::ChannelOnChannelStreamingDataRequest {
562 handle: self.hid,
563 channel_sent: proto::ChannelSent::Stopped(
564 proto::AioStopped { error: Some(Box::new(e)) },
565 ),
566 },
567 )
568 .into(),
569 );
570 self.async_read_in_progress = false;
571 break 'read_loop;
572 }
573 }
574 }
575 }
576
577 AnyHandle::Socket(_) => {
578 'read_loop: while let Some(result) =
579 self.handle.read_socket(ASYNC_READ_BUFSIZE).transpose()
580 {
581 match result {
582 Ok(data) => {
583 event_queue.push_back(
584 FDomainEvent::SocketStreamingData(
585 proto::SocketOnSocketStreamingDataRequest {
586 handle: self.hid,
587 socket_message: proto::SocketMessage::Data(
588 proto::SocketData {
589 data,
590 is_datagram: self.is_datagram_socket,
591 },
592 ),
593 },
594 )
595 .into(),
596 );
597 }
598 Err(e) => {
599 event_queue.push_back(
600 FDomainEvent::SocketStreamingData(
601 proto::SocketOnSocketStreamingDataRequest {
602 handle: self.hid,
603 socket_message: proto::SocketMessage::Stopped(
604 proto::AioStopped { error: Some(Box::new(e)) },
605 ),
606 },
607 )
608 .into(),
609 );
610 self.async_read_in_progress = false;
611 break 'read_loop;
612 }
613 }
614 }
615 }
616
617 _ => unreachable!("Processed async read for unreadable handle type!"),
618 }
619 }
620
621 fn process_write_queue(
623 &mut self,
624 event_queue: &mut VecDeque<UnprocessedFDomainEvent>,
625 ctx: &mut Context<'_>,
626 ) {
627 while let Some(op) = self.write_queue.pop_front() {
632 match op {
633 WriteOp::Socket(mut op) => {
634 if let Some(event) = self.do_write_socket(&mut op) {
635 event_queue.push_back(event.into());
636 } else {
637 self.write_queue.push_front_no_wake(WriteOp::Socket(op));
638 break;
639 }
640 }
641 WriteOp::SetDisposition(tid, disposition, disposition_peer) => {
642 let result = { self.handle.socket_disposition(disposition, disposition_peer) };
643 event_queue.push_back(FDomainEvent::SocketDispositionSet(tid, result).into())
644 }
645 WriteOp::Channel(tid, data, mut handles) => {
646 if self
647 .do_write_channel(tid, &data, &mut handles, event_queue, ctx)
648 .is_pending()
649 {
650 self.write_queue.push_front_no_wake(WriteOp::Channel(tid, data, handles));
651 break;
652 }
653 }
654 }
655 }
656 }
657
658 fn do_read_socket(&mut self, tid: NonZeroU32, max_bytes: u64) -> Option<FDomainEvent> {
662 if self.async_read_in_progress {
663 return Some(
664 FDomainEvent::SocketData(
665 tid,
666 Err(proto::Error::StreamingReadInProgress(proto::StreamingReadInProgress)),
667 )
668 .into(),
669 );
670 }
671
672 let max_bytes = if self.is_datagram_socket {
673 let AnyHandle::Socket(s) = &*self.handle else {
674 unreachable!("Read socket from state that wasn't for a socket!");
675 };
676 match s.info() {
677 Ok(x) => x.rx_buf_available as u64,
678 Err(e) => {
684 return Some(FDomainEvent::SocketData(
685 tid,
686 Err(proto::Error::TargetError(e.into_raw())),
687 ));
688 }
689 }
690 } else {
691 max_bytes
692 };
693 self.handle.read_socket(max_bytes).transpose().map(|x| {
694 FDomainEvent::SocketData(
695 tid,
696 x.map(|data| proto::SocketData { data, is_datagram: self.is_datagram_socket }),
697 )
698 })
699 }
700
701 fn do_write_socket(&mut self, op: &mut SocketWrite) -> Option<FDomainEvent> {
705 match self.handle.write_socket(&op.to_write) {
706 Ok(wrote) => {
707 op.wrote += wrote;
708 op.to_write.drain(..wrote);
709
710 if op.to_write.is_empty() {
711 Some(FDomainEvent::WroteSocket(
712 op.tid,
713 Ok(proto::SocketWriteSocketResponse {
714 wrote: op.wrote.try_into().unwrap(),
715 }),
716 ))
717 } else {
718 None
719 }
720 }
721 Err(error) => Some(FDomainEvent::WroteSocket(
722 op.tid,
723 Err(proto::WriteSocketError { error, wrote: op.wrote.try_into().unwrap() }),
724 )),
725 }
726 }
727
728 fn do_write_channel(
732 &mut self,
733 tid: NonZeroU32,
734 data: &[u8],
735 handles: &mut HandlesToWrite,
736 event_queue: &mut VecDeque<UnprocessedFDomainEvent>,
737 ctx: &mut Context<'_>,
738 ) -> Poll<()> {
739 let Poll::Ready(handles) = handles.poll_ready(event_queue, ctx) else {
740 return Poll::Pending;
741 };
742
743 let ret = self.handle.write_channel(data, handles);
744 if let Some(ret) = ret {
745 event_queue.push_back(FDomainEvent::WroteChannel(tid, ret).into())
746 }
747 Poll::Ready(())
748 }
749
750 fn do_read_channel(&mut self, tid: NonZeroU32) -> Option<UnprocessedFDomainEvent> {
754 if self.async_read_in_progress {
755 return Some(
756 FDomainEvent::ChannelData(
757 tid,
758 Err(proto::Error::StreamingReadInProgress(proto::StreamingReadInProgress)),
759 )
760 .into(),
761 );
762 }
763 match self.handle.read_channel() {
764 Ok(x) => x.map(|x| UnprocessedFDomainEvent::ChannelData(tid, x)),
765 Err(e) => Some(FDomainEvent::ChannelData(tid, Err(e)).into()),
766 }
767 }
768}
769
770struct ClosingHandle {
773 action: Arc<CloseAction>,
774 state: Option<ShuttingDownHandle>,
775}
776
777impl ClosingHandle {
778 fn poll_ready(&mut self, fdomain: &mut FDomain, ctx: &mut Context<'_>) -> Poll<()> {
779 if let Some(state) = self.state.as_mut() {
780 if state.poll_ready(&mut fdomain.event_queue, ctx).is_ready() {
781 let state = self.state.take().unwrap();
782 let ShuttingDownHandle::Ready(handle) = state else {
783 unreachable!();
784 };
785 self.action.perform(fdomain, handle);
786 Poll::Ready(())
787 } else {
788 Poll::Pending
789 }
790 } else {
791 Poll::Ready(())
792 }
793 }
794}
795
796enum CloseAction {
801 Close { tid: NonZeroU32, count: AtomicU32, result: Result<()> },
802 Replace { tid: NonZeroU32, new_hid: proto::NewHandleId, rights: fidl::Rights },
803}
804
805impl CloseAction {
806 fn perform(&self, fdomain: &mut FDomain, handle: AnyHandle) {
807 match self {
808 CloseAction::Close { tid, count, result } => {
809 if count.fetch_sub(1, Ordering::Relaxed) == 1 {
810 fdomain
811 .event_queue
812 .push_back(FDomainEvent::ClosedHandle(*tid, result.clone()).into());
813 }
814 }
815 CloseAction::Replace { tid, new_hid, rights } => {
816 let result = handle
817 .replace(*rights)
818 .and_then(|handle| fdomain.alloc_client_handles([*new_hid], [handle]));
819 fdomain.event_queue.push_back(FDomainEvent::ReplacedHandle(*tid, result).into());
820 }
821 }
822 }
823}
824
825enum Namespace {
826 Native(Box<dyn Fn() -> Result<ClientEnd<fio::DirectoryMarker>, fidl::Status> + Send>),
827 Channel(Box<dyn Fn(proto::HandleId) + Send>),
828}
829
830#[pin_project::pin_project]
835pub struct FDomain {
836 namespace: Namespace,
837 handles: HashMap<proto::HandleId, HandleState>,
838 closing_handles: Vec<ClosingHandle>,
839 event_queue: VecDeque<UnprocessedFDomainEvent>,
840 waker: Waker,
841}
842
843impl FDomain {
844 pub fn new_empty() -> Self {
847 Self::new(|| Err(fidl::Status::NOT_FOUND))
848 }
849
850 pub fn new(
852 namespace: impl Fn() -> Result<ClientEnd<fio::DirectoryMarker>, fidl::Status> + Send + 'static,
853 ) -> Self {
854 FDomain {
855 namespace: Namespace::Native(Box::new(namespace)),
856 handles: HashMap::new(),
857 closing_handles: Vec::new(),
858 event_queue: VecDeque::new(),
859 waker: Waker::noop().clone(),
860 }
861 }
862
863 pub fn new_with_namespace_channel(
865 namespace: impl Fn(proto::HandleId) + Send + 'static,
866 ) -> Self {
867 FDomain {
868 namespace: Namespace::Channel(Box::new(namespace)),
869 handles: HashMap::new(),
870 closing_handles: Vec::new(),
871 event_queue: VecDeque::new(),
872 waker: Waker::noop().clone(),
873 }
874 }
875
876 fn push_event(&mut self, event: impl Into<UnprocessedFDomainEvent>) {
878 self.event_queue.push_back(event.into());
879 self.waker.wake_by_ref();
880 }
881
882 fn process_message(
886 &mut self,
887 message: fidl::MessageBufEtc,
888 ) -> Result<proto::ChannelMessage, proto::Error> {
889 let (data, handles) = message.split();
890 let handles = handles
891 .into_iter()
892 .map(|info| {
893 let type_ = info.object_type;
894
895 let handle = match info.object_type {
896 fidl::ObjectType::CHANNEL => {
897 AnyHandle::Channel(fidl::Channel::from(info.handle))
898 }
899 fidl::ObjectType::SOCKET => AnyHandle::Socket(fidl::Socket::from(info.handle)),
900 fidl::ObjectType::EVENTPAIR => {
901 AnyHandle::EventPair(fidl::EventPair::from(info.handle))
902 }
903 fidl::ObjectType::EVENT => AnyHandle::Event(fidl::Event::from(info.handle)),
904 fidl::ObjectType::VMO => AnyHandle::Vmo(fidl::Vmo::from(info.handle)),
905 _ => AnyHandle::Unknown(handles::Unknown(info.handle, info.object_type)),
906 };
907
908 Ok(proto::HandleInfo {
909 rights: info.rights,
910 handle: self.alloc_fdomain_handle(handle)?,
911 type_,
912 })
913 })
914 .collect::<Result<Vec<_>, proto::Error>>()?;
915
916 Ok(proto::ChannelMessage { data, handles })
917 }
918
919 fn alloc_client_handles<const N: usize>(
926 &mut self,
927 ids: [proto::NewHandleId; N],
928 handles: [AnyHandle; N],
929 ) -> Result<(), proto::Error> {
930 for id in ids {
931 if id.id & (1 << 31) != 0 {
932 return Err(proto::Error::NewHandleIdOutOfRange(proto::NewHandleIdOutOfRange {
933 id: id.id,
934 }));
935 }
936
937 if self.handles.contains_key(&proto::HandleId { id: id.id }) {
938 return Err(proto::Error::NewHandleIdReused(proto::NewHandleIdReused {
939 id: id.id,
940 same_call: false,
941 }));
942 }
943 }
944
945 let mut sorted_ids = ids;
946 sorted_ids.sort();
947
948 if let Some([a, _]) = sorted_ids.array_windows().find(|&[a, b]| a == b) {
949 Err(proto::Error::NewHandleIdReused(proto::NewHandleIdReused {
950 id: a.id,
951 same_call: true,
952 }))
953 } else {
954 let ids = ids.into_iter().map(|id| proto::HandleId { id: id.id });
955 let handles = ids
956 .zip(handles.into_iter())
957 .map(|(id, h)| HandleState::new(h, id).map(|x| (id, x)))
958 .collect::<Result<Vec<_>, proto::Error>>()?;
959
960 self.handles.extend(handles);
961
962 Ok(())
963 }
964 }
965
966 fn alloc_fdomain_handle(&mut self, handle: AnyHandle) -> Result<proto::HandleId, proto::Error> {
969 loop {
970 let id = proto::HandleId { id: rand::random::<u32>() | (1u32 << 31) };
971 if let Entry::Vacant(v) = self.handles.entry(id) {
972 v.insert(HandleState::new(handle, id)?);
973 break Ok(id);
974 }
975 }
976 }
977
978 fn take_handle(&mut self, handle: proto::HandleId) -> Result<HandleState, proto::Error> {
980 self.handles
981 .remove(&handle)
982 .ok_or(proto::Error::BadHandleId(proto::BadHandleId { id: handle.id }))
983 }
984
985 fn using_handle<T>(
987 &mut self,
988 id: proto::HandleId,
989 f: impl FnOnce(&mut HandleState, &Waker) -> Result<T, proto::Error>,
990 ) -> Result<T, proto::Error> {
991 let waker = &self.waker;
992 if let Some(s) = self.handles.get_mut(&id) {
993 f(s, waker)
994 } else {
995 Err(proto::Error::BadHandleId(proto::BadHandleId { id: id.id }))
996 }
997 }
998
999 pub fn get_namespace(&mut self, request: proto::FDomainGetNamespaceRequest) -> Result<()> {
1000 match &self.namespace {
1001 Namespace::Native(namespace) => {
1002 let endpoint = namespace();
1003 match endpoint {
1004 Ok(endpoint) => self.alloc_client_handles(
1005 [request.new_handle],
1006 [AnyHandle::Channel(endpoint.into_channel())],
1007 ),
1008 Err(e) => Err(proto::Error::TargetError(e.into_raw())),
1009 }
1010 }
1011 Namespace::Channel(_) => {
1012 let (client_chan, server_chan) = fidl::Channel::create();
1013 self.alloc_client_handles([request.new_handle], [AnyHandle::Channel(client_chan)])?;
1014 let server_hid = self.alloc_fdomain_handle(AnyHandle::Channel(server_chan))?;
1015 if let Namespace::Channel(callback) = &self.namespace {
1016 callback(server_hid);
1017 }
1018 Ok(())
1019 }
1020 }
1021 }
1022
1023 pub fn create_channel(&mut self, request: proto::ChannelCreateChannelRequest) -> Result<()> {
1024 let (a, b) = fidl::Channel::create();
1025 self.alloc_client_handles(request.handles, [AnyHandle::Channel(a), AnyHandle::Channel(b)])
1026 }
1027
1028 pub fn create_socket(&mut self, request: proto::SocketCreateSocketRequest) -> Result<()> {
1029 let (a, b) = match request.options {
1030 proto::SocketType::Stream => fidl::Socket::create_stream(),
1031 proto::SocketType::Datagram => fidl::Socket::create_datagram(),
1032 type_ => {
1033 return Err(proto::Error::SocketTypeUnknown(proto::SocketTypeUnknown { type_ }));
1034 }
1035 };
1036
1037 self.alloc_client_handles(request.handles, [AnyHandle::Socket(a), AnyHandle::Socket(b)])
1038 }
1039
1040 pub fn create_event_pair(
1041 &mut self,
1042 request: proto::EventPairCreateEventPairRequest,
1043 ) -> Result<()> {
1044 let (a, b) = fidl::EventPair::create();
1045 self.alloc_client_handles(
1046 request.handles,
1047 [AnyHandle::EventPair(a), AnyHandle::EventPair(b)],
1048 )
1049 }
1050
1051 pub fn create_event(&mut self, request: proto::EventCreateEventRequest) -> Result<()> {
1052 let a = fidl::Event::create();
1053 self.alloc_client_handles([request.handle], [AnyHandle::Event(a)])
1054 }
1055
1056 #[cfg(target_os = "fuchsia")]
1057 pub fn create_vmo(&mut self, request: proto::VmoCreateVmoRequest) -> Result<()> {
1058 let opts = zx::VmoOptions::from_bits_truncate(request.options.bits());
1059 let a = zx::Vmo::create_with_opts(opts, request.size)
1060 .map_err(|e| proto::Error::TargetError(e.into_raw()))?;
1061 self.alloc_client_handles([request.handle], [AnyHandle::Vmo(a.into())])
1062 }
1063
1064 #[cfg(not(target_os = "fuchsia"))]
1065 pub fn create_vmo(&mut self, _request: proto::VmoCreateVmoRequest) -> Result<()> {
1066 Err(proto::Error::TargetError(fidl::Status::NOT_SUPPORTED.into_raw()))
1067 }
1068
1069 pub fn read_vmo(
1070 &mut self,
1071 request: proto::VmoReadVmoRequest,
1072 ) -> Result<proto::VmoReadVmoResponse> {
1073 let handle = self
1074 .handles
1075 .get(&request.handle)
1076 .ok_or(proto::Error::BadHandleId(proto::BadHandleId { id: request.handle.id }))?;
1077 let data = handle.handle.read_vmo(request.offset, request.size)?;
1078 Ok(proto::VmoReadVmoResponse { data })
1079 }
1080
1081 pub fn write_vmo(&mut self, request: proto::VmoWriteVmoRequest) -> Result<()> {
1082 let handle = self
1083 .handles
1084 .get(&request.handle)
1085 .ok_or(proto::Error::BadHandleId(proto::BadHandleId { id: request.handle.id }))?;
1086 handle.handle.write_vmo(request.offset, &request.data)
1087 }
1088
1089 pub fn get_vmo_size(
1090 &mut self,
1091 request: proto::VmoGetVmoSizeRequest,
1092 ) -> Result<proto::VmoGetVmoSizeResponse> {
1093 let handle = self
1094 .handles
1095 .get(&request.handle)
1096 .ok_or(proto::Error::BadHandleId(proto::BadHandleId { id: request.handle.id }))?;
1097 let size = handle.handle.get_vmo_size()?;
1098 Ok(proto::VmoGetVmoSizeResponse { size })
1099 }
1100
1101 pub fn set_vmo_size(&mut self, request: proto::VmoSetVmoSizeRequest) -> Result<()> {
1102 let handle = self
1103 .handles
1104 .get(&request.handle)
1105 .ok_or(proto::Error::BadHandleId(proto::BadHandleId { id: request.handle.id }))?;
1106 handle.handle.set_vmo_size(request.size)
1107 }
1108
1109 pub fn get_vmo_stream_size(
1110 &mut self,
1111 request: proto::VmoGetVmoStreamSizeRequest,
1112 ) -> Result<proto::VmoGetVmoStreamSizeResponse> {
1113 let handle = self
1114 .handles
1115 .get(&request.handle)
1116 .ok_or(proto::Error::BadHandleId(proto::BadHandleId { id: request.handle.id }))?;
1117 let size = handle.handle.get_vmo_stream_size()?;
1118 Ok(proto::VmoGetVmoStreamSizeResponse { size })
1119 }
1120
1121 pub fn set_vmo_stream_size(
1122 &mut self,
1123 request: proto::VmoSetVmoStreamSizeRequest,
1124 ) -> Result<()> {
1125 let handle = self
1126 .handles
1127 .get(&request.handle)
1128 .ok_or(proto::Error::BadHandleId(proto::BadHandleId { id: request.handle.id }))?;
1129 handle.handle.set_vmo_stream_size(request.size)
1130 }
1131
1132 pub fn set_socket_disposition(
1133 &mut self,
1134 tid: NonZeroU32,
1135 request: proto::SocketSetSocketDispositionRequest,
1136 ) {
1137 if let Err(err) = self.using_handle(request.handle, |h, waker| {
1138 h.write_queue.push_back(
1139 WriteOp::SetDisposition(tid, request.disposition, request.disposition_peer),
1140 waker,
1141 );
1142 Ok(())
1143 }) {
1144 self.push_event(FDomainEvent::SocketDispositionSet(tid, Err(err)));
1145 }
1146 }
1147
1148 pub fn read_socket(&mut self, tid: NonZeroU32, request: proto::SocketReadSocketRequest) {
1149 if let Err(e) = self.using_handle(request.handle, |h, waker| {
1150 h.read_queue.push_back(ReadOp::Socket(tid, request.max_bytes), waker);
1151 Ok(())
1152 }) {
1153 self.push_event(FDomainEvent::SocketData(tid, Err(e)));
1154 }
1155 }
1156
1157 pub fn read_channel(&mut self, tid: NonZeroU32, request: proto::ChannelReadChannelRequest) {
1158 if let Err(e) = self.using_handle(request.handle, |h, waker| {
1159 h.read_queue.push_back(ReadOp::Channel(tid), waker);
1160 Ok(())
1161 }) {
1162 self.push_event(FDomainEvent::ChannelData(tid, Err(e)));
1163 }
1164 }
1165
1166 pub fn write_socket(&mut self, tid: NonZeroU32, request: proto::SocketWriteSocketRequest) {
1167 if let Err(error) = self.using_handle(request.handle, |h, waker| {
1168 h.write_queue.push_back(
1169 WriteOp::Socket(SocketWrite { tid, wrote: 0, to_write: request.data }),
1170 waker,
1171 );
1172 Ok(())
1173 }) {
1174 self.push_event(FDomainEvent::WroteSocket(
1175 tid,
1176 Err(proto::WriteSocketError { error, wrote: 0 }),
1177 ));
1178 }
1179 }
1180
1181 pub fn write_channel(&mut self, tid: NonZeroU32, request: proto::ChannelWriteChannelRequest) {
1182 let handles: Vec<Result<(ShuttingDownHandle, fidl::Rights)>> = match request.handles {
1190 proto::Handles::Handles(h) => h
1191 .into_iter()
1192 .map(|h| {
1193 if h != request.handle {
1194 self.take_handle(h).map(|handle_state| {
1195 (ShuttingDownHandle::InUse(h, handle_state), fidl::Rights::SAME_RIGHTS)
1196 })
1197 } else {
1198 Err(proto::Error::WroteToSelf(proto::WroteToSelf))
1199 }
1200 })
1201 .collect(),
1202 proto::Handles::Dispositions(d) => d
1203 .into_iter()
1204 .map(|d| {
1205 let res = match d.handle {
1206 proto::HandleOp::Move_(h) => {
1207 if h != request.handle {
1208 self.take_handle(h).map(|x| ShuttingDownHandle::InUse(h, x))
1209 } else {
1210 Err(proto::Error::WroteToSelf(proto::WroteToSelf))
1211 }
1212 }
1213 proto::HandleOp::Duplicate(h) => {
1214 if h != request.handle {
1215 self.using_handle(h, |h, _| {
1221 h.handle.duplicate(fidl::Rights::SAME_RIGHTS)
1222 })
1223 .map(ShuttingDownHandle::Ready)
1224 } else {
1225 Err(proto::Error::WroteToSelf(proto::WroteToSelf))
1226 }
1227 }
1228 };
1229
1230 res.and_then(|x| Ok((x, d.rights)))
1231 })
1232 .collect(),
1233 };
1234
1235 if handles.iter().any(|x| x.is_err()) {
1236 let e = handles.into_iter().map(|x| x.err().map(Box::new)).collect();
1237
1238 self.push_event(FDomainEvent::WroteChannel(
1239 tid,
1240 Err(proto::WriteChannelError::OpErrors(e)),
1241 ));
1242 return;
1243 }
1244
1245 let handles = handles.into_iter().map(|x| x.unwrap()).collect::<Vec<_>>();
1246
1247 if let Err(e) = self.using_handle(request.handle, |h, waker| {
1248 h.write_queue.push_back(
1249 WriteOp::Channel(tid, request.data, HandlesToWrite::SomeInUse(handles)),
1250 waker,
1251 );
1252 Ok(())
1253 }) {
1254 self.push_event(FDomainEvent::WroteChannel(
1255 tid,
1256 Err(proto::WriteChannelError::Error(e)),
1257 ));
1258 }
1259 }
1260
1261 pub fn wait_for_signals(
1262 &mut self,
1263 tid: NonZeroU32,
1264 request: proto::FDomainWaitForSignalsRequest,
1265 ) {
1266 let result = self.using_handle(request.handle, |h, _| {
1267 let signals = fidl::Signals::from_bits_retain(request.signals);
1268 h.signal_waiters.push(SignalWaiter {
1269 tid,
1270 waiter: Box::pin(OnSignals::new(AnyHandleRef(Arc::clone(&h.handle)), signals)),
1271 });
1272 Ok(())
1273 });
1274
1275 if let Err(e) = result {
1276 self.push_event(FDomainEvent::WaitForSignals(tid, Err(e)));
1277 } else {
1278 self.waker.wake_by_ref();
1279 }
1280 }
1281
1282 pub fn close(&mut self, tid: NonZeroU32, request: proto::FDomainCloseRequest) {
1283 let mut states = Vec::with_capacity(request.handles.len());
1284 let mut result = Ok(());
1285 for hid in request.handles {
1286 match self.take_handle(hid) {
1287 Ok(state) => states.push((hid, state)),
1288
1289 Err(e) => {
1290 result = result.and(Err(e));
1291 }
1292 }
1293 }
1294
1295 let action = Arc::new(CloseAction::Close {
1296 tid,
1297 count: AtomicU32::new(states.len().try_into().unwrap()),
1298 result: result.clone(),
1299 });
1300
1301 if states.is_empty() {
1302 self.push_event(FDomainEvent::ClosedHandle(tid, result));
1303 } else {
1304 for (hid, state) in states {
1305 self.closing_handles.push(ClosingHandle {
1306 action: Arc::clone(&action),
1307 state: Some(ShuttingDownHandle::InUse(hid, state)),
1308 });
1309 }
1310 self.waker.wake_by_ref();
1311 }
1312 }
1313
1314 pub fn duplicate(&mut self, request: proto::FDomainDuplicateRequest) -> Result<()> {
1315 let rights = request.rights;
1316 let handle = self.using_handle(request.handle, |h, _| h.handle.duplicate(rights));
1317 handle.and_then(|h| self.alloc_client_handles([request.new_handle], [h]))
1318 }
1319
1320 pub fn replace(
1321 &mut self,
1322 tid: NonZeroU32,
1323 request: proto::FDomainReplaceRequest,
1324 ) -> Result<()> {
1325 let rights = request.rights;
1326 let new_hid = request.new_handle;
1327 match self.take_handle(request.handle) {
1328 Ok(state) => {
1329 self.closing_handles.push(ClosingHandle {
1330 action: Arc::new(CloseAction::Replace { tid, new_hid, rights }),
1331 state: Some(ShuttingDownHandle::InUse(request.handle, state)),
1332 });
1333 self.waker.wake_by_ref();
1334 }
1335 Err(e) => self.push_event(FDomainEvent::ReplacedHandle(tid, Err(e))),
1336 }
1337
1338 Ok(())
1339 }
1340
1341 pub fn signal(&mut self, request: proto::FDomainSignalRequest) -> Result<()> {
1342 let set = fidl::Signals::from_bits_retain(request.set);
1343 let clear = fidl::Signals::from_bits_retain(request.clear);
1344
1345 self.using_handle(request.handle, |h, _| h.handle.signal(clear, set))
1346 }
1347
1348 pub fn signal_peer(&mut self, request: proto::FDomainSignalPeerRequest) -> Result<()> {
1349 let set = fidl::Signals::from_bits_retain(request.set);
1350 let clear = fidl::Signals::from_bits_retain(request.clear);
1351
1352 self.using_handle(request.handle, |h, _| h.handle.signal_peer(clear, set))
1353 }
1354
1355 pub fn get_koid(
1356 &mut self,
1357 request: proto::FDomainGetKoidRequest,
1358 ) -> Result<proto::FDomainGetKoidResponse> {
1359 self.using_handle(request.handle, |h, _| {
1360 h.handle
1361 .as_handle_ref()
1362 .koid()
1363 .map(|k| proto::FDomainGetKoidResponse { koid: k.raw_koid() })
1364 .map_err(|e| proto::Error::TargetError(e.into_raw()))
1365 })
1366 }
1367
1368 pub fn read_channel_streaming_start(
1369 &mut self,
1370 tid: NonZeroU32,
1371 request: proto::ChannelReadChannelStreamingStartRequest,
1372 ) {
1373 if let Err(err) = self.using_handle(request.handle, |h, waker| {
1374 h.handle.expected_type(fidl::ObjectType::CHANNEL)?;
1375 h.read_queue.push_back(ReadOp::StreamingChannel(tid, true), waker);
1376 Ok(())
1377 }) {
1378 self.push_event(FDomainEvent::ChannelStreamingReadStart(tid, Err(err)));
1379 }
1380 }
1381
1382 pub fn read_channel_streaming_stop(
1383 &mut self,
1384 tid: NonZeroU32,
1385 request: proto::ChannelReadChannelStreamingStopRequest,
1386 ) {
1387 if let Err(err) = self.using_handle(request.handle, |h, waker| {
1388 h.handle.expected_type(fidl::ObjectType::CHANNEL)?;
1389 h.read_queue.push_back(ReadOp::StreamingChannel(tid, false), waker);
1390 Ok(())
1391 }) {
1392 self.push_event(FDomainEvent::ChannelStreamingReadStop(tid, Err(err)));
1393 }
1394 }
1395
1396 pub fn read_socket_streaming_start(
1397 &mut self,
1398 tid: NonZeroU32,
1399 request: proto::SocketReadSocketStreamingStartRequest,
1400 ) {
1401 if let Err(err) = self.using_handle(request.handle, |h, waker| {
1402 h.handle.expected_type(fidl::ObjectType::SOCKET)?;
1403 h.read_queue.push_back(ReadOp::StreamingSocket(tid, true), waker);
1404 Ok(())
1405 }) {
1406 self.push_event(FDomainEvent::SocketStreamingReadStart(tid, Err(err)));
1407 }
1408 }
1409
1410 pub fn read_socket_streaming_stop(
1411 &mut self,
1412 tid: NonZeroU32,
1413 request: proto::SocketReadSocketStreamingStopRequest,
1414 ) {
1415 if let Err(err) = self.using_handle(request.handle, |h, waker| {
1416 h.handle.expected_type(fidl::ObjectType::SOCKET)?;
1417 h.read_queue.push_back(ReadOp::StreamingSocket(tid, false), waker);
1418 Ok(())
1419 }) {
1420 self.push_event(FDomainEvent::SocketStreamingReadStop(tid, Err(err)));
1421 }
1422 }
1423}
1424
1425impl futures::Stream for FDomain {
1428 type Item = FDomainEvent;
1429
1430 fn poll_next(
1431 mut self: std::pin::Pin<&mut Self>,
1432 ctx: &mut Context<'_>,
1433 ) -> Poll<Option<Self::Item>> {
1434 let this = &mut *self;
1435
1436 let mut closing_handles = std::mem::replace(&mut this.closing_handles, Vec::new());
1437 closing_handles.retain_mut(|x| x.poll_ready(this, ctx).is_pending());
1438 this.closing_handles = closing_handles;
1439
1440 let handles = &mut this.handles;
1441 let event_queue = &mut this.event_queue;
1442 for state in handles.values_mut() {
1443 state.poll(event_queue, ctx);
1444 }
1445
1446 if let Some(event) = self.event_queue.pop_front() {
1447 match event {
1448 UnprocessedFDomainEvent::Ready(event) => Poll::Ready(Some(event)),
1449 UnprocessedFDomainEvent::ChannelData(tid, message) => {
1450 Poll::Ready(Some(FDomainEvent::ChannelData(tid, self.process_message(message))))
1451 }
1452 UnprocessedFDomainEvent::ChannelStreamingData(hid, message) => {
1453 match self.process_message(message) {
1454 Ok(message) => Poll::Ready(Some(FDomainEvent::ChannelStreamingData(
1455 proto::ChannelOnChannelStreamingDataRequest {
1456 handle: hid,
1457 channel_sent: proto::ChannelSent::Message(message),
1458 },
1459 ))),
1460 Err(e) => {
1461 self.handles.get_mut(&hid).unwrap().async_read_in_progress = false;
1462 Poll::Ready(Some(FDomainEvent::ChannelStreamingData(
1463 proto::ChannelOnChannelStreamingDataRequest {
1464 handle: hid,
1465 channel_sent: proto::ChannelSent::Stopped(proto::AioStopped {
1466 error: Some(Box::new(e)),
1467 }),
1468 },
1469 )))
1470 }
1471 }
1472 }
1473 }
1474 } else {
1475 self.waker = ctx.waker().clone();
1476 Poll::Pending
1477 }
1478 }
1479}