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

Side by Side Diff: third_party/WebKit/Source/core/dom/MessagePort.cpp

Issue 2422793002: HTML MessagePort as mojo::MessagePipeHandle (Closed)
Patch Set: Address feedback from yusuf Created 3 years, 10 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 68
69 // Make sure we aren't connected to any of the passed-in ports. 69 // Make sure we aren't connected to any of the passed-in ports.
70 for (unsigned i = 0; i < ports.size(); ++i) { 70 for (unsigned i = 0; i < ports.size(); ++i) {
71 if (ports[i] == this) { 71 if (ports[i] == this) {
72 exceptionState.throwDOMException( 72 exceptionState.throwDOMException(
73 DataCloneError, 73 DataCloneError,
74 "Port at index " + String::number(i) + " contains the source port."); 74 "Port at index " + String::number(i) + " contains the source port.");
75 return; 75 return;
76 } 76 }
77 } 77 }
78 std::unique_ptr<MessagePortChannelArray> channels = 78 MessagePortChannelArray channels =
79 MessagePort::disentanglePorts(context, ports, exceptionState); 79 MessagePort::disentanglePorts(context, ports, exceptionState);
80 if (exceptionState.hadException()) 80 if (exceptionState.hadException())
81 return; 81 return;
82 82
83 WebString messageString = message->toWireString(); 83 WebString messageString = message->toWireString();
84 std::unique_ptr<WebMessagePortChannelArray> webChannels = 84 WebMessagePortChannelArray webChannels =
85 toWebMessagePortChannelArray(std::move(channels)); 85 toWebMessagePortChannelArray(std::move(channels));
86 m_entangledChannel->postMessage(messageString, webChannels.release()); 86 m_entangledChannel->postMessage(messageString, std::move(webChannels));
87 } 87 }
88 88
89 // static 89 // static
90 std::unique_ptr<WebMessagePortChannelArray> 90 WebMessagePortChannelArray MessagePort::toWebMessagePortChannelArray(
91 MessagePort::toWebMessagePortChannelArray( 91 MessagePortChannelArray channels) {
92 std::unique_ptr<MessagePortChannelArray> channels) { 92 WebMessagePortChannelArray webChannels(channels.size());
93 std::unique_ptr<WebMessagePortChannelArray> webChannels; 93 for (size_t i = 0; i < channels.size(); ++i)
94 if (channels && channels->size()) { 94 webChannels[i] = std::move(channels[i]);
95 webChannels =
96 WTF::wrapUnique(new WebMessagePortChannelArray(channels->size()));
97 for (size_t i = 0; i < channels->size(); ++i)
98 (*webChannels)[i] = (*channels)[i].release();
99 }
100 return webChannels; 95 return webChannels;
101 } 96 }
102 97
103 // static 98 // static
104 MessagePortArray* MessagePort::toMessagePortArray( 99 MessagePortArray* MessagePort::toMessagePortArray(
105 ExecutionContext* context, 100 ExecutionContext* context,
106 const WebMessagePortChannelArray& webChannels) { 101 WebMessagePortChannelArray webChannels) {
107 std::unique_ptr<MessagePortChannelArray> channels = 102 MessagePortChannelArray channels(webChannels.size());
108 WTF::wrapUnique(new MessagePortChannelArray(webChannels.size()));
109 for (size_t i = 0; i < webChannels.size(); ++i) 103 for (size_t i = 0; i < webChannels.size(); ++i)
110 (*channels)[i] = WebMessagePortChannelUniquePtr(webChannels[i]); 104 channels[i] = std::move(webChannels[i]);
111 return MessagePort::entanglePorts(*context, std::move(channels)); 105 return MessagePort::entanglePorts(*context, std::move(channels));
112 } 106 }
113 107
114 WebMessagePortChannelUniquePtr MessagePort::disentangle() { 108 WebMessagePortChannelUniquePtr MessagePort::disentangle() {
115 DCHECK(m_entangledChannel); 109 DCHECK(m_entangledChannel);
116 m_entangledChannel->setClient(nullptr); 110 m_entangledChannel->setClient(nullptr);
117 return std::move(m_entangledChannel); 111 return std::move(m_entangledChannel);
118 } 112 }
119 113
120 // Invoked to notify us that there are messages available for this port. 114 // Invoked to notify us that there are messages available for this port.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 DCHECK(!m_entangledChannel); 150 DCHECK(!m_entangledChannel);
157 DCHECK(getExecutionContext()); 151 DCHECK(getExecutionContext());
158 152
159 m_entangledChannel = std::move(remote); 153 m_entangledChannel = std::move(remote);
160 } 154 }
161 155
162 const AtomicString& MessagePort::interfaceName() const { 156 const AtomicString& MessagePort::interfaceName() const {
163 return EventTargetNames::MessagePort; 157 return EventTargetNames::MessagePort;
164 } 158 }
165 159
166 static bool tryGetMessageFrom( 160 static bool tryGetMessageFrom(WebMessagePortChannel& webChannel,
167 WebMessagePortChannel& webChannel, 161 RefPtr<SerializedScriptValue>& message,
168 RefPtr<SerializedScriptValue>& message, 162 MessagePortChannelArray& channels) {
169 std::unique_ptr<MessagePortChannelArray>& channels) {
170 WebString messageString; 163 WebString messageString;
171 WebMessagePortChannelArray webChannels; 164 WebMessagePortChannelArray webChannels;
172 if (!webChannel.tryGetMessage(&messageString, webChannels)) 165 if (!webChannel.tryGetMessage(&messageString, webChannels))
173 return false; 166 return false;
174 167
175 if (webChannels.size()) { 168 if (webChannels.size()) {
176 channels = WTF::wrapUnique(new MessagePortChannelArray(webChannels.size())); 169 channels.resize(webChannels.size());
177 for (size_t i = 0; i < webChannels.size(); ++i) 170 for (size_t i = 0; i < webChannels.size(); ++i)
178 (*channels)[i] = WebMessagePortChannelUniquePtr(webChannels[i]); 171 channels[i] = std::move(webChannels[i]);
179 } 172 }
180 message = SerializedScriptValue::create(messageString); 173 message = SerializedScriptValue::create(messageString);
181 return true; 174 return true;
182 } 175 }
183 176
184 bool MessagePort::tryGetMessage( 177 bool MessagePort::tryGetMessage(RefPtr<SerializedScriptValue>& message,
185 RefPtr<SerializedScriptValue>& message, 178 MessagePortChannelArray& channels) {
186 std::unique_ptr<MessagePortChannelArray>& channels) {
187 if (!m_entangledChannel) 179 if (!m_entangledChannel)
188 return false; 180 return false;
189 return tryGetMessageFrom(*m_entangledChannel, message, channels); 181 return tryGetMessageFrom(*m_entangledChannel, message, channels);
190 } 182 }
191 183
192 void MessagePort::dispatchMessages() { 184 void MessagePort::dispatchMessages() {
193 // Messages for contexts that are not fully active get dispatched too, but 185 // Messages for contexts that are not fully active get dispatched too, but
194 // JSAbstractEventListener::handleEvent() doesn't call handlers for these. 186 // JSAbstractEventListener::handleEvent() doesn't call handlers for these.
195 // The HTML5 spec specifies that any messages sent to a document that is not 187 // The HTML5 spec specifies that any messages sent to a document that is not
196 // fully active should be dropped, so this behavior is OK. 188 // fully active should be dropped, so this behavior is OK.
197 if (!started()) 189 if (!started())
198 return; 190 return;
199 191
200 while (true) { 192 while (true) {
201 // Because close() doesn't cancel any in flight calls to dispatchMessages(), 193 // Because close() doesn't cancel any in flight calls to dispatchMessages(),
202 // and can be triggered by the onmessage event handler, we need to check if 194 // and can be triggered by the onmessage event handler, we need to check if
203 // the port is still open before each dispatch. 195 // the port is still open before each dispatch.
204 if (m_closed) 196 if (m_closed)
205 break; 197 break;
206 198
207 // WorkerGlobalScope::close() in Worker onmessage handler should prevent 199 // WorkerGlobalScope::close() in Worker onmessage handler should prevent
208 // the next message from dispatching. 200 // the next message from dispatching.
209 if (getExecutionContext()->isWorkerGlobalScope() && 201 if (getExecutionContext()->isWorkerGlobalScope() &&
210 toWorkerGlobalScope(getExecutionContext())->isClosing()) { 202 toWorkerGlobalScope(getExecutionContext())->isClosing()) {
211 break; 203 break;
212 } 204 }
213 205
214 RefPtr<SerializedScriptValue> message; 206 RefPtr<SerializedScriptValue> message;
215 std::unique_ptr<MessagePortChannelArray> channels; 207 MessagePortChannelArray channels;
216 if (!tryGetMessage(message, channels)) 208 if (!tryGetMessage(message, channels))
217 break; 209 break;
218 210
219 MessagePortArray* ports = 211 MessagePortArray* ports =
220 MessagePort::entanglePorts(*getExecutionContext(), std::move(channels)); 212 MessagePort::entanglePorts(*getExecutionContext(), std::move(channels));
221 Event* evt = MessageEvent::create(ports, std::move(message)); 213 Event* evt = MessageEvent::create(ports, std::move(message));
222 214
223 dispatchEvent(evt); 215 dispatchEvent(evt);
224 } 216 }
225 } 217 }
226 218
227 bool MessagePort::hasPendingActivity() const { 219 bool MessagePort::hasPendingActivity() const {
228 // The spec says that entangled message ports should always be treated as if 220 // The spec says that entangled message ports should always be treated as if
229 // they have a strong reference. 221 // they have a strong reference.
230 // We'll also stipulate that the queue needs to be open (if the app drops its 222 // We'll also stipulate that the queue needs to be open (if the app drops its
231 // reference to the port before start()-ing it, then it's not really entangled 223 // reference to the port before start()-ing it, then it's not really entangled
232 // as it's unreachable). 224 // as it's unreachable).
233 return m_started && isEntangled(); 225 return m_started && isEntangled();
234 } 226 }
235 227
236 std::unique_ptr<MessagePortChannelArray> MessagePort::disentanglePorts( 228 MessagePortChannelArray MessagePort::disentanglePorts(
237 ExecutionContext* context, 229 ExecutionContext* context,
238 const MessagePortArray& ports, 230 const MessagePortArray& ports,
239 ExceptionState& exceptionState) { 231 ExceptionState& exceptionState) {
240 if (!ports.size()) 232 if (!ports.size())
241 return nullptr; 233 return MessagePortChannelArray();
242 234
243 HeapHashSet<Member<MessagePort>> visited; 235 HeapHashSet<Member<MessagePort>> visited;
244 236
245 // Walk the incoming array - if there are any duplicate ports, or null ports 237 // Walk the incoming array - if there are any duplicate ports, or null ports
246 // or cloned ports, throw an error (per section 8.3.3 of the HTML5 spec). 238 // or cloned ports, throw an error (per section 8.3.3 of the HTML5 spec).
247 for (unsigned i = 0; i < ports.size(); ++i) { 239 for (unsigned i = 0; i < ports.size(); ++i) {
248 MessagePort* port = ports[i]; 240 MessagePort* port = ports[i];
249 if (!port || port->isNeutered() || visited.contains(port)) { 241 if (!port || port->isNeutered() || visited.contains(port)) {
250 String type; 242 String type;
251 if (!port) 243 if (!port)
252 type = "null"; 244 type = "null";
253 else if (port->isNeutered()) 245 else if (port->isNeutered())
254 type = "already neutered"; 246 type = "already neutered";
255 else 247 else
256 type = "a duplicate"; 248 type = "a duplicate";
257 exceptionState.throwDOMException( 249 exceptionState.throwDOMException(
258 DataCloneError, 250 DataCloneError,
259 "Port at index " + String::number(i) + " is " + type + "."); 251 "Port at index " + String::number(i) + " is " + type + ".");
260 return nullptr; 252 return MessagePortChannelArray();
261 } 253 }
262 visited.insert(port); 254 visited.insert(port);
263 } 255 }
264 256
265 UseCounter::count(context, UseCounter::MessagePortsTransferred); 257 UseCounter::count(context, UseCounter::MessagePortsTransferred);
266 258
267 // Passed-in ports passed validity checks, so we can disentangle them. 259 // Passed-in ports passed validity checks, so we can disentangle them.
268 std::unique_ptr<MessagePortChannelArray> portArray = 260 MessagePortChannelArray portArray(ports.size());
269 WTF::wrapUnique(new MessagePortChannelArray(ports.size()));
270 for (unsigned i = 0; i < ports.size(); ++i) 261 for (unsigned i = 0; i < ports.size(); ++i)
271 (*portArray)[i] = ports[i]->disentangle(); 262 portArray[i] = ports[i]->disentangle();
272 return portArray; 263 return portArray;
273 } 264 }
274 265
275 MessagePortArray* MessagePort::entanglePorts( 266 MessagePortArray* MessagePort::entanglePorts(ExecutionContext& context,
276 ExecutionContext& context, 267 MessagePortChannelArray channels) {
277 std::unique_ptr<MessagePortChannelArray> channels) {
278 // https://html.spec.whatwg.org/multipage/comms.html#message-ports 268 // https://html.spec.whatwg.org/multipage/comms.html#message-ports
279 // |ports| should be an empty array, not null even when there is no ports. 269 // |ports| should be an empty array, not null even when there is no ports.
280 if (!channels || !channels->size()) 270 MessagePortArray* portArray = new MessagePortArray(channels.size());
281 return new MessagePortArray; 271 for (unsigned i = 0; i < channels.size(); ++i) {
282
283 MessagePortArray* portArray = new MessagePortArray(channels->size());
284 for (unsigned i = 0; i < channels->size(); ++i) {
285 MessagePort* port = MessagePort::create(context); 272 MessagePort* port = MessagePort::create(context);
286 port->entangle(std::move((*channels)[i])); 273 port->entangle(std::move(channels[i]));
287 (*portArray)[i] = port; 274 (*portArray)[i] = port;
288 } 275 }
289 return portArray; 276 return portArray;
290 } 277 }
291 278
292 DEFINE_TRACE(MessagePort) { 279 DEFINE_TRACE(MessagePort) {
293 ContextLifecycleObserver::trace(visitor); 280 ContextLifecycleObserver::trace(visitor);
294 EventTargetWithInlineData::trace(visitor); 281 EventTargetWithInlineData::trace(visitor);
295 } 282 }
296 283
297 } // namespace blink 284 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698