Chromium Code Reviews| Index: content/browser/loader/detachable_resource_handler.cc |
| diff --git a/content/browser/loader/detachable_resource_handler.cc b/content/browser/loader/detachable_resource_handler.cc |
| index c534a25ad317cf64b74168338ec838355caf407f..81dc5eefc41b7ca55e28081eff0869d59dd2d2d1 100644 |
| --- a/content/browser/loader/detachable_resource_handler.cc |
| +++ b/content/browser/loader/detachable_resource_handler.cc |
| @@ -36,7 +36,7 @@ class DetachableResourceHandler::Controller : public ResourceController { |
| // ResourceController implementation: |
| void Resume() override { |
| MarkAsUsed(); |
| - detachable_handler_->Resume(); |
| + detachable_handler_->ResumeInternal(); |
| } |
| void Cancel() override { |
| @@ -78,6 +78,8 @@ DetachableResourceHandler::DetachableResourceHandler( |
| : ResourceHandler(request), |
| next_handler_(std::move(next_handler)), |
| cancel_delay_(cancel_delay), |
| + parent_read_buffer_(nullptr), |
| + parent_read_buffer_size_(0), |
|
Charlie Harrison
2017/03/08 21:12:46
nit: Shouldn't this be nullptr as well? Same elsew
mmenke
2017/03/08 22:51:30
Done. You're right, I just see "size" in a name a
|
| is_finished_(false) { |
| GetRequestInfo()->set_detachable_handler(this); |
| } |
| @@ -134,6 +136,23 @@ void DetachableResourceHandler::Detach() { |
| // The nested ResourceHandler may have logged that it's blocking the |
| // request. Log it as no longer doing so, to avoid a DCHECK on resume. |
| request()->LogUnblocked(); |
| + |
| + // If in the middle of an OnWillRead call, need to allocate the read buffer |
| + // before resuming. |
| + if (parent_read_buffer_) { |
| + DCHECK(parent_read_buffer_size_); |
| + |
| + scoped_refptr<net::IOBuffer>* parent_read_buffer = parent_read_buffer_; |
| + int* parent_read_buffer_size = parent_read_buffer_size_; |
| + parent_read_buffer_ = nullptr; |
| + parent_read_buffer_size_ = 0; |
|
Charlie Harrison
2017/03/08 21:12:46
= nullptr
mmenke
2017/03/08 22:51:30
Done.
|
| + |
| + // Will allocate the buffer and resume the request. |
| + OnWillRead(parent_read_buffer, parent_read_buffer_size, |
| + ReleaseController()); |
| + return; |
| + } |
| + |
| Resume(); |
| } |
| } |
| @@ -183,17 +202,24 @@ void DetachableResourceHandler::OnWillStart( |
| next_handler_->OnWillStart(url, base::MakeUnique<Controller>(this)); |
| } |
| -bool DetachableResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
| - int* buf_size) { |
| +void DetachableResourceHandler::OnWillRead( |
| + scoped_refptr<net::IOBuffer>* buf, |
| + int* buf_size, |
| + std::unique_ptr<ResourceController> controller) { |
| if (!next_handler_) { |
| if (!read_buffer_.get()) |
| read_buffer_ = new net::IOBuffer(kReadBufSize); |
| *buf = read_buffer_; |
| *buf_size = kReadBufSize; |
| - return true; |
| + controller->Resume(); |
| + return; |
| } |
| - return next_handler_->OnWillRead(buf, buf_size); |
| + parent_read_buffer_ = buf; |
| + parent_read_buffer_size_ = buf_size; |
| + |
| + HoldController(std::move(controller)); |
| + next_handler_->OnWillRead(buf, buf_size, base::MakeUnique<Controller>(this)); |
| } |
| void DetachableResourceHandler::OnReadCompleted( |
| @@ -236,6 +262,12 @@ void DetachableResourceHandler::OnDataDownloaded(int bytes_downloaded) { |
| next_handler_->OnDataDownloaded(bytes_downloaded); |
| } |
| +void DetachableResourceHandler::ResumeInternal() { |
| + parent_read_buffer_ = nullptr; |
| + parent_read_buffer_size_ = nullptr; |
| + Resume(); |
| +} |
| + |
| void DetachableResourceHandler::OnTimedOut() { |
| // Requests are only timed out after being detached, and shouldn't be deferred |
| // once detached. |