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

Unified Diff: content/common/message_port.cc

Issue 2755223002: Enable Blink to pass extra Mojo handles across MessagePorts
Patch Set: Finish plumbing 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
« no previous file with comments | « content/common/message_port.h ('k') | third_party/WebKit/Source/core/dom/MessagePort.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/common/message_port.cc
diff --git a/content/common/message_port.cc b/content/common/message_port.cc
index a57236a7b28759d5ab7d1b0d963e74817327b64f..1d6dda4aaca6fcce1a6875b665c377ac29733e86 100644
--- a/content/common/message_port.cc
+++ b/content/common/message_port.cc
@@ -47,37 +47,46 @@ std::vector<mojo::ScopedMessagePipeHandle> MessagePort::ReleaseHandles(
}
void MessagePort::PostMessage(const base::string16& encoded_message,
- std::vector<MessagePort> ports) {
+ std::vector<MessagePort> ports,
+ std::vector<mojo::ScopedHandle> extra_handles) {
DCHECK(state_->handle_.is_valid());
- uint32_t num_bytes = encoded_message.size() * sizeof(base::char16);
+ uint32_t num_message_bytes = encoded_message.size() * sizeof(base::char16);
// NOTE: It is OK to ignore the return value of MojoWriteMessage here. HTML
// MessagePorts have no way of reporting when the peer is gone.
- if (ports.empty()) {
- MojoWriteMessage(state_->handle_.get().value(),
- encoded_message.data(),
- num_bytes,
- nullptr,
- 0,
+ // When we have handles to pass, we add a 4-byte prefix to the encoded
+ // message to indicate how many of the handles correspond to ports.
+
+ if (ports.empty() && extra_handles.empty()) {
+ MojoWriteMessage(state_->handle_.get().value(), encoded_message.data(),
+ num_message_bytes, nullptr, 0,
MOJO_WRITE_MESSAGE_FLAG_NONE);
} else {
- uint32_t num_handles = static_cast<uint32_t>(ports.size());
+ uint32_t num_ports = static_cast<uint32_t>(ports.size());
+ uint32_t num_extra_handles = static_cast<uint32_t>(extra_handles.size());
+ uint32_t num_handles = num_ports + num_extra_handles;
+ uint32_t num_bytes = num_message_bytes + sizeof(num_ports);
+
+ std::unique_ptr<uint8_t> bytes(new uint8_t[num_bytes]);
+ memcpy(bytes.get(), &num_ports, sizeof(num_ports));
+ memcpy(bytes.get() + num_ports, encoded_message.data(), num_message_bytes);
+
std::unique_ptr<MojoHandle[]> handles(new MojoHandle[num_handles]);
- for (uint32_t i = 0; i < num_handles; ++i)
+ for (uint32_t i = 0; i < num_ports; ++i)
handles[i] = ports[i].ReleaseHandle().release().value();
- MojoWriteMessage(state_->handle_.get().value(),
- encoded_message.data(),
- num_bytes,
- handles.get(),
- num_handles,
- MOJO_WRITE_MESSAGE_FLAG_NONE);
+ for (uint32_t i = 0; i < num_extra_handles; ++i)
+ handles[num_ports + i] = extra_handles[i].release().value();
+
+ MojoWriteMessage(state_->handle_.get().value(), bytes.get(), num_bytes,
+ handles.get(), num_handles, MOJO_WRITE_MESSAGE_FLAG_NONE);
}
}
bool MessagePort::GetMessage(base::string16* encoded_message,
- std::vector<MessagePort>* ports) {
+ std::vector<MessagePort>* ports,
+ std::vector<mojo::ScopedHandle>* extra_handles) {
DCHECK(state_->handle_.is_valid());
uint32_t num_bytes = 0;
@@ -92,6 +101,7 @@ bool MessagePort::GetMessage(base::string16* encoded_message,
if (rv == MOJO_RESULT_OK) {
encoded_message->clear();
ports->clear();
+ extra_handles->clear();
return true;
}
if (rv != MOJO_RESULT_RESOURCE_EXHAUSTED)
@@ -115,14 +125,33 @@ bool MessagePort::GetMessage(base::string16* encoded_message,
if (rv != MOJO_RESULT_OK)
return false;
- buffer.swap(*encoded_message);
+ // When we have received handles, the message contains a 4-byte prefix
+ // indicating how many of the handles correspond to ports.
if (num_handles) {
- ports->resize(static_cast<size_t>(num_handles));
- for (uint32_t i = 0; i < num_handles; ++i) {
+ uint32_t num_ports;
+ memcpy(&num_ports, buffer.data(), sizeof(num_ports));
+ *encoded_message = buffer.substr(sizeof(num_ports) / sizeof(base::char16));
+
+ CHECK(num_ports <= num_handles);
+
+ uint32_t num_extra_handles = num_handles - num_ports;
+
+ ports->resize(static_cast<size_t>(num_ports));
+ extra_handles->resize(static_cast<size_t>(num_extra_handles));
+
+ for (uint32_t i = 0; i < num_ports; ++i) {
ports->at(i) = MessagePort(
mojo::ScopedMessagePipeHandle(mojo::MessagePipeHandle(handles[i])));
}
+ for (uint32_t i = 0; i < num_extra_handles; ++i) {
+ extra_handles->at(i) =
+ mojo::ScopedHandle(mojo::Handle(handles[num_ports + i]));
+ }
+ } else {
+ buffer.swap(*encoded_message);
+ ports->clear();
+ extra_handles->clear();
}
return true;
}
« no previous file with comments | « content/common/message_port.h ('k') | third_party/WebKit/Source/core/dom/MessagePort.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698