| 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..aa1f7bd608369121b38a115e85e91d442973b088 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_(nullptr),
|
| 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_ = nullptr;
|
| +
|
| + // 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.
|
|
|