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 |