1use crate::Error;
8use crate::encoding::{
9 Decode, Decoder, DefaultFuchsiaResourceDialect, DynamicFlags, Encode, Encoder, EpitaphBody,
10 MessageBufFor, ProxyChannelBox, ProxyChannelFor, ResourceDialect, TransactionHeader,
11 TransactionMessage, TransactionMessageType, TypeMarker, decode_transaction_header,
12};
13use fuchsia_sync::Mutex;
14use futures::future::{self, FusedFuture, Future, FutureExt, Map, MaybeDone};
15use futures::ready;
16use futures::stream::{FusedStream, Stream};
17use futures::task::{Context, Poll, Waker};
18use slab::Slab;
19use std::collections::VecDeque;
20use std::mem;
21use std::ops::ControlFlow;
22use std::pin::Pin;
23use std::sync::Arc;
24use std::task::{RawWaker, RawWakerVTable};
25
26#[doc(hidden)] pub fn decode_transaction_body<T: TypeMarker, D: ResourceDialect, const EXPECTED_ORDINAL: u64>(
29 mut buf: D::MessageBufEtc,
30) -> Result<T::Owned, Error>
31where
32 T::Owned: Decode<T, D>,
33{
34 let (bytes, handles) = buf.split_mut();
35 let (header, body_bytes) = decode_transaction_header(bytes)?;
36 if header.ordinal != EXPECTED_ORDINAL {
37 return Err(Error::InvalidResponseOrdinal);
38 }
39 let mut output = Decode::<T, D>::new_empty();
40 Decoder::<D>::decode_into::<T>(&header, body_bytes, handles, &mut output)?;
41 Ok(output)
42}
43
44#[derive(Debug, Clone)]
46pub struct Client<D: ResourceDialect = DefaultFuchsiaResourceDialect> {
47 inner: Arc<ClientInner<D>>,
48}
49
50pub type DecodedQueryResponseFut<T, D = DefaultFuchsiaResourceDialect> = Map<
52 MessageResponse<D>,
53 fn(Result<<D as ResourceDialect>::MessageBufEtc, Error>) -> Result<T, Error>,
54>;
55
56#[derive(Debug)]
59#[must_use = "futures do nothing unless you `.await` or poll them"]
60pub struct QueryResponseFut<T, D: ResourceDialect = DefaultFuchsiaResourceDialect>(
61 pub MaybeDone<DecodedQueryResponseFut<T, D>>,
62);
63
64impl<T: Unpin, D: ResourceDialect> FusedFuture for QueryResponseFut<T, D> {
65 fn is_terminated(&self) -> bool {
66 matches!(self.0, MaybeDone::Gone)
67 }
68}
69
70impl<T: Unpin, D: ResourceDialect> Future for QueryResponseFut<T, D> {
71 type Output = Result<T, Error>;
72
73 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
74 ready!(self.0.poll_unpin(cx));
75 let maybe_done = Pin::new(&mut self.0);
76 Poll::Ready(maybe_done.take_output().unwrap_or(Err(Error::PollAfterCompletion)))
77 }
78}
79
80impl<T> QueryResponseFut<T> {
81 pub fn check(self) -> Result<Self, Error> {
88 match self.0 {
89 MaybeDone::Done(Err(e)) => Err(e),
90 x => Ok(QueryResponseFut(x)),
91 }
92 }
93}
94
95const TXID_INTEREST_MASK: u32 = 0xFFFFFF;
96const TXID_GENERATION_SHIFT: usize = 24;
97const TXID_GENERATION_MASK: u8 = 0x7F;
98
99#[derive(Debug, Copy, Clone, PartialEq, Eq)]
101pub struct Txid(u32);
102#[derive(Debug, Copy, Clone, PartialEq, Eq)]
104struct InterestId(usize);
105
106impl InterestId {
107 fn from_txid(txid: Txid) -> Self {
108 InterestId((txid.0 & TXID_INTEREST_MASK) as usize - 1)
109 }
110}
111
112impl Txid {
113 fn from_interest_id(int_id: InterestId, generation: u8) -> Self {
114 let id = (int_id.0 as u32 + 1) & TXID_INTEREST_MASK;
117 let generation = (generation & TXID_GENERATION_MASK) as u32;
119
120 let txid = (generation << TXID_GENERATION_SHIFT) | id;
125
126 Txid(txid)
127 }
128
129 pub fn as_raw_id(&self) -> u32 {
131 self.0
132 }
133}
134
135impl From<u32> for Txid {
136 fn from(txid: u32) -> Self {
137 Self(txid)
138 }
139}
140
141impl<D: ResourceDialect> Client<D> {
142 pub fn new(channel: D::ProxyChannel, protocol_name: &'static str) -> Client<D> {
147 Client {
148 inner: Arc::new(ClientInner {
149 channel: channel.boxed(),
150 interests: Mutex::default(),
151 terminal_error: Mutex::default(),
152 protocol_name,
153 }),
154 }
155 }
156
157 pub fn as_channel(&self) -> &D::ProxyChannel {
159 self.inner.channel.as_channel()
160 }
161
162 pub fn into_channel(self) -> Result<D::ProxyChannel, Self> {
169 match Arc::try_unwrap(self.inner) {
179 Ok(inner) => {
180 if inner.interests.lock().messages.is_empty() || inner.channel.is_closed() {
181 Ok(inner.channel.unbox())
182 } else {
183 Err(Self { inner: Arc::new(inner) })
188 }
189 }
190 Err(inner) => Err(Self { inner }),
191 }
192 }
193
194 pub fn take_event_receiver(&self) -> EventReceiver<D> {
197 {
198 let mut lock = self.inner.interests.lock();
199
200 if let EventListener::None = lock.event_listener {
201 lock.event_listener = EventListener::WillPoll;
202 } else {
203 panic!("Event stream was already taken");
204 }
205 }
206
207 EventReceiver { inner: self.inner.clone(), state: EventReceiverState::Active }
208 }
209
210 pub fn send<T: TypeMarker>(
212 &self,
213 body: impl Encode<T, D>,
214 ordinal: u64,
215 dynamic_flags: DynamicFlags,
216 ) -> Result<(), Error> {
217 let msg =
218 TransactionMessage { header: TransactionHeader::new(0, ordinal, dynamic_flags), body };
219 crate::encoding::with_tls_encoded::<TransactionMessageType<T>, D, ()>(
220 msg,
221 |bytes, handles| self.send_raw(bytes, handles),
222 )
223 }
224
225 pub fn send_query<Request: TypeMarker, Response: TypeMarker, const ORDINAL: u64>(
227 &self,
228 body: impl Encode<Request, D>,
229 dynamic_flags: DynamicFlags,
230 ) -> QueryResponseFut<Response::Owned, D>
231 where
232 Response::Owned: Decode<Response, D>,
233 {
234 self.send_query_and_decode::<Request, Response::Owned>(
235 body,
236 ORDINAL,
237 dynamic_flags,
238 |buf| buf.and_then(decode_transaction_body::<Response, D, ORDINAL>),
239 )
240 }
241
242 pub fn send_query_and_decode<Request: TypeMarker, Output>(
245 &self,
246 body: impl Encode<Request, D>,
247 ordinal: u64,
248 dynamic_flags: DynamicFlags,
249 decode: fn(Result<D::MessageBufEtc, Error>) -> Result<Output, Error>,
250 ) -> QueryResponseFut<Output, D> {
251 let send_result = self.send_raw_query(|tx_id, bytes, handles| {
252 let msg = TransactionMessage {
253 header: TransactionHeader::new(tx_id.as_raw_id(), ordinal, dynamic_flags),
254 body,
255 };
256 Encoder::encode::<TransactionMessageType<Request>>(bytes, handles, msg)?;
257 Ok(())
258 });
259
260 QueryResponseFut(match send_result {
261 Ok(res_fut) => future::maybe_done(res_fut.map(decode)),
262 Err(e) => MaybeDone::Done(Err(e)),
263 })
264 }
265
266 pub fn send_raw(
268 &self,
269 bytes: &[u8],
270 handles: &mut [<D::ProxyChannel as ProxyChannelFor<D>>::HandleDisposition],
271 ) -> Result<(), Error> {
272 match self.inner.channel.write_etc(bytes, handles) {
273 Ok(()) | Err(None) => Ok(()),
274 Err(Some(e)) => Err(Error::ClientWrite(e.into())),
275 }
276 }
277
278 pub fn send_raw_query<F>(&self, encode_msg: F) -> Result<MessageResponse<D>, Error>
280 where
281 F: for<'a, 'b> FnOnce(
282 Txid,
283 &'a mut Vec<u8>,
284 &'b mut Vec<<D::ProxyChannel as ProxyChannelFor<D>>::HandleDisposition>,
285 ) -> Result<(), Error>,
286 {
287 let id = self.inner.interests.lock().register_msg_interest();
288 crate::encoding::with_tls_encode_buf::<_, D>(|bytes, handles| {
289 encode_msg(id, bytes, handles)?;
290 self.send_raw(bytes, handles)
291 })?;
292
293 Ok(MessageResponse { id, client: Some(self.inner.clone()) })
294 }
295}
296
297#[must_use]
298#[derive(Debug)]
300pub struct MessageResponse<D: ResourceDialect = DefaultFuchsiaResourceDialect> {
301 id: Txid,
302 client: Option<Arc<ClientInner<D>>>,
304}
305
306impl<D: ResourceDialect> Unpin for MessageResponse<D> {}
307
308impl<D: ResourceDialect> Future for MessageResponse<D> {
309 type Output = Result<D::MessageBufEtc, Error>;
310 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
311 let this = &mut *self;
312 let res;
313 {
314 let client = this.client.as_ref().ok_or(Error::PollAfterCompletion)?;
315 res = client.poll_recv_msg_response(this.id, cx);
316 }
317
318 if let Poll::Ready(Ok(_)) = res {
320 this.client.take().expect("MessageResponse polled after completion");
321 }
322
323 res
324 }
325}
326
327impl<D: ResourceDialect> Drop for MessageResponse<D> {
328 fn drop(&mut self) {
329 if let Some(client) = &self.client {
330 client.interests.lock().deregister(self.id);
331 }
332 }
333}
334
335#[derive(Debug)]
338enum MessageInterest<D: ResourceDialect> {
339 WillPoll,
341 Waiting(Waker),
343 Received(D::MessageBufEtc),
345 Discard,
348}
349
350impl<D: ResourceDialect> MessageInterest<D> {
351 fn is_received(&self) -> bool {
353 matches!(*self, MessageInterest::Received(_))
354 }
355
356 fn unwrap_received(self) -> D::MessageBufEtc {
357 if let MessageInterest::Received(buf) = self {
358 buf
359 } else {
360 panic!("EXPECTED received message")
361 }
362 }
363}
364
365#[derive(Debug)]
366enum EventReceiverState {
367 Active,
368 Terminal,
369 Terminated,
370}
371
372#[derive(Debug)]
374pub struct EventReceiver<D: ResourceDialect = DefaultFuchsiaResourceDialect> {
375 inner: Arc<ClientInner<D>>,
376 state: EventReceiverState,
377}
378
379impl<D: ResourceDialect> Unpin for EventReceiver<D> {}
380
381impl<D: ResourceDialect> FusedStream for EventReceiver<D> {
382 fn is_terminated(&self) -> bool {
383 matches!(self.state, EventReceiverState::Terminated)
384 }
385}
386
387impl<D: ResourceDialect> Stream for EventReceiver<D> {
392 type Item = Result<D::MessageBufEtc, Error>;
393
394 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
395 match self.state {
396 EventReceiverState::Active => {}
397 EventReceiverState::Terminated => {
398 panic!("polled EventReceiver after `None`");
399 }
400 EventReceiverState::Terminal => {
401 self.state = EventReceiverState::Terminated;
402 return Poll::Ready(None);
403 }
404 }
405
406 Poll::Ready(match ready!(self.inner.poll_recv_event(cx)) {
407 Ok(x) => Some(Ok(x)),
408 Err(Error::ClientChannelClosed {
409 epitaph: crate::error::Epitaph::PeerClosed, ..
410 }) => {
411 self.state = EventReceiverState::Terminated;
414 None
415 }
416 err @ Err(_) => {
417 self.state = EventReceiverState::Terminal;
420 Some(err)
421 }
422 })
423 }
424}
425
426impl<D: ResourceDialect> Drop for EventReceiver<D> {
427 fn drop(&mut self) {
428 self.inner.interests.lock().dropped_event_listener();
429 }
430}
431
432#[derive(Debug, Default)]
433enum EventListener {
434 #[default]
436 None,
437 WillPoll,
439 Some(Waker),
441}
442
443impl EventListener {
444 fn is_some(&self) -> bool {
445 matches!(self, EventListener::Some(_))
446 }
447}
448
449#[derive(Debug)]
451struct ClientInner<D: ResourceDialect> {
452 channel: <D::ProxyChannel as ProxyChannelFor<D>>::Boxed,
454
455 interests: Mutex<Interests<D>>,
457
458 terminal_error: Mutex<Option<Error>>,
461
462 protocol_name: &'static str,
464}
465
466#[derive(Debug)]
467struct Interests<D: ResourceDialect> {
468 messages: Slab<MessageInterest<D>>,
469 events: VecDeque<D::MessageBufEtc>,
470 event_listener: EventListener,
471 waker_count: usize,
473 generation: u8,
479}
480
481impl<D: ResourceDialect> Default for Interests<D> {
482 fn default() -> Self {
483 Interests {
484 messages: Slab::new(),
485 events: Default::default(),
486 event_listener: Default::default(),
487 waker_count: 0,
488 generation: 0,
489 }
490 }
491}
492
493impl<D: ResourceDialect> Interests<D> {
494 fn push_event(&mut self, buf: D::MessageBufEtc) -> Option<Waker> {
496 self.events.push_back(buf);
497 self.take_event_waker()
498 }
499
500 fn take_event_waker(&mut self) -> Option<Waker> {
502 if self.event_listener.is_some() {
503 let EventListener::Some(waker) =
504 mem::replace(&mut self.event_listener, EventListener::WillPoll)
505 else {
506 unreachable!()
507 };
508
509 self.waker_count -= 1;
511 Some(waker)
512 } else {
513 None
514 }
515 }
516
517 fn event_waker(&self) -> Option<&Waker> {
519 match &self.event_listener {
520 EventListener::Some(waker) => Some(waker),
521 _ => None,
522 }
523 }
524
525 fn push_message(&mut self, txid: Txid, buf: D::MessageBufEtc) -> Result<Option<Waker>, Error> {
528 let InterestId(raw_id) = InterestId::from_txid(txid);
529 let Some(interest) = self.messages.get_mut(raw_id) else {
532 return Err(Error::InvalidResponseTxid);
534 };
535
536 let mut waker = None;
537 if let MessageInterest::Discard = interest {
538 self.messages.remove(raw_id);
539 } else if let MessageInterest::Waiting(w) =
540 mem::replace(interest, MessageInterest::Received(buf))
541 {
542 waker = Some(w);
543
544 self.waker_count -= 1;
546 }
547
548 Ok(waker)
549 }
550
551 fn register(&mut self, txid: Txid, cx: &Context<'_>) -> Option<D::MessageBufEtc> {
554 let InterestId(raw_id) = InterestId::from_txid(txid);
555 let interest = self.messages.get_mut(raw_id).expect("Polled unregistered interest");
556 match interest {
557 MessageInterest::Received(_) => {
558 return Some(self.messages.remove(raw_id).unwrap_received());
559 }
560 MessageInterest::Discard => panic!("Polled a discarded MessageReceiver?!"),
561 MessageInterest::WillPoll => self.waker_count += 1,
562 MessageInterest::Waiting(_) => {}
563 }
564 *interest = MessageInterest::Waiting(cx.waker().clone());
565 None
566 }
567
568 fn deregister(&mut self, txid: Txid) {
570 let InterestId(raw_id) = InterestId::from_txid(txid);
571 match self.messages[raw_id] {
572 MessageInterest::Received(_) => {
573 self.messages.remove(raw_id);
574 return;
575 }
576 MessageInterest::WillPoll => {}
577 MessageInterest::Waiting(_) => self.waker_count -= 1,
578 MessageInterest::Discard => unreachable!(),
579 }
580 self.messages[raw_id] = MessageInterest::Discard;
581 }
582
583 fn register_event_listener(&mut self, cx: &Context<'_>) -> Option<D::MessageBufEtc> {
585 self.events.pop_front().or_else(|| {
586 if !mem::replace(&mut self.event_listener, EventListener::Some(cx.waker().clone()))
587 .is_some()
588 {
589 self.waker_count += 1;
590 }
591 None
592 })
593 }
594
595 fn dropped_event_listener(&mut self) {
597 if self.event_listener.is_some() {
598 self.waker_count -= 1;
600 }
601 self.event_listener = EventListener::None;
602 }
603
604 fn register_msg_interest(&mut self) -> Txid {
609 self.generation = self.generation.wrapping_add(1);
610 Txid::from_interest_id(
613 InterestId(self.messages.insert(MessageInterest::WillPoll)),
614 self.generation,
615 )
616 }
617}
618
619impl<D: ResourceDialect> ClientInner<D> {
620 fn poll_recv_event(
621 self: &Arc<Self>,
622 cx: &Context<'_>,
623 ) -> Poll<Result<D::MessageBufEtc, Error>> {
624 if let Some(msg_buf) = self.interests.lock().register_event_listener(cx) {
626 return Poll::Ready(Ok(msg_buf));
627 }
628
629 let maybe_terminal_error = self.recv_all(Some(Txid(0)));
632
633 let mut lock = self.interests.lock();
634
635 if let Some(msg_buf) = lock.events.pop_front() {
636 Poll::Ready(Ok(msg_buf))
637 } else {
638 maybe_terminal_error?;
639 Poll::Pending
640 }
641 }
642
643 fn poll_recv_msg_response(
646 self: &Arc<Self>,
647 txid: Txid,
648 cx: &Context<'_>,
649 ) -> Poll<Result<D::MessageBufEtc, Error>> {
650 if let Some(buf) = self.interests.lock().register(txid, cx) {
652 return Poll::Ready(Ok(buf));
653 }
654
655 let maybe_terminal_error = self.recv_all(Some(txid));
658
659 let InterestId(raw_id) = InterestId::from_txid(txid);
660 let mut interests = self.interests.lock();
661 if interests.messages.get(raw_id).expect("Polled unregistered interest").is_received() {
662 let buf = interests.messages.remove(raw_id).unwrap_received();
665 Poll::Ready(Ok(buf))
666 } else {
667 maybe_terminal_error?;
668 Poll::Pending
669 }
670 }
671
672 fn recv_all(self: &Arc<Self>, want_txid: Option<Txid>) -> Result<(), Error> {
682 let mut terminal_error = self.terminal_error.lock();
686 if let Some(error) = terminal_error.as_ref() {
687 return Err(error.clone());
688 }
689
690 let recv_once = |waker| {
691 let cx = &mut Context::from_waker(&waker);
692
693 let mut buf = D::MessageBufEtc::new();
694 let result = self.channel.recv_etc_from(cx, &mut buf);
695 match result {
696 Poll::Ready(Ok(())) => {}
697 Poll::Ready(Err(None)) => {
698 return Err(Error::ClientChannelClosed {
701 epitaph: crate::error::Epitaph::PeerClosed,
702 protocol_name: self.protocol_name,
703 #[cfg(not(target_os = "fuchsia"))]
704 reason: self.channel.closed_reason(),
705 });
706 }
707 Poll::Ready(Err(Some(e))) => return Err(Error::ClientRead(e.into())),
708 Poll::Pending => return Ok(ControlFlow::Break(())),
709 };
710
711 let (bytes, _) = buf.split_mut();
712 let (header, body_bytes) = decode_transaction_header(bytes)?;
713 if header.is_epitaph() {
714 let handles = &mut [];
716 let mut epitaph_body = Decode::<EpitaphBody, D>::new_empty();
717 Decoder::<D>::decode_into::<EpitaphBody>(
718 &header,
719 body_bytes,
720 handles,
721 &mut epitaph_body,
722 )?;
723 return Err(Error::ClientChannelClosed {
724 epitaph: crate::error::Epitaph::Explicit(epitaph_body.error),
725 protocol_name: self.protocol_name,
726 #[cfg(not(target_os = "fuchsia"))]
727 reason: self.channel.closed_reason(),
728 });
729 }
730
731 let txid = Txid(header.tx_id);
732
733 let waker = {
734 buf.shrink_bytes_to_fit();
735 let mut interests = self.interests.lock();
736 if txid == Txid(0) {
737 interests.push_event(buf)
738 } else {
739 interests.push_message(txid, buf)?
740 }
741 };
742
743 if want_txid != Some(txid)
745 && let Some(waker) = waker
746 {
747 waker.wake();
748 }
749
750 Ok(ControlFlow::Continue(()))
751 };
752
753 loop {
754 let waker = {
755 let interests = self.interests.lock();
756 if interests.waker_count == 0 {
757 return Ok(());
758 } else if interests.waker_count == 1 {
759 if let Some(waker) = interests.event_waker() {
765 waker.clone()
766 } else {
767 interests
768 .messages
769 .iter()
770 .find_map(|(_, interest)| {
771 if let MessageInterest::Waiting(waker) = interest {
772 Some(waker.clone())
773 } else {
774 None
775 }
776 })
777 .unwrap()
778 }
779 } else {
780 let weak = Arc::downgrade(self);
781 let waker = ClientWaker(Arc::new(move || {
782 if let Some(strong) = weak.upgrade() {
783 #[cfg(target_os = "fuchsia")]
786 if strong.recv_all(None).is_ok() {
787 return;
788 }
789
790 strong.wake_all();
791 }
792 }));
793 unsafe {
798 Waker::from_raw(RawWaker::new(
799 Arc::into_raw(Arc::new(waker)) as *const (),
800 &WAKER_VTABLE,
801 ))
802 }
803 }
804 };
805
806 match recv_once(waker) {
807 Ok(ControlFlow::Continue(())) => {}
808 Ok(ControlFlow::Break(())) => return Ok(()),
809 Err(error) => {
810 self.wake_all();
812 return Err(terminal_error.insert(error).clone());
813 }
814 }
815 }
816 }
817
818 fn wake_all(&self) {
820 let mut lock = self.interests.lock();
821 for (_, interest) in &mut lock.messages {
822 if let MessageInterest::Waiting(_) = interest {
823 let MessageInterest::Waiting(waker) =
824 mem::replace(interest, MessageInterest::WillPoll)
825 else {
826 unreachable!()
827 };
828 waker.wake();
829 }
830 }
831 if let Some(waker) = lock.take_event_waker() {
832 waker.wake();
833 }
834 lock.waker_count = 0;
835 }
836}
837
838#[derive(Clone)]
839struct ClientWaker(Arc<dyn Fn() + Send + Sync + 'static>);
840
841static WAKER_VTABLE: RawWakerVTable =
842 RawWakerVTable::new(clone_waker, wake, wake_by_ref, drop_waker);
843
844unsafe fn clone_waker(data: *const ()) -> RawWaker {
845 unsafe { Arc::increment_strong_count(data as *const ClientWaker) };
846 RawWaker::new(data, &WAKER_VTABLE)
847}
848
849unsafe fn wake(data: *const ()) {
850 unsafe { Arc::from_raw(data as *const ClientWaker) }.0();
851}
852
853unsafe fn wake_by_ref(data: *const ()) {
854 mem::ManuallyDrop::new(unsafe { Arc::from_raw(data as *const ClientWaker) }).0();
855}
856
857unsafe fn drop_waker(data: *const ()) {
858 unsafe { Arc::from_raw(data as *const ClientWaker) };
859}
860
861#[cfg(target_os = "fuchsia")]
862pub mod sync {
863 use super::*;
866 use crate::endpoints::ProtocolMarker;
867 use std::mem::MaybeUninit;
868 use zx::MessageBufEtc;
869
870 #[derive(Debug)]
872 pub struct Client {
873 channel: zx::Channel,
875 }
876
877 impl Client {
878 pub fn new(channel: zx::Channel) -> Self {
880 Client { channel }
881 }
882
883 pub fn as_channel(&self) -> &zx::Channel {
885 &self.channel
886 }
887
888 pub fn into_channel(self) -> zx::Channel {
890 self.channel
891 }
892
893 pub fn send<T: TypeMarker>(
895 &self,
896 body: impl Encode<T, DefaultFuchsiaResourceDialect>,
897 ordinal: u64,
898 dynamic_flags: DynamicFlags,
899 ) -> Result<(), Error> {
900 let mut write_bytes = Vec::new();
901 let mut write_handles = Vec::new();
902 let msg = TransactionMessage {
903 header: TransactionHeader::new(0, ordinal, dynamic_flags),
904 body,
905 };
906 Encoder::encode::<TransactionMessageType<T>>(
907 &mut write_bytes,
908 &mut write_handles,
909 msg,
910 )?;
911 match self.channel.write_etc(&write_bytes, &mut write_handles) {
912 Ok(()) | Err(zx_status::Status::PEER_CLOSED) => Ok(()),
913 Err(e) => Err(Error::ClientWrite(e.into())),
914 }
915 }
916
917 pub fn send_query<Request: TypeMarker, Response: TypeMarker, P: ProtocolMarker>(
919 &self,
920 body: impl Encode<Request, DefaultFuchsiaResourceDialect>,
921 ordinal: u64,
922 dynamic_flags: DynamicFlags,
923 deadline: zx::MonotonicInstant,
924 ) -> Result<Response::Owned, Error>
925 where
926 Response::Owned: Decode<Response, DefaultFuchsiaResourceDialect>,
927 {
928 let mut write_bytes = Vec::new();
929 let mut write_handles = Vec::new();
930
931 let msg = TransactionMessage {
932 header: TransactionHeader::new(0, ordinal, dynamic_flags),
933 body,
934 };
935 Encoder::encode::<TransactionMessageType<Request>>(
936 &mut write_bytes,
937 &mut write_handles,
938 msg,
939 )?;
940
941 let mut bytes_out =
944 Vec::<MaybeUninit<u8>>::with_capacity(zx::sys::ZX_CHANNEL_MAX_MSG_BYTES as usize);
945 unsafe { bytes_out.set_len(zx::sys::ZX_CHANNEL_MAX_MSG_BYTES as usize) };
948
949 let handles_out = &mut [const { MaybeUninit::<zx::HandleInfo>::uninit() };
953 zx::sys::ZX_CHANNEL_MAX_MSG_HANDLES as usize];
954
955 let (bytes_out, handles_out) = self
958 .channel
959 .call_etc_uninit(
960 deadline,
961 &write_bytes,
962 &mut write_handles,
963 bytes_out.as_mut_slice(),
964 handles_out,
965 )
966 .map_err(|e| self.wrap_error::<P, _>(Error::ClientCall, e))?;
967
968 let (header, body_bytes) = decode_transaction_header(bytes_out)?;
969 if header.ordinal != ordinal {
970 return Err(Error::InvalidResponseOrdinal);
971 }
972 let mut output = Decode::<Response, DefaultFuchsiaResourceDialect>::new_empty();
973 Decoder::<DefaultFuchsiaResourceDialect>::decode_into::<Response>(
974 &header,
975 body_bytes,
976 handles_out,
977 &mut output,
978 )?;
979 Ok(output)
980 }
981
982 pub fn wait_for_event<P: ProtocolMarker>(
984 &self,
985 deadline: zx::MonotonicInstant,
986 ) -> Result<MessageBufEtc, Error> {
987 let mut buf = zx::MessageBufEtc::new();
988 buf.ensure_capacity_bytes(zx::sys::ZX_CHANNEL_MAX_MSG_BYTES as usize);
989 buf.ensure_capacity_handle_infos(zx::sys::ZX_CHANNEL_MAX_MSG_HANDLES as usize);
990
991 loop {
992 self.channel
993 .wait_one(
994 zx::Signals::CHANNEL_READABLE | zx::Signals::CHANNEL_PEER_CLOSED,
995 deadline,
996 )
997 .map_err(|e| self.wrap_error::<P, _>(Error::ClientEvent, e))?;
998 match self.channel.read_etc(&mut buf) {
999 Ok(()) => {
1000 let (header, body_bytes) = decode_transaction_header(buf.bytes())
1003 .map_err(|_| Error::InvalidHeader)?;
1004 if header.is_epitaph() {
1005 let handles = &mut [];
1008 let mut epitaph_body =
1009 Decode::<EpitaphBody, DefaultFuchsiaResourceDialect>::new_empty();
1010 Decoder::<DefaultFuchsiaResourceDialect>::decode_into::<EpitaphBody>(
1011 &header,
1012 body_bytes,
1013 handles,
1014 &mut epitaph_body,
1015 )?;
1016 return Err(Error::ClientChannelClosed {
1017 epitaph: crate::error::Epitaph::Explicit(epitaph_body.error),
1018 protocol_name: P::DEBUG_NAME,
1019 });
1020 }
1021 if header.tx_id != 0 {
1022 return Err(Error::UnexpectedSyncResponse);
1023 }
1024 return Ok(buf);
1025 }
1026 Err(zx::Status::SHOULD_WAIT) => {
1027 continue;
1029 }
1030 Err(e) => {
1031 return Err(self.wrap_error::<P, _>(|x| Error::ClientRead(x.into()), e));
1032 }
1033 }
1034 }
1035 }
1036
1037 fn wrap_error<P: ProtocolMarker, T: Fn(zx_status::Status) -> Error>(
1041 &self,
1042 variant: T,
1043 err: zx_status::Status,
1044 ) -> Error {
1045 if err == zx_status::Status::PEER_CLOSED {
1046 Error::ClientChannelClosed {
1047 epitaph: crate::error::Epitaph::PeerClosed,
1048 protocol_name: P::DEBUG_NAME,
1049 }
1050 } else {
1051 variant(err)
1052 }
1053 }
1054 }
1055}
1056
1057#[cfg(all(test, target_os = "fuchsia"))]
1058mod tests {
1059 use super::*;
1060 use crate::encoding::MAGIC_NUMBER_INITIAL;
1061 use crate::endpoints::{ControlHandle, ProtocolMarker, Proxy, RequestStream, SynchronousProxy};
1062 use crate::epitaph::{self, ChannelEpitaphExt};
1063 use crate::{Channel, OnSignalsRef, ServeInner};
1064 use anyhow::{Context as _, Error};
1065 use assert_matches::assert_matches;
1066 use fuchsia_async as fasync;
1067 use fuchsia_async::{Channel as AsyncChannel, DurationExt, TimeoutExt};
1068 use futures::channel::oneshot;
1069 use futures::stream::{FuturesUnordered, Stream};
1070 use futures::{StreamExt, TryFutureExt, join};
1071 use futures_test::task::new_count_waker;
1072 use std::future::pending;
1073 use std::task::{Wake, Waker};
1074 use std::thread;
1075 use zx::MessageBufEtc;
1076
1077 const SEND_ORDINAL_HIGH_BYTE: u8 = 42;
1078 const SEND_ORDINAL: u64 = 42 << 32;
1079 const SEND_DATA: u8 = 55;
1080
1081 const EVENT_ORDINAL: u64 = 854 << 23;
1082
1083 struct TestProtocolMarker;
1084 impl ProtocolMarker for TestProtocolMarker {
1085 type Proxy = TestProxy;
1086 type SynchronousProxy = TestSynchronousProxy;
1087 type RequestStream = TestRequestStream;
1088 const DEBUG_NAME: &str = "test_protocol";
1089 }
1090
1091 struct TestProxy;
1092 impl Proxy for TestProxy {
1093 type Protocol = TestProtocolMarker;
1094 fn from_channel(_inner: AsyncChannel) -> Self {
1095 unimplemented!();
1096 }
1097 fn into_channel(self) -> Result<AsyncChannel, Self> {
1098 unimplemented!();
1099 }
1100 fn as_channel(&self) -> &AsyncChannel {
1101 unimplemented!();
1102 }
1103 }
1104
1105 struct TestSynchronousProxy;
1106 impl SynchronousProxy for TestSynchronousProxy {
1107 type Proxy = TestProxy;
1108 type Protocol = TestProtocolMarker;
1109 fn from_channel(_inner: Channel) -> Self {
1110 unimplemented!();
1111 }
1112 fn into_channel(self) -> Channel {
1113 unimplemented!();
1114 }
1115 fn as_channel(&self) -> &Channel {
1116 unimplemented!();
1117 }
1118 }
1119
1120 struct TestRequestStream;
1121 impl RequestStream for TestRequestStream {
1122 type Protocol = TestProtocolMarker;
1123 type ControlHandle = TestControlHandle;
1124 fn control_handle(&self) -> Self::ControlHandle {
1125 unimplemented!();
1126 }
1127 fn from_channel(_inner: AsyncChannel) -> Self {
1128 unimplemented!();
1129 }
1130 fn into_inner(self) -> (Arc<ServeInner>, bool) {
1131 unimplemented!();
1132 }
1133
1134 fn from_inner(_inner: Arc<ServeInner>, _is_terminated: bool) -> Self {
1135 unimplemented!();
1136 }
1137 }
1138 impl Stream for TestRequestStream {
1139 type Item = Result<(), crate::Error>;
1140 fn poll_next(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
1141 unimplemented!();
1142 }
1143 }
1144
1145 struct TestControlHandle;
1146 impl ControlHandle for TestControlHandle {
1147 fn shutdown(&self) {
1148 unimplemented!();
1149 }
1150 fn shutdown_with_epitaph(&self, _status: crate::Epitaph) {
1151 unimplemented!();
1152 }
1153 fn is_closed(&self) -> bool {
1154 unimplemented!();
1155 }
1156 fn on_closed(&self) -> OnSignalsRef<'_> {
1157 unimplemented!();
1158 }
1159 fn signal_peer(
1160 &self,
1161 _clear_mask: zx::Signals,
1162 _set_mask: zx::Signals,
1163 ) -> Result<(), zx_status::Status> {
1164 unimplemented!();
1165 }
1166 }
1167
1168 #[rustfmt::skip]
1169 fn expected_sent_bytes(txid_index: u8, txid_generation: u8) -> [u8; 24] {
1170 [
1171 txid_index, 0, 0, txid_generation, 2, 0, 0, MAGIC_NUMBER_INITIAL,
1174 0, 0, 0, 0, SEND_ORDINAL_HIGH_BYTE, 0, 0, 0, SEND_DATA, 0, 0, 0, 0, 0, 0, 0, ]
1179 }
1180
1181 fn expected_sent_bytes_oneway() -> [u8; 24] {
1182 expected_sent_bytes(0, 0)
1183 }
1184
1185 fn send_transaction(header: TransactionHeader, channel: &zx::Channel) {
1186 let (bytes, handles) = (&mut vec![], &mut vec![]);
1187 encode_transaction(header, bytes, handles);
1188 channel.write_etc(bytes, handles).expect("Server channel write failed");
1189 }
1190
1191 fn encode_transaction(
1192 header: TransactionHeader,
1193 bytes: &mut Vec<u8>,
1194 handles: &mut Vec<zx::HandleDisposition<'static>>,
1195 ) {
1196 let event = TransactionMessage { header, body: SEND_DATA };
1197 Encoder::<DefaultFuchsiaResourceDialect>::encode::<TransactionMessageType<u8>>(
1198 bytes, handles, event,
1199 )
1200 .expect("Encoding failure");
1201 }
1202
1203 #[test]
1204 fn sync_client() -> Result<(), Error> {
1205 let (client_end, server_end) = zx::Channel::create();
1206 let client = sync::Client::new(client_end);
1207 client.send::<u8>(SEND_DATA, SEND_ORDINAL, DynamicFlags::empty()).context("sending")?;
1208 let mut received = MessageBufEtc::new();
1209 server_end.read_etc(&mut received).context("reading")?;
1210 assert_eq!(received.bytes(), expected_sent_bytes_oneway());
1211 Ok(())
1212 }
1213
1214 #[test]
1215 fn sync_client_with_response() -> Result<(), Error> {
1216 let (client_end, server_end) = zx::Channel::create();
1217 let client = sync::Client::new(client_end);
1218 thread::spawn(move || {
1219 let mut received = MessageBufEtc::new();
1221 server_end
1222 .wait_one(
1223 zx::Signals::CHANNEL_READABLE,
1224 zx::MonotonicInstant::after(zx::MonotonicDuration::from_seconds(5)),
1225 )
1226 .expect("failed to wait for channel readable");
1227 server_end.read_etc(&mut received).expect("failed to read on server end");
1228 let (buf, _handles) = received.split_mut();
1229 let (header, _body_bytes) = decode_transaction_header(buf).expect("server decode");
1230 assert_eq!(header.ordinal, SEND_ORDINAL);
1231 send_transaction(
1232 TransactionHeader::new(header.tx_id, header.ordinal, DynamicFlags::empty()),
1233 &server_end,
1234 );
1235 });
1236 let response_data = client
1237 .send_query::<u8, u8, TestProtocolMarker>(
1238 SEND_DATA,
1239 SEND_ORDINAL,
1240 DynamicFlags::empty(),
1241 zx::MonotonicInstant::after(zx::MonotonicDuration::from_seconds(5)),
1242 )
1243 .context("sending query")?;
1244 assert_eq!(SEND_DATA, response_data);
1245 Ok(())
1246 }
1247
1248 #[test]
1249 fn sync_client_with_event_and_response() -> Result<(), Error> {
1250 let (client_end, server_end) = zx::Channel::create();
1251 let client = sync::Client::new(client_end);
1252 thread::spawn(move || {
1253 let mut received = MessageBufEtc::new();
1255 server_end
1256 .as_handle_ref()
1257 .wait_one(
1258 zx::Signals::CHANNEL_READABLE,
1259 zx::MonotonicInstant::after(zx::MonotonicDuration::from_seconds(5)),
1260 )
1261 .expect("failed to wait for channel readable");
1262 server_end.read_etc(&mut received).expect("failed to read on server end");
1263 let (buf, _handles) = received.split_mut();
1264 let (header, _body_bytes) = decode_transaction_header(buf).expect("server decode");
1265 assert_ne!(header.tx_id, 0);
1266 assert_eq!(header.ordinal, SEND_ORDINAL);
1267 send_transaction(
1269 TransactionHeader::new(0, EVENT_ORDINAL, DynamicFlags::empty()),
1270 &server_end,
1271 );
1272 send_transaction(
1275 TransactionHeader::new(header.tx_id, header.ordinal, DynamicFlags::empty()),
1276 &server_end,
1277 );
1278 });
1279 let response_data = client
1280 .send_query::<u8, u8, TestProtocolMarker>(
1281 SEND_DATA,
1282 SEND_ORDINAL,
1283 DynamicFlags::empty(),
1284 zx::MonotonicInstant::after(zx::MonotonicDuration::from_seconds(5)),
1285 )
1286 .context("sending query")?;
1287 assert_eq!(SEND_DATA, response_data);
1288
1289 let event_buf = client
1290 .wait_for_event::<TestProtocolMarker>(zx::MonotonicInstant::after(
1291 zx::MonotonicDuration::from_seconds(5),
1292 ))
1293 .context("waiting for event")?;
1294 let (bytes, _handles) = event_buf.split();
1295 let (header, _body) = decode_transaction_header(&bytes).expect("event decode");
1296 assert_eq!(header.ordinal, EVENT_ORDINAL);
1297
1298 Ok(())
1299 }
1300
1301 #[test]
1302 fn sync_client_with_racing_events() -> Result<(), Error> {
1303 let (client_end, server_end) = zx::Channel::create();
1304 let client1 = Arc::new(sync::Client::new(client_end));
1305 let client2 = client1.clone();
1306
1307 let thread1 = thread::spawn(move || {
1308 let result = client1.wait_for_event::<TestProtocolMarker>(zx::MonotonicInstant::after(
1309 zx::MonotonicDuration::from_seconds(5),
1310 ));
1311 assert!(result.is_ok());
1312 });
1313
1314 let thread2 = thread::spawn(move || {
1315 let result = client2.wait_for_event::<TestProtocolMarker>(zx::MonotonicInstant::after(
1316 zx::MonotonicDuration::from_seconds(5),
1317 ));
1318 assert!(result.is_ok());
1319 });
1320
1321 send_transaction(
1322 TransactionHeader::new(0, EVENT_ORDINAL, DynamicFlags::empty()),
1323 &server_end,
1324 );
1325 send_transaction(
1326 TransactionHeader::new(0, EVENT_ORDINAL, DynamicFlags::empty()),
1327 &server_end,
1328 );
1329
1330 assert!(thread1.join().is_ok());
1331 assert!(thread2.join().is_ok());
1332
1333 Ok(())
1334 }
1335
1336 #[test]
1337 fn sync_client_wait_for_event_gets_method_response() -> Result<(), Error> {
1338 let (client_end, server_end) = zx::Channel::create();
1339 let client = sync::Client::new(client_end);
1340 send_transaction(
1341 TransactionHeader::new(3902304923, SEND_ORDINAL, DynamicFlags::empty()),
1342 &server_end,
1343 );
1344 assert_matches!(
1345 client.wait_for_event::<TestProtocolMarker>(zx::MonotonicInstant::after(
1346 zx::MonotonicDuration::from_seconds(5)
1347 )),
1348 Err(crate::Error::UnexpectedSyncResponse)
1349 );
1350 Ok(())
1351 }
1352
1353 #[test]
1354 fn sync_client_one_way_call_suceeds_after_peer_closed() -> Result<(), Error> {
1355 let (client_end, server_end) = zx::Channel::create();
1356 let client = sync::Client::new(client_end);
1357 drop(server_end);
1358 assert_matches!(client.send::<u8>(SEND_DATA, SEND_ORDINAL, DynamicFlags::empty()), Ok(()));
1359 Ok(())
1360 }
1361
1362 #[test]
1363 fn sync_client_two_way_call_fails_after_peer_closed() -> Result<(), Error> {
1364 let (client_end, server_end) = zx::Channel::create();
1365 let client = sync::Client::new(client_end);
1366 drop(server_end);
1367 assert_matches!(
1368 client.send_query::<u8, u8, TestProtocolMarker>(
1369 SEND_DATA,
1370 SEND_ORDINAL,
1371 DynamicFlags::empty(),
1372 zx::MonotonicInstant::after(zx::MonotonicDuration::from_seconds(5))
1373 ),
1374 Err(crate::Error::ClientChannelClosed {
1375 epitaph: crate::error::Epitaph::PeerClosed,
1376 protocol_name: "test_protocol",
1377 })
1378 );
1379 Ok(())
1380 }
1381
1382 #[test]
1385 fn sync_client_send_does_not_receive_epitaphs() -> Result<(), Error> {
1386 let (client_end, server_end) = zx::Channel::create();
1387 let client = sync::Client::new(client_end);
1388 server_end
1390 .close_with_epitaph(zx_status::Status::UNAVAILABLE)
1391 .expect("failed to write epitaph");
1392 assert_matches!(
1393 client.send_query::<u8, u8, TestProtocolMarker>(
1394 SEND_DATA,
1395 SEND_ORDINAL,
1396 DynamicFlags::empty(),
1397 zx::MonotonicInstant::after(zx::MonotonicDuration::from_seconds(5))
1398 ),
1399 Err(crate::Error::ClientChannelClosed {
1400 epitaph: crate::error::Epitaph::PeerClosed,
1401 protocol_name: "test_protocol",
1402 })
1403 );
1404 Ok(())
1405 }
1406
1407 #[test]
1408 fn sync_client_wait_for_events_does_receive_epitaphs() -> Result<(), Error> {
1409 let (client_end, server_end) = zx::Channel::create();
1410 let client = sync::Client::new(client_end);
1411 server_end
1413 .close_with_epitaph(zx_status::Status::UNAVAILABLE)
1414 .expect("failed to write epitaph");
1415 assert_matches!(
1416 client.wait_for_event::<TestProtocolMarker>(zx::MonotonicInstant::after(
1417 zx::MonotonicDuration::from_seconds(5)
1418 )),
1419 Err(crate::Error::ClientChannelClosed {
1420 epitaph: crate::error::Epitaph::Explicit(Err(zx_status::Status::UNAVAILABLE)),
1421 protocol_name: "test_protocol",
1422 })
1423 );
1424 Ok(())
1425 }
1426
1427 #[test]
1428 fn sync_client_into_channel() -> Result<(), Error> {
1429 let (client_end, _server_end) = zx::Channel::create();
1430 let client_end_raw = client_end.raw_handle();
1431 let client = sync::Client::new(client_end);
1432 assert_eq!(client.into_channel().raw_handle(), client_end_raw);
1433 Ok(())
1434 }
1435
1436 #[fasync::run_singlethreaded(test)]
1437 async fn client() {
1438 let (client_end, server_end) = zx::Channel::create();
1439 let client_end = AsyncChannel::from_channel(client_end);
1440 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
1441
1442 let server = AsyncChannel::from_channel(server_end);
1443 let receiver = async move {
1444 let mut buffer = MessageBufEtc::new();
1445 server.recv_etc_msg(&mut buffer).await.expect("failed to recv msg");
1446 assert_eq!(buffer.bytes(), expected_sent_bytes_oneway());
1447 };
1448
1449 let receiver = receiver
1451 .on_timeout(zx::MonotonicDuration::from_millis(300).after_now(), || {
1452 panic!("did not receive message in time!")
1453 });
1454
1455 client
1456 .send::<u8>(SEND_DATA, SEND_ORDINAL, DynamicFlags::empty())
1457 .expect("failed to send msg");
1458
1459 receiver.await;
1460 }
1461
1462 #[fasync::run_singlethreaded(test)]
1463 async fn client_with_response() {
1464 let (client_end, server_end) = zx::Channel::create();
1465 let client_end = AsyncChannel::from_channel(client_end);
1466 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
1467
1468 let server = AsyncChannel::from_channel(server_end);
1469 let mut buffer = MessageBufEtc::new();
1470 let receiver = async move {
1471 server.recv_etc_msg(&mut buffer).await.expect("failed to recv msg");
1472 let two_way_tx_id = 1u8;
1473 assert_eq!(buffer.bytes(), expected_sent_bytes(two_way_tx_id, 1));
1474
1475 let (bytes, handles) = (&mut vec![], &mut vec![]);
1476 let header =
1477 TransactionHeader::new(two_way_tx_id as u32, SEND_ORDINAL, DynamicFlags::empty());
1478 encode_transaction(header, bytes, handles);
1479 server.write_etc(bytes, handles).expect("Server channel write failed");
1480 };
1481
1482 let receiver = receiver
1484 .on_timeout(zx::MonotonicDuration::from_millis(300).after_now(), || {
1485 panic!("did not receiver message in time!")
1486 });
1487
1488 let sender = client
1489 .send_query::<u8, u8, SEND_ORDINAL>(SEND_DATA, DynamicFlags::empty())
1490 .map_ok(|x| assert_eq!(x, SEND_DATA))
1491 .unwrap_or_else(|e| panic!("fidl error: {e:?}"));
1492
1493 let sender = sender.on_timeout(zx::MonotonicDuration::from_millis(300).after_now(), || {
1495 panic!("did not receive response in time!")
1496 });
1497
1498 let ((), ()) = join!(receiver, sender);
1499 }
1500
1501 #[fasync::run_singlethreaded(test)]
1502 async fn client_with_response_receives_epitaph() {
1503 let (client_end, server_end) = zx::Channel::create();
1504 let client_end = AsyncChannel::from_channel(client_end);
1505 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
1506
1507 let server = AsyncChannel::from_channel(server_end);
1508 let mut buffer = zx::MessageBufEtc::new();
1509 let receiver = async move {
1510 server.recv_etc_msg(&mut buffer).await.expect("failed to recv msg");
1511 server
1512 .close_with_epitaph(zx_status::Status::UNAVAILABLE)
1513 .expect("failed to write epitaph");
1514 };
1515 let receiver = receiver
1517 .on_timeout(zx::MonotonicDuration::from_millis(300).after_now(), || {
1518 panic!("did not receive message in time!")
1519 });
1520
1521 let sender = async move {
1522 const ORDINAL: u64 = 42 << 32;
1523 let result = client.send_query::<u8, u8, ORDINAL>(55, DynamicFlags::empty()).await;
1524 assert_matches!(
1525 result,
1526 Err(crate::Error::ClientChannelClosed {
1527 epitaph: crate::error::Epitaph::Explicit(Err(zx_status::Status::UNAVAILABLE)),
1528 protocol_name: "test_protocol",
1529 })
1530 );
1531 };
1532 let sender = sender.on_timeout(zx::MonotonicDuration::from_millis(300).after_now(), || {
1534 panic!("did not receive response in time!")
1535 });
1536
1537 let ((), ()) = join!(receiver, sender);
1538 }
1539
1540 #[fasync::run_singlethreaded(test)]
1541 #[should_panic]
1542 async fn event_cant_be_taken_twice() {
1543 let (client_end, _) = zx::Channel::create();
1544 let client_end = AsyncChannel::from_channel(client_end);
1545 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
1546 let _foo = client.take_event_receiver();
1547 client.take_event_receiver();
1548 }
1549
1550 #[fasync::run_singlethreaded(test)]
1551 async fn event_can_be_taken_after_drop() {
1552 let (client_end, _) = zx::Channel::create();
1553 let client_end = AsyncChannel::from_channel(client_end);
1554 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
1555 let foo = client.take_event_receiver();
1556 drop(foo);
1557 client.take_event_receiver();
1558 }
1559
1560 #[fasync::run_singlethreaded(test)]
1561 async fn receiver_termination_test() {
1562 let (client_end, _) = zx::Channel::create();
1563 let client_end = AsyncChannel::from_channel(client_end);
1564 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
1565 let mut foo = client.take_event_receiver();
1566 assert!(!foo.is_terminated(), "receiver should not report terminated before being polled");
1567 let _ = foo.next().await;
1568 assert!(
1569 foo.is_terminated(),
1570 "receiver should report terminated after seeing channel is closed"
1571 );
1572 }
1573
1574 #[fasync::run_singlethreaded(test)]
1575 #[should_panic(expected = "polled EventReceiver after `None`")]
1576 async fn receiver_cant_be_polled_more_than_once_on_closed_stream() {
1577 let (client_end, _) = zx::Channel::create();
1578 let client_end = AsyncChannel::from_channel(client_end);
1579 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
1580 let foo = client.take_event_receiver();
1581 drop(foo);
1582 let mut bar = client.take_event_receiver();
1583 assert!(bar.next().await.is_none(), "read on closed channel should return none");
1584 let _ = bar.next().await;
1586 }
1587
1588 #[fasync::run_singlethreaded(test)]
1589 #[should_panic(expected = "polled EventReceiver after `None`")]
1590 async fn receiver_panics_when_polled_after_receiving_epitaph_then_none() {
1591 let (client_end, server_end) = zx::Channel::create();
1592 let client_end = AsyncChannel::from_channel(client_end);
1593 let server_end = AsyncChannel::from_channel(server_end);
1594 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
1595 let mut stream = client.take_event_receiver();
1596
1597 epitaph::write_epitaph_impl(&server_end, Err(zx_status::Status::UNAVAILABLE))
1598 .expect("wrote epitaph");
1599 drop(server_end);
1600
1601 assert_matches!(
1602 stream.next().await,
1603 Some(Err(crate::Error::ClientChannelClosed {
1604 epitaph: crate::error::Epitaph::Explicit(Err(zx_status::Status::UNAVAILABLE)),
1605 protocol_name: "test_protocol",
1606 }))
1607 );
1608 assert_matches!(stream.next().await, None);
1609 let _ = stream.next().await;
1611 }
1612
1613 #[fasync::run_singlethreaded(test)]
1614 async fn event_can_be_taken() {
1615 let (client_end, _) = zx::Channel::create();
1616 let client_end = AsyncChannel::from_channel(client_end);
1617 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
1618 client.take_event_receiver();
1619 }
1620
1621 #[fasync::run_singlethreaded(test)]
1622 async fn event_received() {
1623 let (client_end, server_end) = zx::Channel::create();
1624 let client_end = AsyncChannel::from_channel(client_end);
1625 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
1626
1627 let server = AsyncChannel::from_channel(server_end);
1629 let (bytes, handles) = (&mut vec![], &mut vec![]);
1630 const ORDINAL: u64 = 5;
1631 let header = TransactionHeader::new(0, ORDINAL, DynamicFlags::empty());
1632 encode_transaction(header, bytes, handles);
1633 server.write_etc(bytes, handles).expect("Server channel write failed");
1634 drop(server);
1635
1636 let recv = client
1637 .take_event_receiver()
1638 .into_future()
1639 .then(|(x, stream)| {
1640 let x = x.expect("should contain one element");
1641 let x = x.expect("fidl error");
1642 let x: i32 =
1643 decode_transaction_body::<i32, DefaultFuchsiaResourceDialect, ORDINAL>(x)
1644 .expect("failed to decode event");
1645 assert_eq!(x, 55);
1646 stream.into_future()
1647 })
1648 .map(|(x, _stream)| assert!(x.is_none(), "should have emptied"));
1649
1650 let recv = recv.on_timeout(zx::MonotonicDuration::from_millis(300).after_now(), || {
1652 panic!("did not receive event in time!")
1653 });
1654
1655 recv.await;
1656 }
1657
1658 #[fasync::run_singlethreaded(test)]
1662 async fn receiver_can_be_taken_after_end_of_stream() {
1663 let (client_end, server_end) = zx::Channel::create();
1664 let client_end = AsyncChannel::from_channel(client_end);
1665 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
1666
1667 let server = AsyncChannel::from_channel(server_end);
1669 let (bytes, handles) = (&mut vec![], &mut vec![]);
1670 const ORDINAL: u64 = 5;
1671 let header = TransactionHeader::new(0, ORDINAL, DynamicFlags::empty());
1672 encode_transaction(header, bytes, handles);
1673 server.write_etc(bytes, handles).expect("Server channel write failed");
1674 drop(server);
1675
1676 {
1680 let recv = client
1681 .take_event_receiver()
1682 .into_future()
1683 .then(|(x, stream)| {
1684 let x = x.expect("should contain one element");
1685 let x = x.expect("fidl error");
1686 let x: i32 =
1687 decode_transaction_body::<i32, DefaultFuchsiaResourceDialect, ORDINAL>(x)
1688 .expect("failed to decode event");
1689 assert_eq!(x, 55);
1690 stream.into_future()
1691 })
1692 .map(|(x, _stream)| assert!(x.is_none(), "should have emptied"));
1693
1694 let recv = recv.on_timeout(zx::MonotonicDuration::from_millis(300).after_now(), || {
1696 panic!("did not receive event in time!")
1697 });
1698
1699 recv.await;
1700 }
1701
1702 let mut c = client.take_event_receiver();
1705 assert!(
1706 c.next().await.is_none(),
1707 "receiver on closed channel should return none on first call"
1708 );
1709 }
1710
1711 #[fasync::run_singlethreaded(test)]
1712 async fn event_incompatible_format() {
1713 let (client_end, server_end) = zx::Channel::create();
1714 let client_end = AsyncChannel::from_channel(client_end);
1715 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
1716
1717 let server = AsyncChannel::from_channel(server_end);
1719 let (bytes, handles) = (&mut vec![], &mut vec![]);
1720 let header = TransactionHeader::new_full(
1721 0,
1722 5,
1723 crate::encoding::Context {
1724 wire_format_version: crate::encoding::WireFormatVersion::V2,
1725 },
1726 DynamicFlags::empty(),
1727 0,
1728 );
1729 encode_transaction(header, bytes, handles);
1730 server.write_etc(bytes, handles).expect("Server channel write failed");
1731 drop(server);
1732
1733 let mut event_receiver = client.take_event_receiver();
1734 let recv = event_receiver.next().map(|event| {
1735 assert_matches!(event, Some(Err(crate::Error::IncompatibleMagicNumber(0))))
1736 });
1737
1738 let recv = recv.on_timeout(zx::MonotonicDuration::from_millis(300).after_now(), || {
1740 panic!("did not receive event in time!")
1741 });
1742
1743 recv.await;
1744 }
1745
1746 #[test]
1747 fn client_always_wakes_pending_futures() {
1748 let mut executor = fasync::TestExecutor::new();
1749
1750 let (client_end, server_end) = zx::Channel::create();
1751 let client_end = AsyncChannel::from_channel(client_end);
1752 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
1753
1754 let mut event_receiver = client.take_event_receiver();
1755
1756 let (response_waker, response_waker_count) = new_count_waker();
1758 let response_cx = &mut Context::from_waker(&response_waker);
1759 let mut response_txid = Txid(0);
1760 let mut response_future = client
1761 .send_raw_query(|tx_id, bytes, handles| {
1762 response_txid = tx_id;
1763 let header = TransactionHeader::new(
1764 response_txid.as_raw_id(),
1765 SEND_ORDINAL,
1766 DynamicFlags::empty(),
1767 );
1768 encode_transaction(header, bytes, handles);
1769 Ok(())
1770 })
1771 .expect("Couldn't send query");
1772 assert!(response_future.poll_unpin(response_cx).is_pending());
1773
1774 let (event_waker, event_waker_count) = new_count_waker();
1776 let event_cx = &mut Context::from_waker(&event_waker);
1777 assert!(event_receiver.poll_next_unpin(event_cx).is_pending());
1778
1779 assert_eq!(response_waker_count.get(), 0);
1781 assert_eq!(event_waker_count.get(), 0);
1782
1783 send_transaction(TransactionHeader::new(0, 5, DynamicFlags::empty()), &server_end);
1785
1786 let _ = executor.run_until_stalled(&mut future::pending::<()>());
1788
1789 assert_eq!(response_waker_count.get(), 0);
1791 assert_eq!(event_waker_count.get(), 1);
1792
1793 assert!(event_receiver.poll_next_unpin(event_cx).is_ready());
1795
1796 send_transaction(
1798 TransactionHeader::new(response_txid.as_raw_id(), SEND_ORDINAL, DynamicFlags::empty()),
1799 &server_end,
1800 );
1801
1802 let _ = executor.run_until_stalled(&mut future::pending::<()>());
1804
1805 assert_eq!(response_waker_count.get(), 1);
1807 }
1808
1809 #[test]
1810 fn client_always_wakes_pending_futures_on_epitaph() {
1811 let mut executor = fasync::TestExecutor::new();
1812
1813 let (client_end, server_end) = zx::Channel::create();
1814 let client_end = AsyncChannel::from_channel(client_end);
1815 let server_end = AsyncChannel::from_channel(server_end);
1816 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
1817
1818 let mut event_receiver = client.take_event_receiver();
1819
1820 let (response1_waker, response1_waker_count) = new_count_waker();
1822 let response1_cx = &mut Context::from_waker(&response1_waker);
1823 let mut response1_future = client
1824 .send_raw_query(|tx_id, bytes, handles| {
1825 let header =
1826 TransactionHeader::new(tx_id.as_raw_id(), SEND_ORDINAL, DynamicFlags::empty());
1827 encode_transaction(header, bytes, handles);
1828 Ok(())
1829 })
1830 .expect("Couldn't send query");
1831 assert!(response1_future.poll_unpin(response1_cx).is_pending());
1832
1833 let (event_waker, event_waker_count) = new_count_waker();
1835 let event_cx = &mut Context::from_waker(&event_waker);
1836 assert!(event_receiver.poll_next_unpin(event_cx).is_pending());
1837
1838 let (response2_waker, response2_waker_count) = new_count_waker();
1840 let response2_cx = &mut Context::from_waker(&response2_waker);
1841 let mut response2_future = client
1842 .send_raw_query(|tx_id, bytes, handles| {
1843 let header =
1844 TransactionHeader::new(tx_id.as_raw_id(), SEND_ORDINAL, DynamicFlags::empty());
1845 encode_transaction(header, bytes, handles);
1846 Ok(())
1847 })
1848 .expect("Couldn't send query");
1849 assert!(response2_future.poll_unpin(response2_cx).is_pending());
1850
1851 let wakers = vec![response1_waker_count, response2_waker_count, event_waker_count];
1852
1853 let _ = executor.run_until_stalled(&mut future::pending::<()>());
1855
1856 assert_eq!(0, wakers.iter().fold(0, |acc, x| acc + x.get()));
1858
1859 epitaph::write_epitaph_impl(&server_end, Err(zx_status::Status::UNAVAILABLE))
1861 .expect("wrote epitaph");
1862
1863 let _ = executor.run_until_stalled(&mut future::pending::<()>());
1865
1866 for wake_count in &wakers {
1869 assert_eq!(wake_count.get(), 1);
1870 }
1871
1872 assert_matches!(
1874 response1_future.poll_unpin(response1_cx),
1875 Poll::Ready(Err(crate::Error::ClientChannelClosed {
1876 epitaph: crate::error::Epitaph::Explicit(Err(zx_status::Status::UNAVAILABLE)),
1877 protocol_name: "test_protocol",
1878 }))
1879 );
1880
1881 let _ = executor.run_until_stalled(&mut future::pending::<()>());
1883
1884 assert_matches!(
1886 response2_future.poll_unpin(response2_cx),
1887 Poll::Ready(Err(crate::Error::ClientChannelClosed {
1888 epitaph: crate::error::Epitaph::Explicit(Err(zx_status::Status::UNAVAILABLE)),
1889 protocol_name: "test_protocol",
1890 }))
1891 );
1892
1893 assert!(event_receiver.poll_next_unpin(event_cx).is_ready());
1895 }
1896
1897 #[fasync::run_singlethreaded(test)]
1898 async fn client_allows_take_event_stream_even_if_event_delivered() {
1899 let (client_end, server_end) = zx::Channel::create();
1900 let client_end = AsyncChannel::from_channel(client_end);
1901 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
1902
1903 send_transaction(TransactionHeader::new(0, 5, DynamicFlags::empty()), &server_end);
1905
1906 let (response_waker, _response_waker_count) = new_count_waker();
1908 let response_cx = &mut Context::from_waker(&response_waker);
1909 let mut response_future =
1910 client.send_query::<u8, u8, SEND_ORDINAL>(55, DynamicFlags::empty());
1911 assert!(response_future.poll_unpin(response_cx).is_pending());
1912
1913 let mut _event_receiver = client.take_event_receiver();
1915 }
1916
1917 #[fasync::run_singlethreaded(test)]
1918 async fn client_reports_epitaph_from_all_read_actions() {
1919 #[derive(Debug, PartialEq)]
1920 enum Action {
1921 SendMsg, SendQuery, WaitQuery, RecvEvent, }
1926 impl Action {
1927 fn should_report_epitaph(&self) -> bool {
1928 match self {
1929 Action::SendMsg | Action::SendQuery => false,
1930 Action::WaitQuery | Action::RecvEvent => true,
1931 }
1932 }
1933 }
1934 use Action::*;
1935 for two_actions in &[
1938 [SendMsg, SendMsg],
1939 [SendMsg, SendQuery],
1940 [SendMsg, WaitQuery],
1941 [SendMsg, RecvEvent],
1942 [SendQuery, SendMsg],
1943 [SendQuery, SendQuery],
1944 [SendQuery, WaitQuery],
1945 [SendQuery, RecvEvent],
1946 [WaitQuery, SendMsg],
1947 [WaitQuery, SendQuery],
1948 [WaitQuery, WaitQuery],
1949 [WaitQuery, RecvEvent],
1950 [RecvEvent, SendMsg],
1951 [RecvEvent, SendQuery],
1952 [RecvEvent, WaitQuery],
1953 ] {
1956 let (client_end, server_end) = zx::Channel::create();
1957 let client_end = AsyncChannel::from_channel(client_end);
1958 let client = Client::new(client_end, "test_protocol");
1959
1960 let server_end = AsyncChannel::from_channel(server_end);
1962 server_end
1963 .close_with_epitaph(zx_status::Status::UNAVAILABLE)
1964 .expect("failed to write epitaph");
1965
1966 let mut event_receiver = client.take_event_receiver();
1967
1968 for (index, action) in two_actions.iter().enumerate() {
1970 let err = match action {
1971 SendMsg => {
1972 client.send::<u8>(SEND_DATA, SEND_ORDINAL, DynamicFlags::empty()).err()
1973 }
1974 WaitQuery => client
1975 .send_query::<u8, u8, SEND_ORDINAL>(SEND_DATA, DynamicFlags::empty())
1976 .await
1977 .err(),
1978 SendQuery => client
1979 .send_query::<u8, u8, SEND_ORDINAL>(SEND_DATA, DynamicFlags::empty())
1980 .check()
1981 .err(),
1982 RecvEvent => event_receiver.next().await.unwrap().err(),
1983 };
1984 let details = format!("index: {index:?}, two_actions: {two_actions:?}");
1985 match err {
1986 None => assert!(
1987 !action.should_report_epitaph(),
1988 "expected epitaph, but succeeded.\n{details}"
1989 ),
1990 Some(crate::Error::ClientChannelClosed {
1991 epitaph:
1992 crate::error::Epitaph::Explicit(Err(zx_status::Status::UNAVAILABLE)),
1993 protocol_name: "test_protocol",
1994 }) => assert!(
1995 action.should_report_epitaph(),
1996 "got epitaph unexpectedly.\n{details}",
1997 ),
1998 Some(err) => panic!("unexpected error: {err:#?}.\n{details}"),
1999 }
2000 }
2001
2002 if two_actions.contains(&RecvEvent) {
2004 assert_matches!(event_receiver.next().await, None);
2005 }
2006 }
2007 }
2008
2009 #[test]
2010 fn client_query_result_check() {
2011 let mut executor = fasync::TestExecutor::new();
2012 let (client_end, server_end) = zx::Channel::create();
2013 let client_end = AsyncChannel::from_channel(client_end);
2014 let client = Client::new(client_end, "test_protocol");
2015
2016 let server = AsyncChannel::from_channel(server_end);
2017
2018 let active_fut =
2020 client.send_query::<u8, u8, SEND_ORDINAL>(SEND_DATA, DynamicFlags::empty());
2021
2022 let mut checked_fut = active_fut.check().expect("failed to check future");
2023
2024 let mut buffer = MessageBufEtc::new();
2026 executor.run_singlethreaded(server.recv_etc_msg(&mut buffer)).expect("failed to recv msg");
2027 let two_way_tx_id = 1u8;
2028 assert_eq!(buffer.bytes(), expected_sent_bytes(two_way_tx_id, 1));
2029
2030 let (bytes, handles) = (&mut vec![], &mut vec![]);
2031 let header =
2032 TransactionHeader::new(two_way_tx_id as u32, SEND_ORDINAL, DynamicFlags::empty());
2033 encode_transaction(header, bytes, handles);
2034 server.write_etc(bytes, handles).expect("Server channel write failed");
2035
2036 executor
2037 .run_singlethreaded(&mut checked_fut)
2038 .map(|x| assert_eq!(x, SEND_DATA))
2039 .unwrap_or_else(|e| panic!("fidl error: {e:?}"));
2040
2041 drop(server);
2043
2044 let query_fut = client.send_query::<u8, u8, SEND_ORDINAL>(SEND_DATA, DynamicFlags::empty());
2045
2046 let mut checked_fut = query_fut.check().expect("failed to check future");
2048 assert_matches!(
2050 executor.run_singlethreaded(&mut checked_fut),
2051 Err(crate::Error::ClientChannelClosed {
2052 epitaph: crate::error::Epitaph::PeerClosed,
2053 protocol_name: "test_protocol",
2054 })
2055 );
2056 }
2057
2058 #[fasync::run_singlethreaded(test)]
2059 async fn client_into_channel() {
2060 let (client_end, _server_end) = zx::Channel::create();
2063 let client_end = AsyncChannel::from_channel(client_end);
2064 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
2065
2066 assert!(client.into_channel().is_ok());
2067 }
2068
2069 #[fasync::run_singlethreaded(test)]
2070 async fn client_into_channel_outstanding_messages() {
2071 let (client_end, _server_end) = zx::Channel::create();
2074 let client_end = AsyncChannel::from_channel(client_end);
2075 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
2076
2077 {
2078 let _sender =
2081 client.send_query::<u8, u8, SEND_ORDINAL>(SEND_DATA, DynamicFlags::empty());
2082 }
2083
2084 assert!(client.into_channel().is_err());
2085 }
2086
2087 #[fasync::run_singlethreaded(test)]
2088 async fn client_into_channel_active_clone() {
2089 let (client_end, _server_end) = zx::Channel::create();
2092 let client_end = AsyncChannel::from_channel(client_end);
2093 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
2094
2095 let _cloned_client = client.clone();
2096
2097 assert!(client.into_channel().is_err());
2098 }
2099
2100 #[fasync::run_singlethreaded(test)]
2101 async fn client_into_channel_outstanding_messages_get_received() {
2102 let (client_end, server_end) = zx::Channel::create();
2103 let client_end = AsyncChannel::from_channel(client_end);
2104 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
2105
2106 let server = AsyncChannel::from_channel(server_end);
2107 let mut buffer = MessageBufEtc::new();
2108 let receiver = async move {
2109 server.recv_etc_msg(&mut buffer).await.expect("failed to recv msg");
2110 let two_way_tx_id = 1u8;
2111 assert_eq!(buffer.bytes(), expected_sent_bytes(two_way_tx_id, 1));
2112
2113 let (bytes, handles) = (&mut vec![], &mut vec![]);
2114 let header =
2115 TransactionHeader::new(two_way_tx_id as u32, SEND_ORDINAL, DynamicFlags::empty());
2116 encode_transaction(header, bytes, handles);
2117 server.write_etc(bytes, handles).expect("Server channel write failed");
2118 };
2119
2120 let receiver = receiver
2122 .on_timeout(zx::MonotonicDuration::from_millis(300).after_now(), || {
2123 panic!("did not receiver message in time!")
2124 });
2125
2126 let sender = client
2127 .send_query::<u8, u8, SEND_ORDINAL>(SEND_DATA, DynamicFlags::empty())
2128 .map_ok(|x| assert_eq!(x, SEND_DATA))
2129 .unwrap_or_else(|e| panic!("fidl error: {e:?}"));
2130
2131 let sender = sender.on_timeout(zx::MonotonicDuration::from_millis(300).after_now(), || {
2133 panic!("did not receive response in time!")
2134 });
2135
2136 let ((), ()) = join!(receiver, sender);
2137
2138 assert!(client.into_channel().is_ok());
2139 }
2140
2141 #[fasync::run_singlethreaded(test)]
2142 async fn client_decode_errors_are_broadcast() {
2143 let (client_end, server_end) = zx::Channel::create();
2144 let client_end = AsyncChannel::from_channel(client_end);
2145 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
2146
2147 let server = AsyncChannel::from_channel(server_end);
2148
2149 let _server = fasync::Task::spawn(async move {
2150 let mut buffer = MessageBufEtc::new();
2151 server.recv_etc_msg(&mut buffer).await.expect("failed to recv msg");
2152 let two_way_tx_id = 1u8;
2153 assert_eq!(buffer.bytes(), expected_sent_bytes(two_way_tx_id, 1));
2154
2155 let (bytes, handles) = (&mut vec![], &mut vec![]);
2156 let header =
2157 TransactionHeader::new(two_way_tx_id as u32, SEND_ORDINAL, DynamicFlags::empty());
2158 encode_transaction(header, bytes, handles);
2159 bytes[4] = 0;
2161 server.write_etc(bytes, handles).expect("Server channel write failed");
2162
2163 pending::<()>().await;
2165 });
2166
2167 let futures = FuturesUnordered::new();
2168
2169 for _ in 0..4 {
2170 futures.push(async {
2171 assert_matches!(
2172 client
2173 .send_query::<u8, u8, SEND_ORDINAL>(SEND_DATA, DynamicFlags::empty())
2174 .map_ok(|x| assert_eq!(x, SEND_DATA))
2175 .await,
2176 Err(crate::Error::UnsupportedWireFormatVersion)
2177 );
2178 });
2179 }
2180
2181 futures
2182 .collect::<Vec<_>>()
2183 .on_timeout(zx::MonotonicDuration::from_seconds(1).after_now(), || panic!("timed out!"))
2184 .await;
2185 }
2186
2187 #[fasync::run_singlethreaded(test)]
2188 async fn into_channel_from_waker_succeeds() {
2189 let (client_end, server_end) = zx::Channel::create();
2190 let client_end = AsyncChannel::from_channel(client_end);
2191 let client = Client::<DefaultFuchsiaResourceDialect>::new(client_end, "test_protocol");
2192
2193 let server = AsyncChannel::from_channel(server_end);
2194 let mut buffer = MessageBufEtc::new();
2195 let receiver = async move {
2196 server.recv_etc_msg(&mut buffer).await.expect("failed to recv msg");
2197 let two_way_tx_id = 1u8;
2198 assert_eq!(buffer.bytes(), expected_sent_bytes(two_way_tx_id, 1));
2199
2200 let (bytes, handles) = (&mut vec![], &mut vec![]);
2201 let header =
2202 TransactionHeader::new(two_way_tx_id as u32, SEND_ORDINAL, DynamicFlags::empty());
2203 encode_transaction(header, bytes, handles);
2204 server.write_etc(bytes, handles).expect("Server channel write failed");
2205 };
2206
2207 struct Sender {
2208 future: Mutex<Pin<Box<dyn Future<Output = ()> + Send + Sync + 'static>>>,
2209 }
2210
2211 let (done_tx, done_rx) = oneshot::channel();
2212
2213 let sender = Arc::new(Sender {
2214 future: Mutex::new(Box::pin(async move {
2215 client
2216 .send_query::<u8, u8, SEND_ORDINAL>(SEND_DATA, DynamicFlags::empty())
2217 .map_ok(|x| assert_eq!(x, SEND_DATA))
2218 .unwrap_or_else(|e| panic!("fidl error: {e:?}"))
2219 .await;
2220
2221 assert!(client.into_channel().is_ok());
2222
2223 let _ = done_tx.send(());
2224 })),
2225 });
2226
2227 impl Wake for Sender {
2232 fn wake(self: Arc<Self>) {
2233 self.wake_by_ref();
2234 }
2235 fn wake_by_ref(self: &Arc<Self>) {
2236 assert!(
2237 self.future
2238 .lock()
2239 .poll_unpin(&mut Context::from_waker(Waker::noop()))
2240 .is_ready()
2241 );
2242 }
2243 }
2244
2245 let waker = Waker::from(sender.clone());
2246
2247 assert!(sender.future.lock().poll_unpin(&mut Context::from_waker(&waker)).is_pending());
2248
2249 receiver.await;
2250
2251 done_rx.await.unwrap();
2252 }
2253}