Add new API to return effective received data length and local window size

This commit is contained in:
Tatsuhiro Tsujikawa 2013-10-30 00:07:35 +09:00
parent 9b6a0e5875
commit 6c23c34d77
7 changed files with 98 additions and 12 deletions

View File

@ -1550,6 +1550,38 @@ void* nghttp2_session_get_stream_user_data(nghttp2_session *session,
*/
size_t nghttp2_session_get_outbound_queue_size(nghttp2_session *session);
/**
* @function
*
* Returns the number of DATA payload in bytes received without
* WINDOW_UPDATE transmission for the stream |stream_id|. The local
* (receive) window size can be adjusted by
* `nghttp2_submit_window_update()`. This function takes into account
* that and returns effective data length. In particular, if the
* local window size is reduced by submitting negative
* window_size_increment with `nghttp2_submit_window_update()`, this
* function returns the number of bytes less than actually received.
*
* If flow control is disabled for that stream, this function returns
* 0.
*
* This function returns -1 if it fails.
*/
int32_t nghttp2_session_get_stream_effective_recv_data_length
(nghttp2_session *session, int32_t stream_id);
/**
* @function
*
* Returns the local (receive) window size. The local window size can
* be adjusted by `nghttp2_submit_window_update()`. This function
* takes into account that and returns effective window size.
*
* This function returns -1 if it fails.
*/
int32_t nghttp2_session_get_stream_effective_local_window_size
(nghttp2_session *session, int32_t stream_id);
/**
* @function
*

View File

@ -3571,6 +3571,31 @@ size_t nghttp2_session_get_outbound_queue_size(nghttp2_session *session)
return nghttp2_pq_size(&session->ob_pq)+nghttp2_pq_size(&session->ob_ss_pq);
}
int32_t nghttp2_session_get_stream_effective_recv_data_length
(nghttp2_session *session, int32_t stream_id)
{
nghttp2_stream *stream;
stream = nghttp2_session_get_stream(session, stream_id);
if(stream == NULL) {
return -1;
}
if(stream->local_flow_control == 0) {
return 0;
}
return stream->recv_window_size;
}
int32_t nghttp2_session_get_stream_effective_local_window_size
(nghttp2_session *session, int32_t stream_id)
{
nghttp2_stream *stream;
stream = nghttp2_session_get_stream(session, stream_id);
if(stream == NULL) {
return -1;
}
return stream->local_window_size;
}
int nghttp2_session_set_option(nghttp2_session *session,
int optname, void *optval, size_t optlen)
{

View File

@ -723,12 +723,13 @@ int Http2Upstream::rst_stream(Downstream *downstream,
return 0;
}
int Http2Upstream::window_update(Downstream *downstream)
int Http2Upstream::window_update(Downstream *downstream,
int32_t window_size_increment)
{
int rv;
rv = nghttp2_submit_window_update(session_, NGHTTP2_FLAG_NONE,
downstream->get_stream_id(),
downstream->get_recv_window_size());
window_size_increment);
downstream->set_recv_window_size(0);
if(rv < NGHTTP2_ERR_FATAL) {
ULOG(FATAL, this) << "nghttp2_submit_window_update() failed: "
@ -962,8 +963,15 @@ void Http2Upstream::pause_read(IOCtrlReason reason)
int Http2Upstream::resume_read(IOCtrlReason reason, Downstream *downstream)
{
if(get_flow_control()) {
if(downstream->get_recv_window_size() >= get_initial_window_size()/2) {
window_update(downstream);
int32_t recv_length, window_size;
recv_length = nghttp2_session_get_stream_effective_recv_data_length
(session_, downstream->get_stream_id());
window_size = nghttp2_session_get_stream_effective_local_window_size
(session_, downstream->get_stream_id());
if(recv_length != -1 && window_size != -1) {
if(recv_length >= window_size / 2) {
window_update(downstream, recv_length);
}
}
}
return send();

View File

@ -58,7 +58,7 @@ public:
nghttp2_session* get_spdy_session();
int rst_stream(Downstream *downstream, nghttp2_error_code error_code);
int window_update(Downstream *downstream);
int window_update(Downstream *downstream, int32_t window_size_increment);
int error_reply(Downstream *downstream, unsigned int status_code);
virtual void pause_read(IOCtrlReason reason);

View File

@ -442,14 +442,20 @@ int SpdyDownstreamConnection::resume_read(IOCtrlReason reason)
int rv;
if(spdy_->get_state() == SpdySession::CONNECTED &&
spdy_->get_flow_control() &&
downstream_ && downstream_->get_downstream_stream_id() != -1 &&
recv_window_size_ >= spdy_->get_initial_window_size()/2) {
rv = spdy_->submit_window_update(this, recv_window_size_);
if(rv == -1) {
return -1;
downstream_ && downstream_->get_downstream_stream_id() != -1) {
int32_t recv_length, window_size;
recv_length = spdy_->get_stream_effective_recv_data_length
(downstream_->get_stream_id());
window_size = spdy_->get_stream_effective_local_window_size
(downstream_->get_stream_id());
if(recv_length >= window_size / 2) {
rv = spdy_->submit_window_update(this, recv_length);
if(rv == -1) {
return -1;
}
spdy_->notify();
recv_window_size_ = 0;
}
spdy_->notify();
recv_window_size_ = 0;
}
return 0;
}

View File

@ -618,6 +618,18 @@ int32_t SpdySession::get_initial_window_size() const
return (1 << get_config()->spdy_downstream_window_bits) - 1;
}
int32_t SpdySession::get_stream_effective_recv_data_length(int32_t stream_id)
{
return nghttp2_session_get_stream_effective_recv_data_length
(session_, stream_id);
}
int32_t SpdySession::get_stream_effective_local_window_size(int32_t stream_id)
{
return nghttp2_session_get_stream_effective_local_window_size
(session_, stream_id);
}
bool SpdySession::get_flow_control() const
{
return flow_control_;

View File

@ -74,6 +74,9 @@ public:
int32_t get_initial_window_size() const;
int32_t get_stream_effective_recv_data_length(int32_t stream_id);
int32_t get_stream_effective_local_window_size(int32_t stream_id);
bool get_flow_control() const;
int resume_data(SpdyDownstreamConnection *dconn);