1
+ use std:: fmt;
1
2
use std:: future:: Future ;
2
3
use std:: net:: SocketAddr ;
3
4
use std:: pin:: Pin ;
@@ -8,7 +9,7 @@ use crate::io;
8
9
use crate :: net:: { TcpStream , ToSocketAddrs } ;
9
10
use crate :: stream:: Stream ;
10
11
use crate :: sync:: Arc ;
11
- use crate :: task:: { Context , Poll } ;
12
+ use crate :: task:: { ready , Context , Poll } ;
12
13
13
14
/// A TCP socket server, listening for connections.
14
15
///
@@ -146,7 +147,10 @@ impl TcpListener {
146
147
/// # Ok(()) }) }
147
148
/// ```
148
149
pub fn incoming ( & self ) -> Incoming < ' _ > {
149
- Incoming ( self )
150
+ Incoming {
151
+ listener : self ,
152
+ accept : None ,
153
+ }
150
154
}
151
155
152
156
/// Returns the local address that this listener is bound to.
@@ -182,18 +186,36 @@ impl TcpListener {
182
186
/// [`incoming`]: struct.TcpListener.html#method.incoming
183
187
/// [`TcpListener`]: struct.TcpListener.html
184
188
/// [`std::net::Incoming`]: https://doc.rust-lang.org/std/net/struct.Incoming.html
185
- #[ derive( Debug ) ]
186
- pub struct Incoming < ' a > ( & ' a TcpListener ) ;
189
+ 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
+ > ,
194
+ }
187
195
188
- impl < ' a > Stream for Incoming < ' a > {
196
+ impl Stream for Incoming < ' _ > {
189
197
type Item = io:: Result < TcpStream > ;
190
198
191
- fn poll_next ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
192
- let future = self . 0 . accept ( ) ;
193
- pin_utils:: pin_mut!( future) ;
199
+ 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
+ }
211
+ }
212
+ }
194
213
195
- let ( socket, _) = futures_core:: ready!( future. poll( cx) ) ?;
196
- Poll :: Ready ( Some ( Ok ( socket) ) )
214
+ impl fmt:: Debug for Incoming < ' _ > {
215
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
216
+ f. debug_struct ( "Incoming" )
217
+ . field ( "listener" , self . listener )
218
+ . finish ( )
197
219
}
198
220
}
199
221
0 commit comments