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

Side by Side 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« 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