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

Unified Diff: blimp/engine/renderer/blob_channel_sender_proxy.cc

Issue 2033013003: Use shared memory for moving data over BlobChannel Mojo interface. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@blobchannel-master
Patch Set: Added new test runner with Mojo initialization Created 4 years, 6 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: blimp/engine/renderer/blob_channel_sender_proxy.cc
diff --git a/blimp/engine/renderer/blob_channel_sender_proxy.cc b/blimp/engine/renderer/blob_channel_sender_proxy.cc
index 8b689d36c73dd840878105bb72a926845ebe97be..08ec8f3f0f1c71f4303d1e0da9252e4ccd7f5587 100644
--- a/blimp/engine/renderer/blob_channel_sender_proxy.cc
+++ b/blimp/engine/renderer/blob_channel_sender_proxy.cc
@@ -4,6 +4,7 @@
#include "blimp/engine/renderer/blob_channel_sender_proxy.h"
+#include "blimp/common/blob_cache/id_util.h"
#include "content/public/common/service_registry.h"
#include "content/public/renderer/render_thread.h"
@@ -19,30 +20,109 @@ mojom::BlobChannelPtr GetConnectedBlobChannel() {
return blob_channel_ptr;
}
+// Manages the creation and lifetime of Mojo shared memory buffers for blobs.
+// Cleans up the shared memory state when deleted.
+// Caller is responsible for ensuring that |this| is not deleted until the
Wez 2016/06/11 00:16:38 From the caller's PoV, |this| is itself - I think
Kevin M 2016/06/16 21:00:38 Done.
+// remote side has acknowledged that it is finished using the buffer.
+class SharedMemoryBlob {
+ public:
+ explicit SharedMemoryBlob(BlobDataPtr data) {
Wez 2016/06/11 00:16:38 As per style-guide, don't inline methods unless th
Kevin M 2016/06/16 21:00:38 Done.
+ mojo::ScopedSharedBufferHandle local_handle;
+ MojoResult result =
+ mojo::CreateSharedBuffer(NULL, data->data.size(), &local_handle);
Wez 2016/06/11 00:16:38 nit: nullptr
Kevin M 2016/06/16 21:00:39 Done.
+ CHECK_EQ(MOJO_RESULT_OK, result)
+ << "Mojo error when creating shared buffer: " << result;
Wez 2016/06/11 00:16:38 CHECK_EQ will already log |result| (and the expect
Kevin M 2016/06/16 21:00:39 Done.
+
+ result = mojo::MapBuffer(local_handle.get(), 0, data->data.size(),
+ &mapped_data_, MOJO_MAP_BUFFER_FLAG_NONE);
+ CHECK_EQ(MOJO_RESULT_OK, result)
+ << "Mojo error when memory mapping shared buffer: " << result;
+ memcpy(mapped_data_, data->data.data(), data->data.size());
+
+ // Create read-only handle for browser-side consumption.
Wez 2016/06/11 00:16:37 Why not do this on-the-fly in take_remote_handle()
Kevin M 2016/06/16 21:00:38 Uh, why not, indeed! Done.
+ MojoDuplicateBufferHandleOptions options{
+ sizeof(MojoDuplicateBufferHandleOptions),
+ MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_READ_ONLY};
+ result =
+ mojo::DuplicateBuffer(local_handle.get(), &options, &remote_handle_);
+ CHECK_EQ(MOJO_RESULT_OK, result)
+ << "Mojo error when creating read-only buffer handle.";
+ DCHECK(remote_handle_.is_valid());
+ }
+
+ ~SharedMemoryBlob() {
+ MojoResult result = mojo::UnmapBuffer(mapped_data_);
+ CHECK_EQ(MOJO_RESULT_OK, result);
Wez 2016/06/11 00:16:37 Looks like you can move the un-mapping into the ct
Kevin M 2016/06/16 21:00:39 Done.
+ }
+
+ mojo::ScopedSharedBufferHandle take_remote_handle() {
+ return std::move(remote_handle_);
+ }
+
+ private:
+ // Pointer to shared memory buffer.
+ void* mapped_data_;
Wez 2016/06/11 00:16:37 Why do we store this? It doesn't look like anythin
Kevin M 2016/06/16 21:00:38 Done.
+
+ // Handle to be passed to the remote end of the BlobChannel Mojo service.
+ mojo::ScopedSharedBufferHandle remote_handle_;
+
+ DISALLOW_COPY_AND_ASSIGN(SharedMemoryBlob);
+};
+
+void PutComplete(std::unique_ptr<SharedMemoryBlob>) {
+ // Allow the blob to go out of scope and be deleted.
+}
+
} // namespace
BlobChannelSenderProxy::BlobChannelSenderProxy()
- : blob_channel_(GetConnectedBlobChannel()) {}
+ : BlobChannelSenderProxy(GetConnectedBlobChannel()) {}
BlobChannelSenderProxy::~BlobChannelSenderProxy() {}
+BlobChannelSenderProxy::BlobChannelSenderProxy(
+ mojom::BlobChannelPtr blob_channel)
+ : blob_channel_(std::move(blob_channel)) {}
+
bool BlobChannelSenderProxy::IsInEngineCache(const std::string& id) const {
return replication_state_.find(id) != replication_state_.end();
}
bool BlobChannelSenderProxy::IsInClientCache(const std::string& id) const {
- return replication_state_.find(id)->second;
+ auto found = replication_state_.find(id);
+ return found != replication_state_.end() && found->second;
}
void BlobChannelSenderProxy::PutBlob(const BlobId& id, BlobDataPtr data) {
- DCHECK(!IsInEngineCache(id));
+ if (IsInEngineCache(id)) {
+ DLOG(ERROR) << "Redundant blob put attempted: " << BlobIdToString(id);
Wez 2016/06/11 00:16:38 nit: If this is a coding error, consider DLOG(FATA
Kevin M 2016/06/16 21:00:38 Done.
+ return;
+ }
+
+ size_t size = data->data.size();
+ if (size == 0) {
+ DLOG(FATAL) << "Zero length blob requested: " << BlobIdToString(id);
Wez 2016/06/11 00:16:38 nit: This is PutBlob - surely the zero-length blob
Kevin M 2016/06/16 21:00:38 Done.
+ return;
+ }
replication_state_[id] = false;
- blob_channel_->PutBlob(id, data->data);
+ std::unique_ptr<SharedMemoryBlob> shared_mem_blob(
+ new SharedMemoryBlob(std::move(data)));
+ blob_channel_->PutBlob(
+ id, shared_mem_blob->take_remote_handle(), size,
+ base::Bind(&PutComplete, base::Passed(std::move(shared_mem_blob))));
}
void BlobChannelSenderProxy::DeliverBlob(const std::string& id) {
- DCHECK(!IsInClientCache(id));
+ if (!IsInEngineCache(id)) {
+ DLOG(ERROR) << "Attempted to deliver an invalid blob: "
+ << BlobIdToString(id);
Wez 2016/06/11 00:16:38 This seems like a serious coding error - caller ha
Kevin M 2016/06/16 21:00:39 Done.
+ return;
+ }
+ if (IsInClientCache(id)) {
+ DLOG(ERROR) << "Blob is already in the remote cache:" << BlobIdToString(id);
Wez 2016/06/11 00:16:37 nit: As noted above, is it worth having this be an
Kevin M 2016/06/16 21:00:38 Done.
+ return;
+ }
// We assume that the client will have the blob if we push it.
// TODO(kmarshall): Revisit this assumption when asynchronous blob transport

Powered by Google App Engine
This is Rietveld 408576698