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

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

Issue 1693563002: PROTOTYPE: PlzNavigate: use a Mojo data pipe to stream navigation data to the renderer. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Browser sends URLRequest id to the renderer and renderer uses intermediary buffer for data: none he… Created 4 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
« no previous file with comments | « content/browser/loader/mojo_stream_writer.h ('k') | content/browser/loader/navigation_resource_handler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/loader/mojo_stream_writer.cc
diff --git a/content/browser/loader/mojo_stream_writer.cc b/content/browser/loader/mojo_stream_writer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..17afc5f55eb1feefdafd612921c0c7d6493d9b4d
--- /dev/null
+++ b/content/browser/loader/mojo_stream_writer.cc
@@ -0,0 +1,138 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/loader/mojo_stream_writer.h"
+
+#include "base/bind.h"
+#include "base/guid.h"
+#include "base/numerics/safe_conversions.h"
+#include "content/browser/streams/stream.h"
+#include "content/browser/streams/stream_registry.h"
+#include "content/public/browser/resource_controller.h"
+#include "net/base/io_buffer.h"
+#include "url/gurl.h"
+#include "url/url_constants.h"
+
+namespace content {
+
+MojoStreamWriter::MojoStreamWriter()
+ : controller_(nullptr), buffer_(nullptr), buffer_size_(-1) {}
+
+MojoStreamWriter::~MojoStreamWriter() {
+ if (data_producer_handle_.is_valid())
+ Finalize();
+}
+
+void MojoStreamWriter::InitializeStream(
+ mojo::ScopedDataPipeConsumerHandle* data_consumer_handle) {
+ LOG(ERROR) << "MojoStreamWriter@" << this << " InitializeStream";
+ DCHECK(!data_producer_handle_.is_valid());
+
+ // TODO(carlosk): why not have a default constructor for this struct???
+ // The user having to default initialize it is bad.
+ 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 = kReadBufSize;
+
+ mojo::DataPipe data_pipe(options);
+ data_producer_handle_ = std::move(data_pipe.producer_handle);
+ *data_consumer_handle = std::move(data_pipe.consumer_handle);
+
+ // TODO(carlosk): We're creating the buffer ahead of time because:
+ // - I'm guessing that by using mojo::(Begin|End)WriteDataRaw we get access to
+ // the final memory position that has to be written to and avoid temporary
+ // copies.
+ // - And because of the mismatch of the Mojo and this class' APIs in regards
+ // to when the information about the need to defer further writes is available
+ // from Mojo and when deferring is allowed by the calls.
+ // TODO(carlosk): Should make sure MOJO_WRITE_DATA_FLAG_ALL_OR_NONE is in fact
+ // needed here and in the Begin* calls below.
+ // TODO(carlosk): need to properly handle Mojo error cases (MojoResult). Here
+ // and everywhere else.
+ buffer_size_ = kReadBufSize;
+ CHECK_EQ(
+ mojo::BeginWriteDataRaw(data_producer_handle_.get(), &buffer_,
+ &buffer_size_, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE),
+ MOJO_RESULT_OK);
+}
+
+void MojoStreamWriter::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
+ int* buf_size,
+ int min_size) {
+ LOG(ERROR) << "MojoStreamWriter@" << this << " OnWillRead";
+
+ DCHECK(buf);
+ DCHECK(buf_size > 0);
+ DCHECK_LE(min_size, base::checked_cast<int>(kReadBufSize));
+ // TODO(carlosk): using a net::WrappedIOBuffer might be unsafe! The buffer's
+ // life cycle must be better understood and we must be certain there will not
+ // be cases of user after free.
+ *buf = new net::WrappedIOBuffer(static_cast<char*>(buffer_));
+ *buf_size = base::checked_cast<int>(buffer_size_);
+ buffer_ = nullptr;
+ buffer_size_ = -1;
+}
+
+void MojoStreamWriter::OnReadCompleted(int bytes_read, bool* defer) {
+ CHECK(data_producer_handle_.is_valid());
+ LOG(ERROR) << "MojoStreamWriter@" << this
+ << " OnReadCompleted: bytes_read = " << bytes_read;
+ if (!bytes_read)
+ return;
+
+ // We have more data to read.
+ // DCHECK(read_buffer_.get());
+
+ // TODO(carlosk): double check if there's need for the equivalent of
+ // StreamWriter's immediate_mode for Mojo Data Pipes.
+ CHECK_EQ(mojo::EndWriteDataRaw(data_producer_handle_.get(), bytes_read),
+ MOJO_RESULT_OK);
+
+ // TODO(carlosk): hack to comply with the "deferring" interface (further
+ // explained in constructor).
+ buffer_size_ = kReadBufSize;
+ MojoResult result =
+ mojo::BeginWriteDataRaw(data_producer_handle_.get(), &buffer_,
+ &buffer_size_, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
+
+ if (result == MOJO_RESULT_SHOULD_WAIT) {
+ handle_watcher_.Start(data_producer_handle_.get(),
+ MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE,
+ base::Bind(&MojoStreamWriter::OnSpaceAvailable,
+ base::Unretained(this)));
+ *defer = true;
+ LOG(ERROR) << "MojoStreamWriter@" << this
+ << " OnReadCompleted - deferring!";
+ } else {
+ // TODO(carlosk); Must handle errors!
+ CHECK_EQ(result, MOJO_RESULT_OK);
+ }
+}
+
+void MojoStreamWriter::Finalize() {
+ DCHECK(data_producer_handle_.is_valid());
+ if (buffer_ != nullptr) {
+ CHECK_EQ(mojo::EndWriteDataRaw(data_producer_handle_.get(), 0),
+ MOJO_RESULT_OK);
+ buffer_size_ = -1;
+ }
+ data_producer_handle_.reset();
+}
+
+void MojoStreamWriter::OnSpaceAvailable(MojoResult result) {
+ LOG(ERROR) << "MojoStreamWriter@" << this << " OnSpaceAvailable - resuming!";
+ LOG(ERROR) << "MojoStreamWriter@ data_producer_handle_.is_valid(): "
+ << data_producer_handle_.is_valid();
+ LOG(ERROR) << "MojoStreamWriter@ result: " << result;
+ if (result == MOJO_RESULT_OK) {
+ CHECK(data_producer_handle_.is_valid());
+ controller_->Resume();
+ return;
+ }
+ controller_->Cancel();
+}
+
+} // namespace content
« no previous file with comments | « content/browser/loader/mojo_stream_writer.h ('k') | content/browser/loader/navigation_resource_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698