| 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;
|
| }
|
|
|