30
30
socket : Fuse < frame:: Io < T > > ,
31
31
) -> Self {
32
32
Self {
33
- state : State :: FlushingPendingFrames ,
33
+ state : State :: ClosingStreamReceiver ,
34
34
stream_receivers,
35
35
pending_frames,
36
36
socket,
49
49
50
50
loop {
51
51
match this. state {
52
- State :: FlushingPendingFrames => {
53
- ready ! ( this. socket. poll_ready_unpin( cx) ) ?;
54
-
55
- match this. pending_frames . pop_front ( ) {
56
- Some ( frame) => this. socket . start_send_unpin ( frame) ?,
57
- None => this. state = State :: ClosingStreamReceiver ,
58
- }
59
- }
60
52
State :: ClosingStreamReceiver => {
61
53
for stream in this. stream_receivers . iter_mut ( ) {
62
54
stream. inner_mut ( ) . close ( ) ;
@@ -77,11 +69,19 @@ where
77
69
Poll :: Pending | Poll :: Ready ( None ) => {
78
70
// No more frames from streams, append `Term` frame and flush them all.
79
71
this. pending_frames . push_back ( Frame :: term ( ) . into ( ) ) ;
80
- this. state = State :: ClosingSocket ;
72
+ this. state = State :: FlushingPendingFrames ;
81
73
continue ;
82
74
}
83
75
}
84
76
}
77
+ State :: FlushingPendingFrames => {
78
+ ready ! ( this. socket. poll_ready_unpin( cx) ) ?;
79
+
80
+ match this. pending_frames . pop_front ( ) {
81
+ Some ( frame) => this. socket . start_send_unpin ( frame) ?,
82
+ None => this. state = State :: ClosingSocket ,
83
+ }
84
+ }
85
85
State :: ClosingSocket => {
86
86
ready ! ( this. socket. poll_close_unpin( cx) ) ?;
87
87
@@ -93,8 +93,107 @@ where
93
93
}
94
94
95
95
enum State {
96
- FlushingPendingFrames ,
97
96
ClosingStreamReceiver ,
98
97
DrainingStreamReceiver ,
98
+ FlushingPendingFrames ,
99
99
ClosingSocket ,
100
100
}
101
+
102
+ #[ cfg( test) ]
103
+ mod tests {
104
+ use super :: * ;
105
+ use futures:: future:: poll_fn;
106
+ use futures:: FutureExt ;
107
+
108
+ struct Socket {
109
+ written : Vec < u8 > ,
110
+ closed : bool ,
111
+ }
112
+ impl AsyncRead for Socket {
113
+ fn poll_read (
114
+ self : Pin < & mut Self > ,
115
+ _: & mut Context < ' _ > ,
116
+ _: & mut [ u8 ] ,
117
+ ) -> Poll < std:: io:: Result < usize > > {
118
+ unimplemented ! ( )
119
+ }
120
+ }
121
+ impl AsyncWrite for Socket {
122
+ fn poll_write (
123
+ mut self : Pin < & mut Self > ,
124
+ _: & mut Context < ' _ > ,
125
+ buf : & [ u8 ] ,
126
+ ) -> Poll < std:: io:: Result < usize > > {
127
+ assert ! ( !self . closed) ;
128
+ self . written . extend_from_slice ( buf) ;
129
+ Poll :: Ready ( Ok ( buf. len ( ) ) )
130
+ }
131
+
132
+ fn poll_flush ( self : Pin < & mut Self > , _: & mut Context < ' _ > ) -> Poll < std:: io:: Result < ( ) > > {
133
+ unimplemented ! ( )
134
+ }
135
+
136
+ fn poll_close ( mut self : Pin < & mut Self > , _: & mut Context < ' _ > ) -> Poll < std:: io:: Result < ( ) > > {
137
+ assert ! ( !self . closed) ;
138
+ self . closed = true ;
139
+ Poll :: Ready ( Ok ( ( ) ) )
140
+ }
141
+ }
142
+
143
+ #[ test]
144
+ fn pending_frames ( ) {
145
+ let frame_pending = Frame :: data ( StreamId :: new ( 1 ) , vec ! [ 2 ] ) . unwrap ( ) . into ( ) ;
146
+ let frame_data = Frame :: data ( StreamId :: new ( 3 ) , vec ! [ 4 ] ) . unwrap ( ) . into ( ) ;
147
+ let frame_close = Frame :: close_stream ( StreamId :: new ( 5 ) , false ) . into ( ) ;
148
+ let frame_close_ack = Frame :: close_stream ( StreamId :: new ( 6 ) , true ) . into ( ) ;
149
+ let frame_term = Frame :: term ( ) . into ( ) ;
150
+ fn encode ( buf : & mut Vec < u8 > , frame : & Frame < ( ) > ) {
151
+ buf. extend_from_slice ( & frame:: header:: encode ( frame. header ( ) ) ) ;
152
+ if frame. header ( ) . tag ( ) == frame:: header:: Tag :: Data {
153
+ buf. extend_from_slice ( frame. clone ( ) . into_data ( ) . body ( ) ) ;
154
+ }
155
+ }
156
+ let mut expected_written = vec ! [ ] ;
157
+ encode ( & mut expected_written, & frame_pending) ;
158
+ encode ( & mut expected_written, & frame_data) ;
159
+ encode ( & mut expected_written, & frame_close) ;
160
+ encode ( & mut expected_written, & frame_close_ack) ;
161
+ encode ( & mut expected_written, & frame_term) ;
162
+
163
+ let receiver = |frame : & Frame < _ > , command : StreamCommand | {
164
+ TaggedStream :: new ( frame. header ( ) . stream_id ( ) , {
165
+ let ( mut tx, rx) = mpsc:: channel ( 1 ) ;
166
+ tx. try_send ( command) . unwrap ( ) ;
167
+ rx
168
+ } )
169
+ } ;
170
+
171
+ let mut stream_receivers: SelectAll < _ > = Default :: default ( ) ;
172
+ stream_receivers. push ( receiver (
173
+ & frame_data,
174
+ StreamCommand :: SendFrame ( frame_data. clone ( ) . into_data ( ) . left ( ) ) ,
175
+ ) ) ;
176
+ stream_receivers. push ( receiver (
177
+ & frame_close,
178
+ StreamCommand :: CloseStream { ack : false } ,
179
+ ) ) ;
180
+ stream_receivers. push ( receiver (
181
+ & frame_close_ack,
182
+ StreamCommand :: CloseStream { ack : true } ,
183
+ ) ) ;
184
+ let pending_frames = vec ! [ frame_pending. into( ) ] ;
185
+ let mut socket = Socket {
186
+ written : vec ! [ ] ,
187
+ closed : false ,
188
+ } ;
189
+ let mut closing = Closing :: new (
190
+ stream_receivers,
191
+ pending_frames. into ( ) ,
192
+ frame:: Io :: new ( crate :: connection:: Id ( 0 ) , & mut socket) . fuse ( ) ,
193
+ ) ;
194
+ futures:: executor:: block_on ( async { poll_fn ( |cx| closing. poll_unpin ( cx) ) . await . unwrap ( ) } ) ;
195
+ assert ! ( closing. pending_frames. is_empty( ) ) ;
196
+ assert ! ( socket. closed) ;
197
+ assert_eq ! ( socket. written, expected_written) ;
198
+ }
199
+ }
0 commit comments