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