Index: content/browser/loader/async_resource_handler.cc |
diff --git a/content/browser/loader/async_resource_handler.cc b/content/browser/loader/async_resource_handler.cc |
index 78e0dab415bb2318f7548a6154c65f18d018faa3..f4c3921884c799db7898b65972ef17e5b32f19c8 100644 |
--- a/content/browser/loader/async_resource_handler.cc |
+++ b/content/browser/loader/async_resource_handler.cc |
@@ -190,9 +190,9 @@ class DependentIOBuffer : public net::WrappedIOBuffer { |
scoped_refptr<ResourceBuffer> backing_; |
}; |
-AsyncResourceHandler::AsyncResourceHandler( |
- net::URLRequest* request, |
- ResourceDispatcherHostImpl* rdh) |
+AsyncResourceHandler::AsyncResourceHandler(net::URLRequest* request, |
+ ResourceDispatcherHostImpl* rdh, |
+ bool using_mojo_data_handle) |
: ResourceHandler(request), |
ResourceMessageDelegate(request), |
rdh_(rdh), |
@@ -202,6 +202,7 @@ AsyncResourceHandler::AsyncResourceHandler( |
has_checked_for_sufficient_resources_(false), |
sent_received_response_msg_(false), |
sent_data_buffer_msg_(false), |
+ using_mojo_data_handle_(using_mojo_data_handle), |
inlining_helper_(new InliningHelper), |
last_upload_position_(0), |
waiting_for_upload_progress_ack_(false), |
@@ -369,6 +370,19 @@ bool AsyncResourceHandler::OnResponseStarted(ResourceResponse* response, |
response->head.request_start = request()->creation_time(); |
response->head.response_start = TimeTicks::Now(); |
+ if (using_mojo_data_handle_) { |
+ MojoCreateDataPipeOptions options; |
+ options.struct_size = sizeof(MojoCreateDataPipeOptions); |
+ options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; |
+ options.element_num_bytes = 1; |
+ options.capacity_num_bytes = kMaxAllocationSize; |
+ mojo::DataPipe data_pipe(options); |
+ mojo::ScopedDataPipeConsumerHandle handle; |
+ |
+ writer_ = std::move(data_pipe.producer_handle); |
+ GetRequestInfo()->InstallBodyReader(std::move(data_pipe.consumer_handle)); |
+ } |
+ |
info->filter()->Send(new ResourceMsg_ReceivedResponse(GetRequestID(), |
response->head)); |
sent_received_response_msg_ = true; |
@@ -410,6 +424,20 @@ bool AsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
if (!CheckForSufficientResource()) |
return false; |
+ if (using_mojo_data_handle_) { |
+ void* buffer = nullptr; |
+ uint32_t available = 0; |
+ MojoResult result = mojo::BeginWriteDataRaw( |
+ writer_.get(), &buffer, &available, MOJO_WRITE_DATA_FLAG_NONE); |
+ // Note that we cannot handle SHOULD_WAIT here. It should be handled in |
+ // OnReadCompleted. |
+ if (result == MOJO_RESULT_OK) { |
+ *buf = new net::WrappedIOBuffer(static_cast<const char*>(buffer)); |
+ *buf_size = available; |
+ return true; |
+ } |
+ return false; |
+ } |
// Return early if InliningHelper allocates the buffer, so that we should |
// inline the data into the IPC message without allocating SharedMemory. |
if (inlining_helper_->PrepareInlineBufferIfApplicable(buf, buf_size)) |
@@ -434,6 +462,29 @@ bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { |
if (!bytes_read) |
return true; |
+ if (using_mojo_data_handle_) { |
+ MojoResult result = mojo::EndWriteDataRaw(writer_.get(), bytes_read); |
+ if (result != MOJO_RESULT_OK) |
+ return false; |
+ void* buffer = nullptr; |
+ uint32_t available = 0; |
+ // To see if we can continue writing. |
+ result = mojo::BeginWriteDataRaw(writer_.get(), &buffer, &available, |
+ MOJO_WRITE_DATA_FLAG_NONE); |
+ if (result == MOJO_RESULT_SHOULD_WAIT || |
+ (result == MOJO_RESULT_OK && available == 0)) { |
+ *defer = did_defer_ = true; |
+ OnDefer(); |
+ handle_watcher_.Start(writer_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, |
+ MOJO_DEADLINE_INDEFINITE, |
+ base::Bind(&AsyncResourceHandler::OnWritable, |
+ base::Unretained(this))); |
+ } |
+ if (result == MOJO_RESULT_OK) |
+ mojo::EndWriteDataRaw(writer_.get(), 0); |
+ return true; |
+ } |
+ |
ResourceMessageFilter* filter = GetFilter(); |
if (!filter) |
return false; |
@@ -607,4 +658,8 @@ void AsyncResourceHandler::RecordHistogram() { |
inlining_helper_->RecordHistogram(elapsed_time); |
} |
+void AsyncResourceHandler::OnWritable(MojoResult result) { |
+ ResumeIfDeferred(); |
+} |
+ |
} // namespace content |