OLD | NEW |
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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 { | 59 { |
60 } | 60 } |
61 | 61 |
62 MessagePort::~MessagePort() | 62 MessagePort::~MessagePort() |
63 { | 63 { |
64 close(); | 64 close(); |
65 if (m_scriptStateForConversion) | 65 if (m_scriptStateForConversion) |
66 m_scriptStateForConversion->disposePerContextData(); | 66 m_scriptStateForConversion->disposePerContextData(); |
67 } | 67 } |
68 | 68 |
69 void MessagePort::postMessage(ExecutionContext* context, PassRefPtr<SerializedSc
riptValue> message, const MessagePortArray* ports, ExceptionState& exceptionStat
e) | 69 void MessagePort::postMessage(ExecutionContext* context, PassRefPtr<SerializedSc
riptValue> message, const MessagePortArray& ports, ExceptionState& exceptionStat
e) |
70 { | 70 { |
71 if (!isEntangled()) | 71 if (!isEntangled()) |
72 return; | 72 return; |
73 DCHECK(getExecutionContext()); | 73 DCHECK(getExecutionContext()); |
74 DCHECK(m_entangledChannel); | 74 DCHECK(m_entangledChannel); |
75 | 75 |
76 OwnPtr<MessagePortChannelArray> channels; | 76 OwnPtr<MessagePortChannelArray> channels; |
77 // Make sure we aren't connected to any of the passed-in ports. | 77 // Make sure we aren't connected to any of the passed-in ports. |
78 if (ports) { | 78 for (unsigned i = 0; i < ports.size(); ++i) { |
79 for (unsigned i = 0; i < ports->size(); ++i) { | 79 if (ports[i] == this) { |
80 MessagePort* dataPort = (*ports)[i]; | 80 exceptionState.throwDOMException(DataCloneError, "Port at index " +
String::number(i) + " contains the source port."); |
81 if (dataPort == this) { | 81 return; |
82 exceptionState.throwDOMException(DataCloneError, "Port at index
" + String::number(i) + " contains the source port."); | |
83 return; | |
84 } | |
85 } | 82 } |
86 channels = MessagePort::disentanglePorts(context, ports, exceptionState)
; | |
87 if (exceptionState.hadException()) | |
88 return; | |
89 } | 83 } |
| 84 channels = MessagePort::disentanglePorts(context, ports, exceptionState); |
| 85 if (exceptionState.hadException()) |
| 86 return; |
90 | 87 |
91 if (message->containsTransferableArrayBuffer()) | 88 if (message->containsTransferableArrayBuffer()) |
92 getExecutionContext()->addConsoleMessage(ConsoleMessage::create(JSMessag
eSource, WarningMessageLevel, "MessagePort cannot send an ArrayBuffer as a trans
ferable object yet. See http://crbug.com/334408")); | 89 getExecutionContext()->addConsoleMessage(ConsoleMessage::create(JSMessag
eSource, WarningMessageLevel, "MessagePort cannot send an ArrayBuffer as a trans
ferable object yet. See http://crbug.com/334408")); |
93 | 90 |
94 WebString messageString = message->toWireString(); | 91 WebString messageString = message->toWireString(); |
95 OwnPtr<WebMessagePortChannelArray> webChannels = toWebMessagePortChannelArra
y(channels.release()); | 92 OwnPtr<WebMessagePortChannelArray> webChannels = toWebMessagePortChannelArra
y(channels.release()); |
96 m_entangledChannel->postMessage(messageString, webChannels.leakPtr()); | 93 m_entangledChannel->postMessage(messageString, webChannels.leakPtr()); |
97 } | 94 } |
98 | 95 |
99 // static | 96 // static |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 } | 213 } |
217 } | 214 } |
218 | 215 |
219 bool MessagePort::hasPendingActivity() const | 216 bool MessagePort::hasPendingActivity() const |
220 { | 217 { |
221 // The spec says that entangled message ports should always be treated as if
they have a strong reference. | 218 // The spec says that entangled message ports should always be treated as if
they have a strong reference. |
222 // We'll also stipulate that the queue needs to be open (if the app drops it
s reference to the port before start()-ing it, then it's not really entangled as
it's unreachable). | 219 // We'll also stipulate that the queue needs to be open (if the app drops it
s reference to the port before start()-ing it, then it's not really entangled as
it's unreachable). |
223 return m_started && isEntangled(); | 220 return m_started && isEntangled(); |
224 } | 221 } |
225 | 222 |
226 PassOwnPtr<MessagePortChannelArray> MessagePort::disentanglePorts(ExecutionConte
xt* context, const MessagePortArray* ports, ExceptionState& exceptionState) | 223 PassOwnPtr<MessagePortChannelArray> MessagePort::disentanglePorts(ExecutionConte
xt* context, const MessagePortArray& ports, ExceptionState& exceptionState) |
227 { | 224 { |
228 if (!ports || !ports->size()) | 225 if (!ports.size()) |
229 return nullptr; | 226 return nullptr; |
230 | 227 |
231 // HeapHashSet used to efficiently check for duplicates in the passed-in arr
ay. | 228 HeapHashSet<Member<MessagePort>> visited; |
232 HeapHashSet<Member<MessagePort>> portSet; | |
233 | 229 |
234 // Walk the incoming array - if there are any duplicate ports, or null ports
or cloned ports, throw an error (per section 8.3.3 of the HTML5 spec). | 230 // Walk the incoming array - if there are any duplicate ports, or null ports
or cloned ports, throw an error (per section 8.3.3 of the HTML5 spec). |
235 for (unsigned i = 0; i < ports->size(); ++i) { | 231 for (unsigned i = 0; i < ports.size(); ++i) { |
236 MessagePort* port = (*ports)[i]; | 232 MessagePort* port = ports[i]; |
237 if (!port || port->isNeutered() || portSet.contains(port)) { | 233 if (!port || port->isNeutered() || visited.contains(port)) { |
238 String type; | 234 String type; |
239 if (!port) | 235 if (!port) |
240 type = "null"; | 236 type = "null"; |
241 else if (port->isNeutered()) | 237 else if (port->isNeutered()) |
242 type = "already neutered"; | 238 type = "already neutered"; |
243 else | 239 else |
244 type = "a duplicate"; | 240 type = "a duplicate"; |
245 exceptionState.throwDOMException(DataCloneError, "Port at index " +
String::number(i) + " is " + type + "."); | 241 exceptionState.throwDOMException(DataCloneError, "Port at index " +
String::number(i) + " is " + type + "."); |
246 return nullptr; | 242 return nullptr; |
247 } | 243 } |
248 portSet.add(port); | 244 visited.add(port); |
249 } | 245 } |
250 | 246 |
251 UseCounter::count(context, UseCounter::MessagePortsTransferred); | 247 UseCounter::count(context, UseCounter::MessagePortsTransferred); |
252 | 248 |
253 // Passed-in ports passed validity checks, so we can disentangle them. | 249 // Passed-in ports passed validity checks, so we can disentangle them. |
254 OwnPtr<MessagePortChannelArray> portArray = adoptPtr(new MessagePortChannelA
rray(ports->size())); | 250 OwnPtr<MessagePortChannelArray> portArray = adoptPtr(new MessagePortChannelA
rray(ports.size())); |
255 for (unsigned i = 0; i < ports->size(); ++i) | 251 for (unsigned i = 0; i < ports.size(); ++i) |
256 (*portArray)[i] = (*ports)[i]->disentangle(); | 252 (*portArray)[i] = ports[i]->disentangle(); |
257 return portArray.release(); | 253 return portArray.release(); |
258 } | 254 } |
259 | 255 |
260 MessagePortArray* MessagePort::entanglePorts(ExecutionContext& context, PassOwnP
tr<MessagePortChannelArray> channels) | 256 MessagePortArray* MessagePort::entanglePorts(ExecutionContext& context, PassOwnP
tr<MessagePortChannelArray> channels) |
261 { | 257 { |
262 // https://html.spec.whatwg.org/multipage/comms.html#message-ports | 258 // https://html.spec.whatwg.org/multipage/comms.html#message-ports |
263 // |ports| should be an empty array, not null even when there is no ports. | 259 // |ports| should be an empty array, not null even when there is no ports. |
264 if (!channels || !channels->size()) | 260 if (!channels || !channels->size()) |
265 return new MessagePortArray; | 261 return new MessagePortArray; |
266 | 262 |
(...skipping 22 matching lines...) Expand all Loading... |
289 { | 285 { |
290 DCHECK(getExecutionContext()); | 286 DCHECK(getExecutionContext()); |
291 if (!m_scriptStateForConversion) { | 287 if (!m_scriptStateForConversion) { |
292 v8::Isolate* isolate = scriptIsolate(); | 288 v8::Isolate* isolate = scriptIsolate(); |
293 m_scriptStateForConversion = ScriptState::create(v8::Context::New(isolat
e), DOMWrapperWorld::create(isolate)); | 289 m_scriptStateForConversion = ScriptState::create(v8::Context::New(isolat
e), DOMWrapperWorld::create(isolate)); |
294 } | 290 } |
295 return m_scriptStateForConversion->context(); | 291 return m_scriptStateForConversion->context(); |
296 } | 292 } |
297 | 293 |
298 } // namespace blink | 294 } // namespace blink |
OLD | NEW |