Chromium Code Reviews| Index: net/http/http_stream_factory_impl_job.cc |
| diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc |
| index 99ad829180dd9936e5383aa880eaf8e54cdc8995..641af22520596d4c18fc5898d0528afe69879bfd 100644 |
| --- a/net/http/http_stream_factory_impl_job.cc |
| +++ b/net/http/http_stream_factory_impl_job.cc |
| @@ -204,6 +204,7 @@ HttpStreamFactoryImpl::Job::Job(Delegate* delegate, |
| origin_url_, |
| request_info_.privacy_mode)), |
| stream_type_(HttpStreamRequest::BIDIRECTIONAL_STREAM), |
| + init_connection_already_resumed_(false), |
| ptr_factory_(this) { |
| DCHECK(session); |
| if (alternative_protocol != kProtoUnknown) { |
| @@ -554,6 +555,10 @@ void HttpStreamFactoryImpl::Job::RunLoop(int result) { |
| if (result == ERR_IO_PENDING) |
| return; |
| + // Resume all throttled Jobs with the same SpdySessionKey if there are any, |
| + // now that this job is done. |
| + session_->spdy_session_pool()->ResumePendingRequests(spdy_session_key_); |
| + |
| if (job_type_ == PRECONNECT) { |
| base::ThreadTaskRunnerHandle::Get()->PostTask( |
| FROM_HERE, |
| @@ -685,6 +690,10 @@ int HttpStreamFactoryImpl::Job::DoLoop(int result) { |
| case STATE_WAIT_COMPLETE: |
| rv = DoWaitComplete(rv); |
| break; |
| + case STATE_EVALUATE_THROTTLE: |
| + DCHECK_EQ(OK, rv); |
| + rv = DoEvaluateThrottle(); |
| + break; |
| case STATE_INIT_CONNECTION: |
| DCHECK_EQ(OK, rv); |
| rv = DoInitConnection(); |
| @@ -762,10 +771,49 @@ int HttpStreamFactoryImpl::Job::DoWait() { |
| int HttpStreamFactoryImpl::Job::DoWaitComplete(int result) { |
| net_log_.EndEvent(NetLogEventType::HTTP_STREAM_JOB_WAITING); |
| DCHECK_EQ(OK, result); |
| - next_state_ = STATE_INIT_CONNECTION; |
| + next_state_ = STATE_EVALUATE_THROTTLE; |
| return OK; |
| } |
| +int HttpStreamFactoryImpl::Job::DoEvaluateThrottle() { |
| + next_state_ = STATE_INIT_CONNECTION; |
| + if (!using_ssl_) |
| + return OK; |
| + // Ask |delegate_delegate_| to update the spdy session key for the request |
| + // that launched this job. |
| + delegate_->SetSpdySessionKey(this, spdy_session_key_); |
| + |
| + // Throttle connect to an HTTP/2 supported server, if there are pending |
| + // requests with the same SpdySessionKey. |
| + if (session_->http_server_properties()->RequiresHTTP11( |
| + spdy_session_key_.host_port_pair())) |
| + return OK; |
| + url::SchemeHostPort scheme_host_port( |
| + using_ssl_ ? url::kHttpsScheme : url::kHttpScheme, |
| + spdy_session_key_.host_port_pair().host(), |
| + spdy_session_key_.host_port_pair().port()); |
| + if (!session_->http_server_properties()->GetSupportsSpdy(scheme_host_port)) |
| + return OK; |
| + base::Closure callback = |
| + base::Bind(&HttpStreamFactoryImpl::Job::ResumeInitConnection, |
| + ptr_factory_.GetWeakPtr()); |
| + if (session_->spdy_session_pool()->StartRequest(spdy_session_key_, |
| + callback)) { |
| + return OK; |
| + } |
| + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| + FROM_HERE, callback, base::TimeDelta::FromMilliseconds(kHTTP2ThrottleMs)); |
| + return ERR_IO_PENDING; |
| +} |
| + |
| +void HttpStreamFactoryImpl::Job::ResumeInitConnection() { |
| + if (init_connection_already_resumed_) |
| + return; |
| + CHECK_EQ(next_state_, STATE_INIT_CONNECTION); |
|
Bence
2017/06/15 13:37:46
Very optional: a DCHECK should be enough here.
xunjieli
2017/06/15 13:53:25
Thanks. I add a TODO to change it back to DCHECK.
|
| + init_connection_already_resumed_ = true; |
| + OnIOComplete(OK); |
| +} |
| + |
| int HttpStreamFactoryImpl::Job::DoInitConnection() { |
| net_log_.BeginEvent(NetLogEventType::HTTP_STREAM_JOB_INIT_CONNECTION); |
| int result = DoInitConnectionImpl(); |
| @@ -873,11 +921,6 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionImpl() { |
| return OK; |
| } |
| } |
| - if (using_ssl_) { |
| - // Ask |delegate_delegate_| to update the spdy session key for the request |
| - // that launched this job. |
| - delegate_->SetSpdySessionKey(this, spdy_session_key_); |
| - } |
| if (proxy_info_.is_http() || proxy_info_.is_https()) |
| establishing_tunnel_ = using_ssl_; |