h2load: Support -W option for SPDY, if the value >= 16

This commit is contained in:
Tatsuhiro Tsujikawa 2014-03-14 01:40:41 +09:00
parent 2b7627f70c
commit 136d997596
3 changed files with 69 additions and 1 deletions

View File

@ -555,7 +555,9 @@ Options:
(2**<N>)-1. For SPDY, 2**<N> is used instead. (2**<N>)-1. For SPDY, 2**<N> is used instead.
-W, --connection-window-bits=<N> -W, --connection-window-bits=<N>
Sets the connection level initial window size to Sets the connection level initial window size to
(2**<N>)-1. This option does not work with SPDY. (2**<N>)-1. For SPDY, if <N> is strictly less
than 16, this option is ignored. Otherwise
2**<N> is used for SPDY.
-v, --verbose Output debug information. -v, --verbose Output debug information.
--version Display version information and exit. --version Display version information and exit.
-h, --help Display this help and exit.)" -h, --help Display this help and exit.)"

View File

@ -82,6 +82,10 @@ void on_data_chunk_recv_callback
{ {
auto client = static_cast<Client*>(user_data); auto client = static_cast<Client*>(user_data);
client->worker->stats.bytes_body += len; client->worker->stats.bytes_body += len;
auto spdy_session = static_cast<SpdySession*>(client->session.get());
spdy_session->handle_window_update(stream_id, len);
} }
} // namespace } // namespace
@ -123,12 +127,25 @@ void SpdySession::on_connect()
spdylay_session_client_new(&session_, spdy_version_, &callbacks, client_); spdylay_session_client_new(&session_, spdy_version_, &callbacks, client_);
int val = 1;
spdylay_session_set_option(session_, SPDYLAY_OPT_NO_AUTO_WINDOW_UPDATE,
&val, sizeof(val));
spdylay_settings_entry iv[1]; spdylay_settings_entry iv[1];
iv[0].settings_id = SPDYLAY_SETTINGS_INITIAL_WINDOW_SIZE; iv[0].settings_id = SPDYLAY_SETTINGS_INITIAL_WINDOW_SIZE;
iv[0].flags = SPDYLAY_ID_FLAG_SETTINGS_NONE; iv[0].flags = SPDYLAY_ID_FLAG_SETTINGS_NONE;
iv[0].value = (1 << client_->worker->config->window_bits); iv[0].value = (1 << client_->worker->config->window_bits);
spdylay_submit_settings(session_, SPDYLAY_FLAG_SETTINGS_NONE, iv, spdylay_submit_settings(session_, SPDYLAY_FLAG_SETTINGS_NONE, iv,
sizeof(iv) / sizeof(iv[0])); sizeof(iv) / sizeof(iv[0]));
auto config = client_->worker->config;
if(spdy_version_ >= SPDYLAY_PROTO_SPDY3_1 &&
config->connection_window_bits > 16) {
auto delta = (1 << config->connection_window_bits)
- SPDYLAY_INITIAL_WINDOW_SIZE;
spdylay_submit_window_update(session_, 0, delta);
}
} }
void SpdySession::submit_request() void SpdySession::submit_request()
@ -182,4 +199,52 @@ void SpdySession::terminate()
spdylay_session_fail_session(session_, SPDYLAY_OK); spdylay_session_fail_session(session_, SPDYLAY_OK);
} }
namespace {
int32_t determine_window_update_transmission(spdylay_session *session,
int32_t stream_id,
size_t window_bits)
{
int32_t recv_length;
if(stream_id == 0) {
recv_length = spdylay_session_get_recv_data_length(session);
} else {
recv_length = spdylay_session_get_stream_recv_data_length
(session, stream_id);
}
auto window_size = 1 << window_bits;
if(recv_length != -1 && recv_length >= window_size / 2) {
return recv_length;
}
return -1;
}
} // namespace
void SpdySession::handle_window_update(int32_t stream_id, size_t recvlen)
{
auto config = client_->worker->config;
size_t connection_window_bits;
if(config->connection_window_bits > 16) {
connection_window_bits = config->connection_window_bits;
} else {
connection_window_bits = 16;
}
auto delta = determine_window_update_transmission
(session_, 0, connection_window_bits);
if(delta > 0) {
spdylay_submit_window_update(session_, 0, delta);
}
delta = determine_window_update_transmission
(session_, stream_id, config->window_bits);
if(delta > 0) {
spdylay_submit_window_update(session_, stream_id, delta);
}
}
} // namespace h2load } // namespace h2load

View File

@ -44,6 +44,7 @@ public:
virtual ssize_t on_read(); virtual ssize_t on_read();
virtual int on_write(); virtual int on_write();
virtual void terminate(); virtual void terminate();
void handle_window_update(int32_t stream_id, size_t recvlen);
nghttp2::util::EvbufferBuffer sendbuf; nghttp2::util::EvbufferBuffer sendbuf;
private: private: