Skip to content

Commit c4e181c

Browse files
committed
Change Incoming impls to only do one allocation
This modifies net::tcp::Incoming and os::net::unix::Incoming to only do one allocation, rather than an allocation for each connection.
1 parent d395607 commit c4e181c

File tree

2 files changed

+11
-40
lines changed

2 files changed

+11
-40
lines changed

src/net/tcp/listener.rs

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::fmt;
2-
use std::future::Future;
32
use std::net::SocketAddr;
3+
use std::net::TcpStream as StdTcpStream;
44
use std::pin::Pin;
55

66
use async_io::Async;
@@ -148,8 +148,7 @@ impl TcpListener {
148148
/// ```
149149
pub fn incoming(&self) -> Incoming<'_> {
150150
Incoming {
151-
listener: self,
152-
accept: None,
151+
incoming: Box::pin(self.watcher.incoming()),
153152
}
154153
}
155154

@@ -187,35 +186,21 @@ impl TcpListener {
187186
/// [`TcpListener`]: struct.TcpListener.html
188187
/// [`std::net::Incoming`]: https://doc.rust-lang.org/std/net/struct.Incoming.html
189188
pub struct Incoming<'a> {
190-
listener: &'a TcpListener,
191-
accept: Option<
192-
Pin<Box<dyn Future<Output = io::Result<(TcpStream, SocketAddr)>> + Send + Sync + 'a>>,
193-
>,
189+
incoming: Pin<Box<dyn Stream<Item = io::Result<Async<StdTcpStream>>> + Send + Sync + 'a>>,
194190
}
195191

196192
impl Stream for Incoming<'_> {
197193
type Item = io::Result<TcpStream>;
198194

199195
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
200-
loop {
201-
if self.accept.is_none() {
202-
self.accept = Some(Box::pin(self.listener.accept()));
203-
}
204-
205-
if let Some(f) = &mut self.accept {
206-
let res = ready!(f.as_mut().poll(cx));
207-
self.accept = None;
208-
return Poll::Ready(Some(res.map(|(stream, _)| stream)));
209-
}
210-
}
196+
let res = ready!(Pin::new(&mut self.incoming).poll_next(cx));
197+
Poll::Ready(res.map(|res| res.map(|stream| TcpStream { watcher: Arc::new(stream) })))
211198
}
212199
}
213200

214201
impl fmt::Debug for Incoming<'_> {
215202
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
216-
f.debug_struct("Incoming")
217-
.field("listener", self.listener)
218-
.finish()
203+
write!(f, "Incoming {{ ... }}")
219204
}
220205
}
221206

src/os/unix/net/listener.rs

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Unix-specific networking extensions.
22
33
use std::fmt;
4-
use std::future::Future;
54
use std::os::unix::net::UnixListener as StdUnixListener;
5+
use std::os::unix::net::UnixStream as StdUnixStream;
66
use std::pin::Pin;
77

88
use async_io::Async;
@@ -129,8 +129,7 @@ impl UnixListener {
129129
/// ```
130130
pub fn incoming(&self) -> Incoming<'_> {
131131
Incoming {
132-
listener: self,
133-
accept: None,
132+
incoming: Box::pin(self.watcher.incoming()),
134133
}
135134
}
136135

@@ -178,34 +177,21 @@ impl fmt::Debug for UnixListener {
178177
/// [`incoming`]: struct.UnixListener.html#method.incoming
179178
/// [`UnixListener`]: struct.UnixListener.html
180179
pub struct Incoming<'a> {
181-
listener: &'a UnixListener,
182-
accept: Option<
183-
Pin<Box<dyn Future<Output = io::Result<(UnixStream, SocketAddr)>> + Send + Sync + 'a>>,
184-
>,
180+
incoming: Pin<Box<dyn Stream<Item = io::Result<Async<StdUnixStream>>> + Send + Sync + 'a>>,
185181
}
186182

187183
impl Stream for Incoming<'_> {
188184
type Item = io::Result<UnixStream>;
189185

190186
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
191-
loop {
192-
if self.accept.is_none() {
193-
self.accept = Some(Box::pin(self.listener.accept()));
194-
}
195-
196-
if let Some(f) = &mut self.accept {
197-
let res = ready!(f.as_mut().poll(cx));
198-
self.accept = None;
199-
return Poll::Ready(Some(res.map(|(stream, _)| stream)));
200-
}
201-
}
187+
let res = ready!(Pin::new(&mut self.incoming).poll_next(cx));
188+
Poll::Ready(res.map(|res| res.map(|stream| UnixStream { watcher: Arc::new(stream) })))
202189
}
203190
}
204191

205192
impl fmt::Debug for Incoming<'_> {
206193
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207194
f.debug_struct("Incoming")
208-
.field("listener", self.listener)
209195
.finish()
210196
}
211197
}

0 commit comments

Comments
 (0)