@@ -126,7 +126,7 @@ use std::future::Future;
126
126
use std:: pin:: Pin ;
127
127
use std:: task:: { Context , Poll } ;
128
128
use std:: time:: Duration ;
129
- use std:: { convert , fmt, io, mem } ;
129
+ use std:: { fmt, io} ;
130
130
use tokio:: io:: { AsyncRead , AsyncWrite , ReadBuf } ;
131
131
use tracing:: instrument:: { Instrument , Instrumented } ;
132
132
@@ -301,8 +301,8 @@ enum Handshaking<T, B: Buf> {
301
301
Flushing ( Instrumented < Flush < T , Prioritized < B > > > ) ,
302
302
/// State 2. Connection is waiting for the client preface.
303
303
ReadingPreface ( Instrumented < ReadPreface < T , Prioritized < B > > > ) ,
304
- /// Dummy state for `mem::replace` .
305
- Empty ,
304
+ /// State 3. Handshake is done, polling again would panic .
305
+ Done ,
306
306
}
307
307
308
308
/// Flush a Sink
@@ -387,7 +387,8 @@ where
387
387
. expect ( "invalid SETTINGS frame" ) ;
388
388
389
389
// Create the handshake future.
390
- let state = Handshaking :: from ( codec) ;
390
+ let state =
391
+ Handshaking :: Flushing ( Flush :: new ( codec) . instrument ( tracing:: trace_span!( "flush" ) ) ) ;
391
392
392
393
drop ( entered) ;
393
394
@@ -1269,63 +1270,58 @@ where
1269
1270
let span = self . span . clone ( ) ; // XXX(eliza): T_T
1270
1271
let _e = span. enter ( ) ;
1271
1272
tracing:: trace!( state = ?self . state) ;
1272
- use crate :: server:: Handshaking :: * ;
1273
-
1274
- self . state = if let Flushing ( ref mut flush) = self . state {
1275
- // We're currently flushing a pending SETTINGS frame. Poll the
1276
- // flush future, and, if it's completed, advance our state to wait
1277
- // for the client preface.
1278
- let codec = match Pin :: new ( flush) . poll ( cx) ? {
1279
- Poll :: Pending => {
1280
- tracing:: trace!( flush. poll = %"Pending" ) ;
1281
- return Poll :: Pending ;
1273
+
1274
+ loop {
1275
+ match & mut self . state {
1276
+ Handshaking :: Flushing ( flush) => {
1277
+ // We're currently flushing a pending SETTINGS frame. Poll the
1278
+ // flush future, and, if it's completed, advance our state to wait
1279
+ // for the client preface.
1280
+ let codec = match Pin :: new ( flush) . poll ( cx) ? {
1281
+ Poll :: Pending => {
1282
+ tracing:: trace!( flush. poll = %"Pending" ) ;
1283
+ return Poll :: Pending ;
1284
+ }
1285
+ Poll :: Ready ( flushed) => {
1286
+ tracing:: trace!( flush. poll = %"Ready" ) ;
1287
+ flushed
1288
+ }
1289
+ } ;
1290
+ self . state = Handshaking :: ReadingPreface (
1291
+ ReadPreface :: new ( codec) . instrument ( tracing:: trace_span!( "read_preface" ) ) ,
1292
+ ) ;
1282
1293
}
1283
- Poll :: Ready ( flushed) => {
1284
- tracing:: trace!( flush. poll = %"Ready" ) ;
1285
- flushed
1294
+ Handshaking :: ReadingPreface ( read) => {
1295
+ let codec = ready ! ( Pin :: new( read) . poll( cx) ?) ;
1296
+
1297
+ self . state = Handshaking :: Done ;
1298
+
1299
+ let connection = proto:: Connection :: new (
1300
+ codec,
1301
+ Config {
1302
+ next_stream_id : 2 . into ( ) ,
1303
+ // Server does not need to locally initiate any streams
1304
+ initial_max_send_streams : 0 ,
1305
+ max_send_buffer_size : self . builder . max_send_buffer_size ,
1306
+ reset_stream_duration : self . builder . reset_stream_duration ,
1307
+ reset_stream_max : self . builder . reset_stream_max ,
1308
+ settings : self . builder . settings . clone ( ) ,
1309
+ } ,
1310
+ ) ;
1311
+
1312
+ tracing:: trace!( "connection established!" ) ;
1313
+ let mut c = Connection { connection } ;
1314
+ if let Some ( sz) = self . builder . initial_target_connection_window_size {
1315
+ c. set_target_window_size ( sz) ;
1316
+ }
1317
+
1318
+ return Poll :: Ready ( Ok ( c) ) ;
1319
+ }
1320
+ Handshaking :: Done => {
1321
+ panic ! ( "Handshaking::poll() called again after handshaking was complete" )
1286
1322
}
1287
- } ;
1288
- Handshaking :: from ( ReadPreface :: new ( codec) )
1289
- } else {
1290
- // Otherwise, we haven't actually advanced the state, but we have
1291
- // to replace it with itself, because we have to return a value.
1292
- // (note that the assignment to `self.state` has to be outside of
1293
- // the `if let` block above in order to placate the borrow checker).
1294
- mem:: replace ( & mut self . state , Handshaking :: Empty )
1295
- } ;
1296
- let poll = if let ReadingPreface ( ref mut read) = self . state {
1297
- // We're now waiting for the client preface. Poll the `ReadPreface`
1298
- // future. If it has completed, we will create a `Connection` handle
1299
- // for the connection.
1300
- Pin :: new ( read) . poll ( cx)
1301
- // Actually creating the `Connection` has to occur outside of this
1302
- // `if let` block, because we've borrowed `self` mutably in order
1303
- // to poll the state and won't be able to borrow the SETTINGS frame
1304
- // as well until we release the borrow for `poll()`.
1305
- } else {
1306
- unreachable ! ( "Handshake::poll() state was not advanced completely!" )
1307
- } ;
1308
- poll?. map ( |codec| {
1309
- let connection = proto:: Connection :: new (
1310
- codec,
1311
- Config {
1312
- next_stream_id : 2 . into ( ) ,
1313
- // Server does not need to locally initiate any streams
1314
- initial_max_send_streams : 0 ,
1315
- max_send_buffer_size : self . builder . max_send_buffer_size ,
1316
- reset_stream_duration : self . builder . reset_stream_duration ,
1317
- reset_stream_max : self . builder . reset_stream_max ,
1318
- settings : self . builder . settings . clone ( ) ,
1319
- } ,
1320
- ) ;
1321
-
1322
- tracing:: trace!( "connection established!" ) ;
1323
- let mut c = Connection { connection } ;
1324
- if let Some ( sz) = self . builder . initial_target_connection_window_size {
1325
- c. set_target_window_size ( sz) ;
1326
1323
}
1327
- Ok ( c)
1328
- } )
1324
+ }
1329
1325
}
1330
1326
}
1331
1327
@@ -1548,42 +1544,9 @@ where
1548
1544
#[ inline]
1549
1545
fn fmt ( & self , f : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
1550
1546
match * self {
1551
- Handshaking :: Flushing ( _) => write ! ( f , "Handshaking:: Flushing(_)") ,
1552
- Handshaking :: ReadingPreface ( _) => write ! ( f , "Handshaking:: ReadingPreface(_)") ,
1553
- Handshaking :: Empty => write ! ( f , "Handshaking::Empty ") ,
1547
+ Handshaking :: Flushing ( _) => f . write_str ( " Flushing(_)") ,
1548
+ Handshaking :: ReadingPreface ( _) => f . write_str ( " ReadingPreface(_)") ,
1549
+ Handshaking :: Done => f . write_str ( "Done ") ,
1554
1550
}
1555
1551
}
1556
1552
}
1557
-
1558
- impl < T , B > convert:: From < Flush < T , Prioritized < B > > > for Handshaking < T , B >
1559
- where
1560
- T : AsyncRead + AsyncWrite ,
1561
- B : Buf ,
1562
- {
1563
- #[ inline]
1564
- fn from ( flush : Flush < T , Prioritized < B > > ) -> Self {
1565
- Handshaking :: Flushing ( flush. instrument ( tracing:: trace_span!( "flush" ) ) )
1566
- }
1567
- }
1568
-
1569
- impl < T , B > convert:: From < ReadPreface < T , Prioritized < B > > > for Handshaking < T , B >
1570
- where
1571
- T : AsyncRead + AsyncWrite ,
1572
- B : Buf ,
1573
- {
1574
- #[ inline]
1575
- fn from ( read : ReadPreface < T , Prioritized < B > > ) -> Self {
1576
- Handshaking :: ReadingPreface ( read. instrument ( tracing:: trace_span!( "read_preface" ) ) )
1577
- }
1578
- }
1579
-
1580
- impl < T , B > convert:: From < Codec < T , Prioritized < B > > > for Handshaking < T , B >
1581
- where
1582
- T : AsyncRead + AsyncWrite ,
1583
- B : Buf ,
1584
- {
1585
- #[ inline]
1586
- fn from ( codec : Codec < T , Prioritized < B > > ) -> Self {
1587
- Handshaking :: from ( Flush :: new ( codec) )
1588
- }
1589
- }
0 commit comments