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

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

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

Powered by Google App Engine
This is Rietveld 408576698