| 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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 return MessagePort::entanglePorts(*context, std::move(channels)); | 122 return MessagePort::entanglePorts(*context, std::move(channels)); |
| 123 } | 123 } |
| 124 | 124 |
| 125 WebMessagePortChannelUniquePtr MessagePort::disentangle() { | 125 WebMessagePortChannelUniquePtr MessagePort::disentangle() { |
| 126 DCHECK(m_entangledChannel); | 126 DCHECK(m_entangledChannel); |
| 127 m_entangledChannel->setClient(nullptr); | 127 m_entangledChannel->setClient(nullptr); |
| 128 return std::move(m_entangledChannel); | 128 return std::move(m_entangledChannel); |
| 129 } | 129 } |
| 130 | 130 |
| 131 // Invoked to notify us that there are messages available for this port. | 131 // Invoked to notify us that there are messages available for this port. |
| 132 // This code may be called from another thread, and so should not call any non-t
hreadsafe APIs (i.e. should not call into the entangled channel or access mutabl
e variables). | 132 // This code may be called from another thread, and so should not call any |
| 133 // non-threadsafe APIs (i.e. should not call into the entangled channel or |
| 134 // access mutable variables). |
| 133 void MessagePort::messageAvailable() { | 135 void MessagePort::messageAvailable() { |
| 134 DCHECK(getExecutionContext()); | 136 DCHECK(getExecutionContext()); |
| 135 getExecutionContext()->postTask( | 137 getExecutionContext()->postTask( |
| 136 BLINK_FROM_HERE, | 138 BLINK_FROM_HERE, |
| 137 createCrossThreadTask(&MessagePort::dispatchMessages, | 139 createCrossThreadTask(&MessagePort::dispatchMessages, |
| 138 wrapCrossThreadWeakPersistent(this))); | 140 wrapCrossThreadWeakPersistent(this))); |
| 139 } | 141 } |
| 140 | 142 |
| 141 void MessagePort::start() { | 143 void MessagePort::start() { |
| 142 // Do nothing if we've been cloned or closed. | 144 // Do nothing if we've been cloned or closed. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 | 192 |
| 191 bool MessagePort::tryGetMessage( | 193 bool MessagePort::tryGetMessage( |
| 192 RefPtr<SerializedScriptValue>& message, | 194 RefPtr<SerializedScriptValue>& message, |
| 193 std::unique_ptr<MessagePortChannelArray>& channels) { | 195 std::unique_ptr<MessagePortChannelArray>& channels) { |
| 194 if (!m_entangledChannel) | 196 if (!m_entangledChannel) |
| 195 return false; | 197 return false; |
| 196 return tryGetMessageFrom(*m_entangledChannel, message, channels); | 198 return tryGetMessageFrom(*m_entangledChannel, message, channels); |
| 197 } | 199 } |
| 198 | 200 |
| 199 void MessagePort::dispatchMessages() { | 201 void MessagePort::dispatchMessages() { |
| 200 // Because close() doesn't cancel any in flight calls to dispatchMessages() we
need to check if the port is still open before dispatch. | 202 // Because close() doesn't cancel any in flight calls to dispatchMessages() we |
| 203 // need to check if the port is still open before dispatch. |
| 201 if (m_closed) | 204 if (m_closed) |
| 202 return; | 205 return; |
| 203 | 206 |
| 204 // Messages for contexts that are not fully active get dispatched too, but JSA
bstractEventListener::handleEvent() doesn't call handlers for these. | 207 // Messages for contexts that are not fully active get dispatched too, but |
| 205 // The HTML5 spec specifies that any messages sent to a document that is not f
ully active should be dropped, so this behavior is OK. | 208 // JSAbstractEventListener::handleEvent() doesn't call handlers for these. |
| 209 // The HTML5 spec specifies that any messages sent to a document that is not |
| 210 // fully active should be dropped, so this behavior is OK. |
| 206 if (!started()) | 211 if (!started()) |
| 207 return; | 212 return; |
| 208 | 213 |
| 209 RefPtr<SerializedScriptValue> message; | 214 RefPtr<SerializedScriptValue> message; |
| 210 std::unique_ptr<MessagePortChannelArray> channels; | 215 std::unique_ptr<MessagePortChannelArray> channels; |
| 211 while (tryGetMessage(message, channels)) { | 216 while (tryGetMessage(message, channels)) { |
| 212 // close() in Worker onmessage handler should prevent next message from disp
atching. | 217 // close() in Worker onmessage handler should prevent next message from |
| 218 // dispatching. |
| 213 if (getExecutionContext()->isWorkerGlobalScope() && | 219 if (getExecutionContext()->isWorkerGlobalScope() && |
| 214 toWorkerGlobalScope(getExecutionContext())->isClosing()) | 220 toWorkerGlobalScope(getExecutionContext())->isClosing()) |
| 215 return; | 221 return; |
| 216 | 222 |
| 217 MessagePortArray* ports = | 223 MessagePortArray* ports = |
| 218 MessagePort::entanglePorts(*getExecutionContext(), std::move(channels)); | 224 MessagePort::entanglePorts(*getExecutionContext(), std::move(channels)); |
| 219 Event* evt = MessageEvent::create(ports, message.release()); | 225 Event* evt = MessageEvent::create(ports, message.release()); |
| 220 | 226 |
| 221 dispatchEvent(evt); | 227 dispatchEvent(evt); |
| 222 } | 228 } |
| 223 } | 229 } |
| 224 | 230 |
| 225 bool MessagePort::hasPendingActivity() const { | 231 bool MessagePort::hasPendingActivity() const { |
| 226 // The spec says that entangled message ports should always be treated as if t
hey have a strong reference. | 232 // The spec says that entangled message ports should always be treated as if |
| 227 // We'll also stipulate that the queue needs to be open (if the app drops its
reference to the port before start()-ing it, then it's not really entangled as i
t's unreachable). | 233 // they have a strong reference. |
| 234 // We'll also stipulate that the queue needs to be open (if the app drops its |
| 235 // reference to the port before start()-ing it, then it's not really entangled |
| 236 // as it's unreachable). |
| 228 return m_started && isEntangled(); | 237 return m_started && isEntangled(); |
| 229 } | 238 } |
| 230 | 239 |
| 231 std::unique_ptr<MessagePortChannelArray> MessagePort::disentanglePorts( | 240 std::unique_ptr<MessagePortChannelArray> MessagePort::disentanglePorts( |
| 232 ExecutionContext* context, | 241 ExecutionContext* context, |
| 233 const MessagePortArray& ports, | 242 const MessagePortArray& ports, |
| 234 ExceptionState& exceptionState) { | 243 ExceptionState& exceptionState) { |
| 235 if (!ports.size()) | 244 if (!ports.size()) |
| 236 return nullptr; | 245 return nullptr; |
| 237 | 246 |
| 238 HeapHashSet<Member<MessagePort>> visited; | 247 HeapHashSet<Member<MessagePort>> visited; |
| 239 | 248 |
| 240 // Walk the incoming array - if there are any duplicate ports, or null ports o
r cloned ports, throw an error (per section 8.3.3 of the HTML5 spec). | 249 // Walk the incoming array - if there are any duplicate ports, or null ports |
| 250 // or cloned ports, throw an error (per section 8.3.3 of the HTML5 spec). |
| 241 for (unsigned i = 0; i < ports.size(); ++i) { | 251 for (unsigned i = 0; i < ports.size(); ++i) { |
| 242 MessagePort* port = ports[i]; | 252 MessagePort* port = ports[i]; |
| 243 if (!port || port->isNeutered() || visited.contains(port)) { | 253 if (!port || port->isNeutered() || visited.contains(port)) { |
| 244 String type; | 254 String type; |
| 245 if (!port) | 255 if (!port) |
| 246 type = "null"; | 256 type = "null"; |
| 247 else if (port->isNeutered()) | 257 else if (port->isNeutered()) |
| 248 type = "already neutered"; | 258 type = "already neutered"; |
| 249 else | 259 else |
| 250 type = "a duplicate"; | 260 type = "a duplicate"; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 } | 292 } |
| 283 return portArray; | 293 return portArray; |
| 284 } | 294 } |
| 285 | 295 |
| 286 DEFINE_TRACE(MessagePort) { | 296 DEFINE_TRACE(MessagePort) { |
| 287 ActiveDOMObject::trace(visitor); | 297 ActiveDOMObject::trace(visitor); |
| 288 EventTargetWithInlineData::trace(visitor); | 298 EventTargetWithInlineData::trace(visitor); |
| 289 } | 299 } |
| 290 | 300 |
| 291 } // namespace blink | 301 } // namespace blink |
| OLD | NEW |