| 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 |