overnet_core/proxy/handle/
signals.rs
1use super::ReadValue;
6use fidl::{HandleRef, Signals};
7use fidl_fuchsia_overnet_protocol::{SignalUpdate, Signals as WireSignals};
8use fuchsia_async::OnSignalsRef;
9use futures::FutureExt;
10use std::task::{Context, Poll};
11use zx_status;
12
13const POLLED_SIGNALS: Signals = Signals::from_bits_truncate(
14 Signals::USER_0.bits()
15 | Signals::USER_1.bits()
16 | Signals::USER_2.bits()
17 | Signals::USER_3.bits()
18 | Signals::USER_4.bits()
19 | Signals::USER_5.bits()
20 | Signals::USER_6.bits()
21 | Signals::USER_7.bits(),
22);
23
24#[derive(Default)]
25pub(crate) struct Collector<'a> {
26 on_signals: Option<OnSignalsRef<'a>>,
27 shutdown: bool,
28}
29
30impl<'h> Collector<'h> {
31 pub(crate) fn after_read<'ctx>(
32 &mut self,
33 ctx: &mut Context<'ctx>,
34 hdl: HandleRef<'h>,
35 read_result: Poll<Result<(), zx_status::Status>>,
36 do_peer_closed: bool,
37 ) -> Poll<Result<ReadValue, zx_status::Status>> {
38 match read_result {
39 Poll::Ready(Ok(())) => Poll::Ready(Ok(ReadValue::Message)),
40 Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
41 Poll::Pending => {
42 if self.shutdown {
43 return Poll::Ready(Err(zx_status::Status::PEER_CLOSED));
44 }
45
46 let signals = if do_peer_closed {
47 POLLED_SIGNALS | Signals::OBJECT_PEER_CLOSED
48 } else {
49 POLLED_SIGNALS
50 };
51
52 let mut on_signals = self
53 .on_signals
54 .take()
55 .unwrap_or_else(|| OnSignalsRef::new(hdl.clone(), signals));
56 match on_signals.poll_unpin(ctx) {
57 Poll::Ready(Ok(mut signals)) => {
58 self.shutdown =
59 self.shutdown || signals.contains(Signals::OBJECT_PEER_CLOSED);
60 signals.remove(Signals::OBJECT_PEER_CLOSED);
61 if signals.is_empty() {
62 Poll::Ready(Err(zx_status::Status::PEER_CLOSED))
63 } else {
64 hdl.signal(signals, Signals::empty())?;
65 Poll::Ready(Ok(ReadValue::SignalUpdate(SignalUpdate {
66 assert_signals: Some(to_wire_signals(signals)),
67 ..Default::default()
68 })))
69 }
70 }
71 Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
72 Poll::Pending => {
73 self.on_signals = Some(on_signals);
74 Poll::Pending
75 }
76 }
77 }
78 }
79 }
80}
81
82fn to_wire_signals(signals: Signals) -> WireSignals {
83 let mut out = WireSignals::empty();
84 if signals.contains(Signals::USER_0) {
85 out.insert(WireSignals::USER_0);
86 }
87 if signals.contains(Signals::USER_1) {
88 out.insert(WireSignals::USER_1);
89 }
90 if signals.contains(Signals::USER_2) {
91 out.insert(WireSignals::USER_2);
92 }
93 if signals.contains(Signals::USER_3) {
94 out.insert(WireSignals::USER_3);
95 }
96 if signals.contains(Signals::USER_4) {
97 out.insert(WireSignals::USER_4);
98 }
99 if signals.contains(Signals::USER_5) {
100 out.insert(WireSignals::USER_5);
101 }
102 if signals.contains(Signals::USER_6) {
103 out.insert(WireSignals::USER_6);
104 }
105 if signals.contains(Signals::USER_7) {
106 out.insert(WireSignals::USER_7);
107 }
108 out
109}
110
111pub(crate) fn from_wire_signals(signals: WireSignals) -> Signals {
112 let mut out = Signals::empty();
113 if signals.contains(WireSignals::USER_0) {
114 out.insert(Signals::USER_0);
115 }
116 if signals.contains(WireSignals::USER_1) {
117 out.insert(Signals::USER_1);
118 }
119 if signals.contains(WireSignals::USER_2) {
120 out.insert(Signals::USER_2);
121 }
122 if signals.contains(WireSignals::USER_3) {
123 out.insert(Signals::USER_3);
124 }
125 if signals.contains(WireSignals::USER_4) {
126 out.insert(Signals::USER_4);
127 }
128 if signals.contains(WireSignals::USER_5) {
129 out.insert(Signals::USER_5);
130 }
131 if signals.contains(WireSignals::USER_6) {
132 out.insert(Signals::USER_6);
133 }
134 if signals.contains(WireSignals::USER_7) {
135 out.insert(Signals::USER_7);
136 }
137 out
138}