Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(950)

Unified Diff: content/browser/loader/mime_sniffing_resource_handler.cc

Issue 2668603003: Make ResourceHandler::OnWillRead able to complete asynchronously. (Closed)
Patch Set: Fix merge (x2) Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/loader/mime_sniffing_resource_handler.cc
diff --git a/content/browser/loader/mime_sniffing_resource_handler.cc b/content/browser/loader/mime_sniffing_resource_handler.cc
index e90fa81d7ff9e2e72de54c88b614a550323ad892..29d9b12a8ffb2231e46839d91dfb8c244ab141ca 100644
--- a/content/browser/loader/mime_sniffing_resource_handler.cc
+++ b/content/browser/loader/mime_sniffing_resource_handler.cc
@@ -125,6 +125,8 @@ MimeSniffingResourceHandler::MimeSniffingResourceHandler(
must_download_is_set_(false),
read_buffer_size_(0),
bytes_read_(0),
+ parent_read_buffer_(nullptr),
+ parent_read_buffer_size_(nullptr),
intercepting_handler_(intercepting_handler),
request_context_type_(request_context_type),
in_state_loop_(false),
@@ -215,24 +217,41 @@ void MimeSniffingResourceHandler::OnResponseStarted(
AdvanceState();
}
-bool MimeSniffingResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
- int* buf_size) {
- if (state_ == STATE_STREAMING)
- return next_handler_->OnWillRead(buf, buf_size);
+void MimeSniffingResourceHandler::OnWillRead(
+ scoped_refptr<net::IOBuffer>* buf,
+ int* buf_size,
+ std::unique_ptr<ResourceController> controller) {
+ DCHECK(buf);
+ DCHECK(buf_size);
+ DCHECK(!parent_read_buffer_);
+ DCHECK(!parent_read_buffer_size_);
+
+ if (state_ == STATE_STREAMING) {
+ next_handler_->OnWillRead(buf, buf_size, std::move(controller));
+ return;
+ }
+
+ DCHECK_EQ(State::STATE_BUFFERING, state_);
if (read_buffer_.get()) {
CHECK_LT(bytes_read_, read_buffer_size_);
*buf = new DependentIOBuffer(read_buffer_.get(), bytes_read_);
*buf_size = read_buffer_size_ - bytes_read_;
- } else {
- if (!next_handler_->OnWillRead(buf, buf_size))
- return false;
-
- read_buffer_ = *buf;
- read_buffer_size_ = *buf_size;
- DCHECK_GE(read_buffer_size_, net::kMaxBytesToSniff * 2);
+ controller->Resume();
+ return;
}
- return true;
+
+ DCHECK(!read_buffer_size_);
+
+ parent_read_buffer_ = buf;
+ parent_read_buffer_size_ = buf_size;
+
+ HoldController(std::move(controller));
+
+ // Have to go through AdvanceState here so that if OnWillRead completes
+ // synchronously, won't post a task.
+ state_ = State::STATE_CALLING_ON_WILL_READ;
+ AdvanceState();
}
void MimeSniffingResourceHandler::OnReadCompleted(
@@ -316,6 +335,12 @@ void MimeSniffingResourceHandler::AdvanceState() {
case STATE_BUFFERING:
MaybeIntercept();
break;
+ case STATE_CALLING_ON_WILL_READ:
+ CallOnWillRead();
+ break;
+ case STATE_WAITING_FOR_BUFFER:
+ BufferReceived();
+ break;
case STATE_INTERCEPTION_CHECK_DONE:
ReplayResponseReceived();
break;
@@ -324,7 +349,6 @@ void MimeSniffingResourceHandler::AdvanceState() {
break;
case STATE_STARTING:
case STATE_STREAMING:
- in_state_loop_ = false;
Resume();
return;
default:
@@ -348,6 +372,32 @@ void MimeSniffingResourceHandler::MaybeIntercept() {
ResumeInternal();
}
+void MimeSniffingResourceHandler::CallOnWillRead() {
+ DCHECK_EQ(STATE_CALLING_ON_WILL_READ, state_);
+
+ state_ = STATE_WAITING_FOR_BUFFER;
+ next_handler_->OnWillRead(&read_buffer_, &read_buffer_size_,
+ base::MakeUnique<Controller>(this));
+}
+
+void MimeSniffingResourceHandler::BufferReceived() {
+ DCHECK_EQ(STATE_WAITING_FOR_BUFFER, state_);
+
+ DCHECK(read_buffer_);
+ DCHECK(parent_read_buffer_);
+ DCHECK(parent_read_buffer_size_);
+ DCHECK_GE(read_buffer_size_, net::kMaxBytesToSniff * 2);
+
+ *parent_read_buffer_ = read_buffer_;
+ *parent_read_buffer_size_ = read_buffer_size_;
+
+ parent_read_buffer_ = nullptr;
+ parent_read_buffer_size_ = nullptr;
+
+ state_ = State::STATE_BUFFERING;
+ Resume();
+}
+
void MimeSniffingResourceHandler::ReplayResponseReceived() {
DCHECK_EQ(STATE_INTERCEPTION_CHECK_DONE, state_);
state_ = STATE_REPLAYING_RESPONSE_RECEIVED;

Powered by Google App Engine
This is Rietveld 408576698