| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/common/message_port.h" | 5 #include "content/common/message_port.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/threading/thread_task_runner_handle.h" | 9 #include "base/threading/thread_task_runner_handle.h" |
| 10 | 10 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 // static | 40 // static |
| 41 std::vector<mojo::ScopedMessagePipeHandle> MessagePort::ReleaseHandles( | 41 std::vector<mojo::ScopedMessagePipeHandle> MessagePort::ReleaseHandles( |
| 42 const std::vector<MessagePort>& ports) { | 42 const std::vector<MessagePort>& ports) { |
| 43 std::vector<mojo::ScopedMessagePipeHandle> handles(ports.size()); | 43 std::vector<mojo::ScopedMessagePipeHandle> handles(ports.size()); |
| 44 for (size_t i = 0; i < ports.size(); ++i) | 44 for (size_t i = 0; i < ports.size(); ++i) |
| 45 handles[i] = ports[i].ReleaseHandle(); | 45 handles[i] = ports[i].ReleaseHandle(); |
| 46 return handles; | 46 return handles; |
| 47 } | 47 } |
| 48 | 48 |
| 49 void MessagePort::PostMessage(const base::string16& encoded_message, | 49 void MessagePort::PostMessage(const base::string16& encoded_message, |
| 50 std::vector<MessagePort> ports) { | 50 std::vector<MessagePort> ports, |
| 51 std::vector<mojo::ScopedHandle> extra_handles) { |
| 51 DCHECK(state_->handle_.is_valid()); | 52 DCHECK(state_->handle_.is_valid()); |
| 52 | 53 |
| 53 uint32_t num_bytes = encoded_message.size() * sizeof(base::char16); | 54 uint32_t num_message_bytes = encoded_message.size() * sizeof(base::char16); |
| 54 | 55 |
| 55 // NOTE: It is OK to ignore the return value of MojoWriteMessage here. HTML | 56 // NOTE: It is OK to ignore the return value of MojoWriteMessage here. HTML |
| 56 // MessagePorts have no way of reporting when the peer is gone. | 57 // MessagePorts have no way of reporting when the peer is gone. |
| 57 | 58 |
| 58 if (ports.empty()) { | 59 // When we have handles to pass, we add a 4-byte prefix to the encoded |
| 59 MojoWriteMessage(state_->handle_.get().value(), | 60 // message to indicate how many of the handles correspond to ports. |
| 60 encoded_message.data(), | 61 |
| 61 num_bytes, | 62 if (ports.empty() && extra_handles.empty()) { |
| 62 nullptr, | 63 MojoWriteMessage(state_->handle_.get().value(), encoded_message.data(), |
| 63 0, | 64 num_message_bytes, nullptr, 0, |
| 64 MOJO_WRITE_MESSAGE_FLAG_NONE); | 65 MOJO_WRITE_MESSAGE_FLAG_NONE); |
| 65 } else { | 66 } else { |
| 66 uint32_t num_handles = static_cast<uint32_t>(ports.size()); | 67 uint32_t num_ports = static_cast<uint32_t>(ports.size()); |
| 68 uint32_t num_extra_handles = static_cast<uint32_t>(extra_handles.size()); |
| 69 uint32_t num_handles = num_ports + num_extra_handles; |
| 70 uint32_t num_bytes = num_message_bytes + sizeof(num_ports); |
| 71 |
| 72 std::unique_ptr<uint8_t> bytes(new uint8_t[num_bytes]); |
| 73 memcpy(bytes.get(), &num_ports, sizeof(num_ports)); |
| 74 memcpy(bytes.get() + num_ports, encoded_message.data(), num_message_bytes); |
| 75 |
| 67 std::unique_ptr<MojoHandle[]> handles(new MojoHandle[num_handles]); | 76 std::unique_ptr<MojoHandle[]> handles(new MojoHandle[num_handles]); |
| 68 for (uint32_t i = 0; i < num_handles; ++i) | 77 for (uint32_t i = 0; i < num_ports; ++i) |
| 69 handles[i] = ports[i].ReleaseHandle().release().value(); | 78 handles[i] = ports[i].ReleaseHandle().release().value(); |
| 70 MojoWriteMessage(state_->handle_.get().value(), | 79 for (uint32_t i = 0; i < num_extra_handles; ++i) |
| 71 encoded_message.data(), | 80 handles[num_ports + i] = extra_handles[i].release().value(); |
| 72 num_bytes, | 81 |
| 73 handles.get(), | 82 MojoWriteMessage(state_->handle_.get().value(), bytes.get(), num_bytes, |
| 74 num_handles, | 83 handles.get(), num_handles, MOJO_WRITE_MESSAGE_FLAG_NONE); |
| 75 MOJO_WRITE_MESSAGE_FLAG_NONE); | |
| 76 } | 84 } |
| 77 } | 85 } |
| 78 | 86 |
| 79 bool MessagePort::GetMessage(base::string16* encoded_message, | 87 bool MessagePort::GetMessage(base::string16* encoded_message, |
| 80 std::vector<MessagePort>* ports) { | 88 std::vector<MessagePort>* ports, |
| 89 std::vector<mojo::ScopedHandle>* extra_handles) { |
| 81 DCHECK(state_->handle_.is_valid()); | 90 DCHECK(state_->handle_.is_valid()); |
| 82 | 91 |
| 83 uint32_t num_bytes = 0; | 92 uint32_t num_bytes = 0; |
| 84 uint32_t num_handles = 0; | 93 uint32_t num_handles = 0; |
| 85 | 94 |
| 86 MojoResult rv = MojoReadMessage(state_->handle_.get().value(), | 95 MojoResult rv = MojoReadMessage(state_->handle_.get().value(), |
| 87 nullptr, | 96 nullptr, |
| 88 &num_bytes, | 97 &num_bytes, |
| 89 nullptr, | 98 nullptr, |
| 90 &num_handles, | 99 &num_handles, |
| 91 MOJO_READ_MESSAGE_FLAG_NONE); | 100 MOJO_READ_MESSAGE_FLAG_NONE); |
| 92 if (rv == MOJO_RESULT_OK) { | 101 if (rv == MOJO_RESULT_OK) { |
| 93 encoded_message->clear(); | 102 encoded_message->clear(); |
| 94 ports->clear(); | 103 ports->clear(); |
| 104 extra_handles->clear(); |
| 95 return true; | 105 return true; |
| 96 } | 106 } |
| 97 if (rv != MOJO_RESULT_RESOURCE_EXHAUSTED) | 107 if (rv != MOJO_RESULT_RESOURCE_EXHAUSTED) |
| 98 return false; | 108 return false; |
| 99 | 109 |
| 100 CHECK(num_bytes % 2 == 0); | 110 CHECK(num_bytes % 2 == 0); |
| 101 | 111 |
| 102 base::string16 buffer; | 112 base::string16 buffer; |
| 103 buffer.resize(num_bytes / sizeof(base::char16)); | 113 buffer.resize(num_bytes / sizeof(base::char16)); |
| 104 | 114 |
| 105 std::unique_ptr<MojoHandle[]> handles; | 115 std::unique_ptr<MojoHandle[]> handles; |
| 106 if (num_handles) | 116 if (num_handles) |
| 107 handles.reset(new MojoHandle[num_handles]); | 117 handles.reset(new MojoHandle[num_handles]); |
| 108 | 118 |
| 109 rv = MojoReadMessage(state_->handle_.get().value(), | 119 rv = MojoReadMessage(state_->handle_.get().value(), |
| 110 num_bytes ? &buffer[0] : nullptr, | 120 num_bytes ? &buffer[0] : nullptr, |
| 111 &num_bytes, | 121 &num_bytes, |
| 112 handles.get(), | 122 handles.get(), |
| 113 &num_handles, | 123 &num_handles, |
| 114 MOJO_READ_MESSAGE_FLAG_NONE); | 124 MOJO_READ_MESSAGE_FLAG_NONE); |
| 115 if (rv != MOJO_RESULT_OK) | 125 if (rv != MOJO_RESULT_OK) |
| 116 return false; | 126 return false; |
| 117 | 127 |
| 118 buffer.swap(*encoded_message); | 128 // When we have received handles, the message contains a 4-byte prefix |
| 129 // indicating how many of the handles correspond to ports. |
| 119 | 130 |
| 120 if (num_handles) { | 131 if (num_handles) { |
| 121 ports->resize(static_cast<size_t>(num_handles)); | 132 uint32_t num_ports; |
| 122 for (uint32_t i = 0; i < num_handles; ++i) { | 133 memcpy(&num_ports, buffer.data(), sizeof(num_ports)); |
| 134 *encoded_message = buffer.substr(sizeof(num_ports) / sizeof(base::char16)); |
| 135 |
| 136 CHECK(num_ports <= num_handles); |
| 137 |
| 138 uint32_t num_extra_handles = num_handles - num_ports; |
| 139 |
| 140 ports->resize(static_cast<size_t>(num_ports)); |
| 141 extra_handles->resize(static_cast<size_t>(num_extra_handles)); |
| 142 |
| 143 for (uint32_t i = 0; i < num_ports; ++i) { |
| 123 ports->at(i) = MessagePort( | 144 ports->at(i) = MessagePort( |
| 124 mojo::ScopedMessagePipeHandle(mojo::MessagePipeHandle(handles[i]))); | 145 mojo::ScopedMessagePipeHandle(mojo::MessagePipeHandle(handles[i]))); |
| 125 } | 146 } |
| 147 for (uint32_t i = 0; i < num_extra_handles; ++i) { |
| 148 extra_handles->at(i) = |
| 149 mojo::ScopedHandle(mojo::Handle(handles[num_ports + i])); |
| 150 } |
| 151 } else { |
| 152 buffer.swap(*encoded_message); |
| 153 ports->clear(); |
| 154 extra_handles->clear(); |
| 126 } | 155 } |
| 127 return true; | 156 return true; |
| 128 } | 157 } |
| 129 | 158 |
| 130 void MessagePort::SetCallback(const base::Closure& callback) { | 159 void MessagePort::SetCallback(const base::Closure& callback) { |
| 131 state_->CancelWatch(); | 160 state_->CancelWatch(); |
| 132 state_->callback_ = callback; | 161 state_->callback_ = callback; |
| 133 state_->AddWatch(); | 162 state_->AddWatch(); |
| 134 } | 163 } |
| 135 | 164 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 if (result == MOJO_RESULT_CANCELLED) { | 253 if (result == MOJO_RESULT_CANCELLED) { |
| 225 // Last notification. Release the watch context's owned State ref. This is | 254 // Last notification. Release the watch context's owned State ref. This is |
| 226 // balanced in MessagePort::State::AddWatch. | 255 // balanced in MessagePort::State::AddWatch. |
| 227 state->Release(); | 256 state->Release(); |
| 228 } else { | 257 } else { |
| 229 state->OnHandleReady(result); | 258 state->OnHandleReady(result); |
| 230 } | 259 } |
| 231 } | 260 } |
| 232 | 261 |
| 233 } // namespace content | 262 } // namespace content |
| OLD | NEW |