@@ -166,6 +166,12 @@ rcv_data_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
166166 cstate.decrement_server_rwnd (payload_length);
167167 stream->decrement_server_rwnd (payload_length);
168168
169+ if (is_debug_tag_set (" http2_con" )) {
170+ uint32_t rwnd = cstate.server_settings .get (HTTP2_SETTINGS_INITIAL_WINDOW_SIZE);
171+ Http2StreamDebug (cstate.ua_session , id, " Received DATA frame: rwnd con=%zd/%" PRId32 " stream=%zd/%" PRId32,
172+ cstate.server_rwnd (), rwnd, stream->server_rwnd (), rwnd);
173+ }
174+
169175 const uint32_t unpadded_length = payload_length - pad_length;
170176 MIOBuffer *writer = stream->read_vio_writer ();
171177 if (writer == nullptr ) {
@@ -202,21 +208,6 @@ rcv_data_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
202208 stream->signal_read_event (VC_EVENT_READ_READY);
203209 }
204210
205- uint32_t initial_rwnd = cstate.server_settings .get (HTTP2_SETTINGS_INITIAL_WINDOW_SIZE);
206- uint32_t min_rwnd = std::min (initial_rwnd, cstate.server_settings .get (HTTP2_SETTINGS_MAX_FRAME_SIZE));
207- // Connection level WINDOW UPDATE
208- if (cstate.server_rwnd () <= min_rwnd) {
209- Http2WindowSize diff_size = initial_rwnd - cstate.server_rwnd ();
210- cstate.increment_server_rwnd (diff_size);
211- cstate.send_window_update_frame (0 , diff_size);
212- }
213- // Stream level WINDOW UPDATE
214- if (stream->server_rwnd () <= min_rwnd) {
215- Http2WindowSize diff_size = initial_rwnd - stream->server_rwnd ();
216- stream->increment_server_rwnd (diff_size);
217- cstate.send_window_update_frame (stream->get_id (), diff_size);
218- }
219-
220211 return Http2Error (Http2ErrorClass::HTTP2_ERROR_CLASS_NONE);
221212}
222213
@@ -1288,6 +1279,35 @@ Http2ConnectionState::restart_streams()
12881279 }
12891280}
12901281
1282+ void
1283+ Http2ConnectionState::restart_receiving (Http2Stream *stream)
1284+ {
1285+ uint32_t initial_rwnd = this ->server_settings .get (HTTP2_SETTINGS_INITIAL_WINDOW_SIZE);
1286+ uint32_t min_rwnd = std::min (initial_rwnd, this ->server_settings .get (HTTP2_SETTINGS_MAX_FRAME_SIZE));
1287+
1288+ // Connection level WINDOW UPDATE
1289+ if (this ->server_rwnd () < min_rwnd) {
1290+ Http2WindowSize diff_size = initial_rwnd - this ->server_rwnd ();
1291+ this ->increment_server_rwnd (diff_size);
1292+ this ->send_window_update_frame (0 , diff_size);
1293+ }
1294+
1295+ // Stream level WINDOW UPDATE
1296+ if (stream == nullptr || stream->server_rwnd () >= min_rwnd) {
1297+ return ;
1298+ }
1299+
1300+ // If read_vio is buffering data, do not fully update window
1301+ int64_t data_size = stream->read_vio_read_avail ();
1302+ if (data_size >= initial_rwnd) {
1303+ return ;
1304+ }
1305+
1306+ Http2WindowSize diff_size = initial_rwnd - std::max (static_cast <int64_t >(stream->server_rwnd ()), data_size);
1307+ stream->increment_server_rwnd (diff_size);
1308+ this ->send_window_update_frame (stream->get_id (), diff_size);
1309+ }
1310+
12911311void
12921312Http2ConnectionState::cleanup_streams ()
12931313{
@@ -1497,6 +1517,12 @@ Http2ConnectionState::send_a_data_frame(Http2Stream *stream, size_t &payload_len
14971517 return Http2SendDataFrameResult::ERROR;
14981518 }
14991519
1520+ SCOPED_MUTEX_LOCK (lock, this ->ua_session ->mutex , this_ethread ());
1521+ if (this ->ua_session ->write_avail () == 0 ) {
1522+ Http2StreamDebug (this ->ua_session , stream->get_id (), " Not write avail" );
1523+ return Http2SendDataFrameResult::NOT_WRITE_AVAIL;
1524+ }
1525+
15001526 // Select appropriate payload length
15011527 if (resp_reader->is_read_avail_more_than (0 )) {
15021528 // We only need to check for window size when there is a payload
@@ -1872,7 +1898,7 @@ Http2ConnectionState::send_goaway_frame(Http2StreamId id, Http2ErrorCode ec)
18721898void
18731899Http2ConnectionState::send_window_update_frame (Http2StreamId id, uint32_t size)
18741900{
1875- Http2StreamDebug (ua_session, id, " Send WINDOW_UPDATE frame" );
1901+ Http2StreamDebug (ua_session, id, " Send WINDOW_UPDATE frame: size=% " PRIu32, size );
18761902
18771903 // Create WINDOW_UPDATE frame
18781904 Http2WindowUpdateFrame window_update (id, size);
0 commit comments