Skip to content

Commit 9d9fb79

Browse files
committed
Simplify net-tokio select logic
When `PeerManager` tells us to stop reading from a peer, `lightning-net-tokio` will skip polling the TCP socket receiver. This is great, but we had an entire separate struct to avoid the second poll, which we remove here, replacing the missing future with an `Option`.
1 parent 05f2848 commit 9d9fb79

File tree

1 file changed

+23
-52
lines changed

1 file changed

+23
-52
lines changed

lightning-net-tokio/src/lib.rs

Lines changed: 23 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -61,43 +61,14 @@ pub(crate) enum SelectorOutput {
6161
C(tokio::io::Result<()>),
6262
}
6363

64-
pub(crate) struct TwoSelector<
65-
A: Future<Output = Option<()>> + Unpin,
66-
B: Future<Output = Option<()>> + Unpin,
67-
> {
68-
pub a: A,
69-
pub b: B,
70-
}
71-
72-
impl<A: Future<Output = Option<()>> + Unpin, B: Future<Output = Option<()>> + Unpin> Future
73-
for TwoSelector<A, B>
74-
{
75-
type Output = SelectorOutput;
76-
fn poll(mut self: Pin<&mut Self>, ctx: &mut task::Context<'_>) -> Poll<SelectorOutput> {
77-
match Pin::new(&mut self.a).poll(ctx) {
78-
Poll::Ready(res) => {
79-
return Poll::Ready(SelectorOutput::A(res));
80-
},
81-
Poll::Pending => {},
82-
}
83-
match Pin::new(&mut self.b).poll(ctx) {
84-
Poll::Ready(res) => {
85-
return Poll::Ready(SelectorOutput::B(res));
86-
},
87-
Poll::Pending => {},
88-
}
89-
Poll::Pending
90-
}
91-
}
92-
9364
pub(crate) struct ThreeSelector<
9465
A: Future<Output = Option<()>> + Unpin,
9566
B: Future<Output = Option<()>> + Unpin,
9667
C: Future<Output = tokio::io::Result<()>> + Unpin,
9768
> {
9869
pub a: A,
9970
pub b: B,
100-
pub c: C,
71+
pub c: Option<C>,
10172
}
10273

10374
impl<
@@ -120,11 +91,13 @@ impl<
12091
},
12192
Poll::Pending => {},
12293
}
123-
match Pin::new(&mut self.c).poll(ctx) {
124-
Poll::Ready(res) => {
125-
return Poll::Ready(SelectorOutput::C(res));
126-
},
127-
Poll::Pending => {},
94+
if let Some(c) = self.c.as_mut() {
95+
match Pin::new(c).poll(ctx) {
96+
Poll::Ready(res) => {
97+
return Poll::Ready(SelectorOutput::C(res));
98+
},
99+
Poll::Pending => {},
100+
}
128101
}
129102
Poll::Pending
130103
}
@@ -198,29 +171,27 @@ impl Connection {
198171
PeerDisconnected,
199172
}
200173
let disconnect_type = loop {
201-
let read_paused = {
174+
let selector = {
202175
let us_lock = us.lock().unwrap();
203176
if us_lock.rl_requested_disconnect {
204177
break Disconnect::CloseConnection;
205178
}
206-
us_lock.read_paused
207-
};
208-
// TODO: Drop the Box'ing of the futures once Rust has pin-on-stack support.
209-
let select_result = if read_paused {
210-
TwoSelector {
211-
a: Box::pin(write_avail_receiver.recv()),
212-
b: Box::pin(read_wake_receiver.recv()),
213-
}
214-
.await
215-
} else {
216-
ThreeSelector {
217-
a: Box::pin(write_avail_receiver.recv()),
218-
b: Box::pin(read_wake_receiver.recv()),
219-
c: Box::pin(reader.readable()),
179+
if us_lock.read_paused {
180+
// TODO: Drop the Box'ing of the futures once Rust has pin-on-stack support.
181+
ThreeSelector {
182+
a: Box::pin(write_avail_receiver.recv()),
183+
b: Box::pin(read_wake_receiver.recv()),
184+
c: None,
185+
}
186+
} else {
187+
ThreeSelector {
188+
a: Box::pin(write_avail_receiver.recv()),
189+
b: Box::pin(read_wake_receiver.recv()),
190+
c: Some(Box::pin(reader.readable())),
191+
}
220192
}
221-
.await
222193
};
223-
match select_result {
194+
match selector.await {
224195
SelectorOutput::A(v) => {
225196
assert!(v.is_some()); // We can't have dropped the sending end, its in the us Arc!
226197
if peer_manager.as_ref().write_buffer_space_avail(&mut our_descriptor).is_err()

0 commit comments

Comments
 (0)