void MessagePort::postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, ExceptionState& exceptionState) { if (!isEntangled()) return; ASSERT(executionContext()); ASSERT(m_entangledChannel); OwnPtr<MessagePortChannelArray> channels; // Make sure we aren't connected to any of the passed-in ports. if (ports) { for (unsigned i = 0; i < ports->size(); ++i) { MessagePort* dataPort = (*ports)[i].get(); if (dataPort == this) { exceptionState.throwDOMException(DataCloneError, "Port at index " + String::number(i) + " contains the source port."); return; } } channels = MessagePort::disentanglePorts(ports, exceptionState); if (exceptionState.hadException()) return; } blink::WebString messageString = message->toWireString(); OwnPtr<blink::WebMessagePortChannelArray> webChannels = toWebMessagePortChannelArray(channels.release()); m_entangledChannel->postMessage(messageString, webChannels.leakPtr()); }
void MessagePort::close() { m_closed = true; if (!isEntangled()) return; m_entangledChannel->close(); }
ExceptionOr<void> MessagePort::postMessage(JSC::ExecState& state, JSC::JSValue messageValue, Vector<JSC::Strong<JSC::JSObject>>&& transfer) { Vector<RefPtr<MessagePort>> ports; auto message = SerializedScriptValue::create(state, messageValue, WTFMove(transfer), ports); if (message.hasException()) return message.releaseException(); if (!isEntangled()) return { }; ASSERT(m_scriptExecutionContext); std::unique_ptr<MessagePortChannelArray> channels; // Make sure we aren't connected to any of the passed-in ports. if (!ports.isEmpty()) { for (auto& dataPort : ports) { if (dataPort == this || m_entangledChannel->isConnectedTo(dataPort.get())) return Exception { DATA_CLONE_ERR }; } auto disentangleResult = MessagePort::disentanglePorts(WTFMove(ports)); if (disentangleResult.hasException()) return disentangleResult.releaseException(); channels = disentangleResult.releaseReturnValue(); } m_entangledChannel->postMessageToRemote(message.releaseReturnValue(), WTFMove(channels)); return { }; }
void MessagePort::postMessage(ExecutionContext* context, PassRefPtr<SerializedScriptValue> message, const MessagePortArray& ports, ExceptionState& exceptionState) { if (!isEntangled()) return; DCHECK(getExecutionContext()); DCHECK(m_entangledChannel); // Make sure we aren't connected to any of the passed-in ports. for (unsigned i = 0; i < ports.size(); ++i) { if (ports[i] == this) { exceptionState.throwDOMException( DataCloneError, "Port at index " + String::number(i) + " contains the source port."); return; } } std::unique_ptr<MessagePortChannelArray> channels = MessagePort::disentanglePorts(context, ports, exceptionState); if (exceptionState.hadException()) return; if (message->containsTransferableArrayBuffer()) getExecutionContext()->addConsoleMessage(ConsoleMessage::create( JSMessageSource, WarningMessageLevel, "MessagePort cannot send an ArrayBuffer as a transferable object yet. " "See http://crbug.com/334408")); WebString messageString = message->toWireString(); std::unique_ptr<WebMessagePortChannelArray> webChannels = toWebMessagePortChannelArray(std::move(channels)); m_entangledChannel->postMessage(messageString, webChannels.release()); }
bool MessagePort::hasPendingActivity() const { // The spec says that entangled message ports should always be treated as if // they have a strong reference. // 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 it's unreachable). return m_started && isEntangled(); }
bool MessagePort::hasPendingActivity() { // The spec says that entangled message ports should always be treated as if they have a strong reference. // 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 it's unreachable). if (m_started && m_entangledChannel && m_entangledChannel->hasPendingActivity()) return true; if (isEntangled() && !locallyEntangledPort()) return true; return false; }
void MessagePort::start() { // Do nothing if we've been cloned or closed. if (!isEntangled()) return; ASSERT(m_scriptExecutionContext); if (m_started) return; m_started = true; m_scriptExecutionContext->processMessagePortMessagesSoon(); }
void MessagePort::start() { // Do nothing if we've been cloned or closed. if (!isEntangled()) return; ASSERT(executionContext()); if (m_started) return; m_started = true; messageAvailable(); }
void MessagePort::start() { // Do nothing if we've been cloned or closed. if (!isEntangled()) return; DCHECK(getExecutionContext()); if (m_started) return; m_entangledChannel->setClient(this); m_started = true; messageAvailable(); }
void MessagePort::postMessage(RefPtr<SerializedScriptValue>&& message, const MessagePortArray* ports, ExceptionCode& ec) { if (!isEntangled()) return; ASSERT(m_scriptExecutionContext); std::unique_ptr<MessagePortChannelArray> channels; // Make sure we aren't connected to any of the passed-in ports. if (ports) { for (auto& dataPort : *ports) { if (dataPort == this || m_entangledChannel->isConnectedTo(dataPort.get())) { ec = DATA_CLONE_ERR; return; } } channels = MessagePort::disentanglePorts(ports, ec); if (ec) return; } m_entangledChannel->postMessageToRemote(WTFMove(message), WTFMove(channels)); }
void MessagePort::postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, ExceptionCode& ec) { if (!isEntangled()) return; ASSERT(m_scriptExecutionContext); std::unique_ptr<MessagePortChannelArray> channels; // Make sure we aren't connected to any of the passed-in ports. if (ports) { for (unsigned int i = 0; i < ports->size(); ++i) { MessagePort* dataPort = (*ports)[i].get(); if (dataPort == this || m_entangledChannel->isConnectedTo(dataPort)) { ec = DATA_CLONE_ERR; return; } } channels = MessagePort::disentanglePorts(ports, ec); if (ec) return; } m_entangledChannel->postMessageToRemote(message, std::move(channels)); }
void MessagePort::close() { if (isEntangled()) m_entangledChannel->close(); m_closed = true; }
MessagePort::~MessagePort() { DCHECK(!m_started || !isEntangled()); if (m_scriptStateForConversion) m_scriptStateForConversion->disposePerContextData(); }
void MessagePort::close() { if (isEntangled()) m_entangledChannel->setClient(nullptr); m_closed = true; }