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 fad7272c86a890efc3ac61ec386821143b57f15e..6915d72c1da8399a713c044e69deab9566541d6d 100644 |
| --- a/net/http/http_stream_factory_impl_job.cc |
| +++ b/net/http/http_stream_factory_impl_job.cc |
| @@ -203,8 +203,6 @@ HttpStreamFactoryImpl::Job::Job(JobController* job_controller, |
| alternative_service_(alternative_service), |
| job_controller_(job_controller), |
| job_type_(job_type), |
| - blocking_job_(NULL), |
| - waiting_job_(NULL), |
| using_ssl_(false), |
| using_spdy_(false), |
| using_quic_(false), |
| @@ -286,61 +284,36 @@ LoadState HttpStreamFactoryImpl::Job::GetLoadState() const { |
| } |
| } |
| -void HttpStreamFactoryImpl::Job::WaitFor(Job* job) { |
| - DCHECK_EQ(STATE_NONE, next_state_); |
| - DCHECK_EQ(STATE_NONE, job->next_state_); |
| - DCHECK(!blocking_job_); |
| - DCHECK(!job->waiting_job_); |
| - |
| - // Never share connection with other jobs for FTP requests. |
| - DCHECK(!request_info_.url.SchemeIs("ftp")); |
| - |
| - blocking_job_ = job; |
| - job->waiting_job_ = this; |
| -} |
| - |
| -void HttpStreamFactoryImpl::Job::ResumeAfterDelay() { |
| - DCHECK(!blocking_job_); |
| - DCHECK_EQ(STATE_WAIT_FOR_JOB_COMPLETE, next_state_); |
| +void HttpStreamFactoryImpl::Job::ResumeAfterDelay( |
| + const base::TimeDelta& delay) { |
| + DCHECK((job_type_ == ALTERNATIVE || !job_controller_->blocking())); |
| net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_DELAYED, |
| - base::Bind(&NetLogHttpStreamJobDelayCallback, wait_time_)); |
| + base::Bind(&NetLogHttpStreamJobDelayCallback, delay)); |
| base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| FROM_HERE, base::Bind(&HttpStreamFactoryImpl::Job::OnIOComplete, |
| ptr_factory_.GetWeakPtr(), OK), |
| - wait_time_); |
| + delay); |
| } |
| -void HttpStreamFactoryImpl::Job::Resume(Job* job, |
| - const base::TimeDelta& delay) { |
| - DCHECK_EQ(blocking_job_, job); |
| - blocking_job_ = NULL; |
| - |
| +void HttpStreamFactoryImpl::Job::Resume(const base::TimeDelta& delay) { |
| + DCHECK_EQ(job_type_, MAIN); |
| // If |this| job is not past STATE_WAIT_FOR_JOB_COMPLETE state, then it will |
| - // be delayed by the |wait_time_| when it resumes. |
| + // be delayed by the |delay| when it resumes. |
| if (next_state_ == STATE_NONE || next_state_ <= STATE_WAIT_FOR_JOB_COMPLETE) |
| - wait_time_ = delay; |
| + job_controller_->SetWaitTimeForMainJob(delay); |
| // We know we're blocked if the next_state_ is STATE_WAIT_FOR_JOB_COMPLETE. |
| // Unblock |this|. |
| if (next_state_ == STATE_WAIT_FOR_JOB_COMPLETE) |
| - ResumeAfterDelay(); |
| + ResumeAfterDelay(job_controller_->GetWaitTime()); |
| } |
| void HttpStreamFactoryImpl::Job::Orphan() { |
| net_log_.AddEvent(NetLog::TYPE_HTTP_STREAM_JOB_ORPHANED); |
| - if (blocking_job_) { |
| - // We've been orphaned, but there's a job we're blocked on. Don't bother |
| - // racing, just cancel ourself. |
| - DCHECK(blocking_job_->waiting_job_); |
| - blocking_job_->waiting_job_ = NULL; |
| - blocking_job_ = NULL; |
| - if (job_controller_->for_websockets() && connection_ && |
| - connection_->socket()) { |
| - connection_->socket()->Disconnect(); |
| - } |
| - job_controller_->OnOrphanedJobComplete(this); |
| - } else if (job_controller_->for_websockets()) { |
| + |
| + job_controller_->MaybeResumeOtherJob(this, base::TimeDelta()); |
| + if (job_controller_->for_websockets()) { |
| // We cancel this job because a WebSocketHandshakeStream can't be created |
| // without a WebSocketHandshakeStreamBase::CreateHelper which is stored in |
| // the Request class and isn't retrievable by this job. |
| @@ -559,9 +532,9 @@ int HttpStreamFactoryImpl::Job::RunLoop(int result) { |
| if (result == ERR_IO_PENDING) |
| return result; |
| - // If there was an error, we should have already resumed the |waiting_job_|, |
| - // if there was one. |
| - DCHECK(result == OK || waiting_job_ == NULL); |
| + // If there was an error, we should have already resumed the other waiting |
| + // job, if there was one. |
| + DCHECK(result == OK || job_type_ == MAIN || !job_controller_->blocking()); |
| if (job_type_ == PRECONNECT) { |
| base::ThreadTaskRunnerHandle::Get()->PostTask( |
| @@ -762,10 +735,7 @@ int HttpStreamFactoryImpl::Job::DoStart() { |
| // Don't connect to restricted ports. |
| if (!IsPortAllowedForScheme(destination_.port(), |
| request_info_.url.scheme())) { |
| - if (waiting_job_) { |
| - waiting_job_->Resume(this, base::TimeDelta()); |
| - waiting_job_ = NULL; |
| - } |
| + job_controller_->MaybeResumeOtherJob(this, base::TimeDelta()); |
|
Ryan Hamilton
2016/05/17 22:14:09
As discussed offline, I *think* we can move the lo
Randy Smith (Not in Mondays)
2016/05/25 21:22:21
+1; one of my reactions to this CL is that we're n
|
| return ERR_UNSAFE_PORT; |
| } |
| @@ -838,10 +808,7 @@ int HttpStreamFactoryImpl::Job::DoResolveProxyComplete(int result) { |
| } |
| if (result != OK) { |
| - if (waiting_job_) { |
| - waiting_job_->Resume(this, base::TimeDelta()); |
| - waiting_job_ = NULL; |
| - } |
| + job_controller_->MaybeResumeOtherJob(this, base::TimeDelta()); |
| return result; |
| } |
| @@ -857,26 +824,19 @@ bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { |
| } |
| int HttpStreamFactoryImpl::Job::DoWaitForJob() { |
| - if (!blocking_job_ && wait_time_.is_zero()) { |
| - // There is no |blocking_job_| and there is no |wait_time_|. |
| + if (job_controller_->ResumeJobWithDelay(this)) { |
|
Ryan Hamilton
2016/05/17 22:14:09
I'm quite happy with the logic here. Yay!
It'd be
Zhongyi Shi
2016/06/29 21:49:03
Done.
|
| + next_state_ = STATE_WAIT_FOR_JOB_COMPLETE; |
| + return ERR_IO_PENDING; |
| + } else { |
|
Ryan Hamilton
2016/05/17 22:14:09
nit: no need for else since if() returned.
Zhongyi Shi
2016/06/29 21:49:03
Done.
|
| next_state_ = STATE_INIT_CONNECTION; |
| return OK; |
| } |
| - |
| - next_state_ = STATE_WAIT_FOR_JOB_COMPLETE; |
| - if (!wait_time_.is_zero()) { |
| - // If there is a waiting_time, then resume the job after the wait_time_. |
| - DCHECK(!blocking_job_); |
| - ResumeAfterDelay(); |
| - } |
| - |
| - return ERR_IO_PENDING; |
| } |
| int HttpStreamFactoryImpl::Job::DoWaitForJobComplete(int result) { |
| - DCHECK(!blocking_job_); |
| + DCHECK((job_type_ == ALTERNATIVE || !job_controller_->blocking())); |
| DCHECK_EQ(OK, result); |
| - wait_time_ = base::TimeDelta(); |
| + job_controller_->SetWaitTimeForMainJob(base::TimeDelta()); |
| next_state_ = STATE_INIT_CONNECTION; |
| return OK; |
| } |
| @@ -886,7 +846,7 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { |
| tracked_objects::ScopedTracker tracking_profile( |
| FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| "462812 HttpStreamFactoryImpl::Job::DoInitConnection")); |
| - DCHECK(!blocking_job_); |
| + DCHECK((job_type_ == ALTERNATIVE || !job_controller_->blocking())); |
| DCHECK(!connection_->is_initialized()); |
| DCHECK(proxy_info_.proxy_server().is_valid()); |
| next_state_ = STATE_INIT_CONNECTION_COMPLETE; |
| @@ -958,22 +918,18 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { |
| if (rv == OK) { |
| using_existing_quic_session_ = true; |
| } else { |
| - // OK, there's no available QUIC session. Let |waiting_job_| resume |
| - // if it's paused. |
| - if (waiting_job_) { |
| - if (rv == ERR_IO_PENDING) { |
| - // Start the |waiting_job_| after the delay returned by |
| - // GetTimeDelayForWaitingJob(). |
| - // |
| - // If QUIC request fails during handshake, then |
| - // DoInitConnectionComplete() will start the |waiting_job_|. |
| - waiting_job_->Resume(this, quic_request_.GetTimeDelayForWaitingJob()); |
| - } else { |
| - // QUIC request has failed, resume the |waiting_job_|. |
| - waiting_job_->Resume(this, base::TimeDelta()); |
| - } |
| - waiting_job_ = NULL; |
| + base::TimeDelta delay; |
| + // OK, there's no available QUIC session. Let JobController to resume |
| + // the waiting job if it's paused. |
| + if (rv == ERR_IO_PENDING) { |
| + // Start the waiting job after the delay returned by |
| + // GetTimeDelayForWaitingJob(). |
| + // |
| + // If QUIC request fails during handshake, then |
| + // DoInitConnectionComplete() will start the waiting job. |
| + delay = quic_request_.GetTimeDelayForWaitingJob(); |
| } |
| + job_controller_->MaybeResumeOtherJob(this, delay); |
|
Ryan Hamilton
2016/05/17 22:14:09
Looking at this line (and the line below in this s
|
| } |
| return rv; |
| } |
| @@ -1005,12 +961,9 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { |
| job_controller_->SetSpdySessionKey(this, spdy_session_key); |
| } |
| - // OK, there's no available SPDY session. Let |waiting_job_| resume if it's |
| - // paused. |
| - if (waiting_job_) { |
| - waiting_job_->Resume(this, base::TimeDelta()); |
| - waiting_job_ = NULL; |
| - } |
| + // OK, there's no available SPDY session. Let JobController to resume the |
| + // non-alternative job if it's paused. |
| + job_controller_->MaybeResumeOtherJob(this, base::TimeDelta()); |
| if (proxy_info_.is_http() || proxy_info_.is_https()) |
| establishing_tunnel_ = using_ssl_; |
| @@ -1064,9 +1017,8 @@ int HttpStreamFactoryImpl::Job::DoInitConnection() { |
| } |
| int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { |
| - if (using_quic_ && result < 0 && waiting_job_) { |
| - waiting_job_->Resume(this, base::TimeDelta()); |
| - waiting_job_ = NULL; |
| + if (using_quic_ && result < 0) { |
| + job_controller_->MaybeResumeOtherJob(this, base::TimeDelta()); |
| } |
| if (job_type_ == PRECONNECT) { |
| if (using_quic_) |
| @@ -1104,9 +1056,8 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { |
| // TODO(willchan): Make this a bit more exact. Maybe there are recoverable |
| // errors, such as ignoring certificate errors for Alternate-Protocol. |
| - if (result < 0 && waiting_job_) { |
| - waiting_job_->Resume(this, base::TimeDelta()); |
| - waiting_job_ = NULL; |
| + if (result < 0) { |
| + job_controller_->MaybeResumeOtherJob(this, base::TimeDelta()); |
| } |
| // |result| may be the result of any of the stacked pools. The following |