15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011, 2012 Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/websockets/WorkerThreadableWebSocketChannel.h" 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 35197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptCallStackFactory.h" 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/CrossThreadTask.h" 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h" 381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/dom/ExecutionContext.h" 399e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)#include "core/dom/ExecutionContextTask.h" 4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/fileapi/Blob.h" 4181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)#include "core/inspector/ScriptCallFrame.h" 4281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)#include "core/inspector/ScriptCallStack.h" 439e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)#include "core/workers/WorkerGlobalScope.h" 4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/workers/WorkerLoaderProxy.h" 4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/workers/WorkerThread.h" 4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/websockets/MainThreadWebSocketChannel.h" 4709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "modules/websockets/NewWebSocketChannelImpl.h" 4876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)#include "platform/RuntimeEnabledFeatures.h" 4909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "public/platform/Platform.h" 5009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "public/platform/WebWaitableEvent.h" 5153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/ArrayBuffer.h" 52323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#include "wtf/Assertions.h" 5309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "wtf/Functional.h" 5453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/MainThread.h" 559e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)#include "wtf/text/WTFString.h" 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 57c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 58c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 59c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)typedef WorkerThreadableWebSocketChannel::Bridge Bridge; 60c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)typedef WorkerThreadableWebSocketChannel::Peer Peer; 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// Created and destroyed on the worker thread. All setters of this class are 6309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// called on the main thread, while all getters are called on the worker 6409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// thread. signalWorkerThread() must be called before any getters are called. 65c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class ThreadableWebSocketChannelSyncHelper : public GarbageCollectedFinalized<ThreadableWebSocketChannelSyncHelper> { 6609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)public: 67e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) static ThreadableWebSocketChannelSyncHelper* create(PassOwnPtr<WebWaitableEvent> event) 68197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 69c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return new ThreadableWebSocketChannelSyncHelper(event); 70197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 71197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 72197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ~ThreadableWebSocketChannelSyncHelper() 7309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) { 7409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 7509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 7609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // All setters are called on the main thread. 77f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu void setConnectRequestResult(bool connectRequestResult) 78f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu { 79f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu m_connectRequestResult = connectRequestResult; 80f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu } 8109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 8209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // All getter are called on the worker thread. 83f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu bool connectRequestResult() const 84f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu { 85f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return m_connectRequestResult; 86f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu } 8709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 8809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // This should be called after all setters are called and before any 8909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // getters are called. 9009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) void signalWorkerThread() 9109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) { 9209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_event->signal(); 9309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 94c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) void wait() 9509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) { 96c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_event->wait(); 9709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 9809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 99197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch void trace(Visitor* visitor) { } 100197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 10109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)private: 102e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) explicit ThreadableWebSocketChannelSyncHelper(PassOwnPtr<WebWaitableEvent> event) 10309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) : m_event(event) 104f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu , m_connectRequestResult(false) 10509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) { 10609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 10709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 108e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) OwnPtr<WebWaitableEvent> m_event; 109f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu bool m_connectRequestResult; 11009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}; 11109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 112323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)WorkerThreadableWebSocketChannel::WorkerThreadableWebSocketChannel(WorkerGlobalScope& workerGlobalScope, WebSocketChannelClient* client, const String& sourceURL, unsigned lineNumber) 1139e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) : m_bridge(new Bridge(client, workerGlobalScope)) 114a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) , m_sourceURLAtConnection(sourceURL) 115a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) , m_lineNumberAtConnection(lineNumber) 11681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles){ 11781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) m_bridge->initialize(sourceURL, lineNumber); 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WorkerThreadableWebSocketChannel::~WorkerThreadableWebSocketChannel() 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 122197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(!m_bridge); 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 125f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liubool WorkerThreadableWebSocketChannel::connect(const KURL& url, const String& protocol) 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 127c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_bridge); 128c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return m_bridge->connect(url, protocol); 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 131c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void WorkerThreadableWebSocketChannel::send(const String& message) 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 133c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_bridge); 134c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_bridge->send(message); 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 137c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void WorkerThreadableWebSocketChannel::send(const ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength) 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 139c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_bridge); 140c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_bridge->send(binaryData, byteOffset, byteLength); 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 143c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void WorkerThreadableWebSocketChannel::send(PassRefPtr<BlobDataHandle> blobData) 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 145c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_bridge); 146c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_bridge->send(blobData); 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void WorkerThreadableWebSocketChannel::close(int code, const String& reason) 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 151c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_bridge); 152c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_bridge->close(code, reason); 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)void WorkerThreadableWebSocketChannel::fail(const String& reason, MessageLevel level, const String& sourceURL, unsigned lineNumber) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) if (!m_bridge) 15881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) return; 15981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) 1605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) RefPtrWillBeRawPtr<ScriptCallStack> callStack = createScriptCallStack(1, true); 16181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) if (callStack && callStack->size()) { 16281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) // In order to emulate the ConsoleMessage behavior, 16381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) // we should ignore the specified url and line number if 16481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) // we can get the JavaScript context. 16581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) m_bridge->fail(reason, level, callStack->at(0).sourceURL(), callStack->at(0).lineNumber()); 16681a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) } else if (sourceURL.isEmpty() && !lineNumber) { 16781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) // No information is specified by the caller - use the url 16881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) // and the line number at the connection. 16981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) m_bridge->fail(reason, level, m_sourceURLAtConnection, m_lineNumberAtConnection); 17081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) } else { 17181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) // Use the specified information. 17281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) m_bridge->fail(reason, level, sourceURL, lineNumber); 17381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) } 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void WorkerThreadableWebSocketChannel::disconnect() 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_bridge->disconnect(); 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_bridge.clear(); 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)void WorkerThreadableWebSocketChannel::trace(Visitor* visitor) 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 184197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch visitor->trace(m_bridge); 1855d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) WebSocketChannel::trace(visitor); 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1889e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)Peer::Peer(Bridge* bridge, WorkerLoaderProxy& loaderProxy, ThreadableWebSocketChannelSyncHelper* syncHelper) 1899e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) : m_bridge(bridge) 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_loaderProxy(loaderProxy) 191d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) , m_mainWebSocketChannel(nullptr) 19209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) , m_syncHelper(syncHelper) 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 194c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(!isMainThread()); 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 197c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)Peer::~Peer() 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 199c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(!isMainThread()); 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 202c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Peer::initializeInternal(ExecutionContext* context, const String& sourceURL, unsigned lineNumber) 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 20409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ASSERT(isMainThread()); 205c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) Document* document = toDocument(context); 206c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (RuntimeEnabledFeatures::experimentalWebSocketEnabled()) { 207c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_mainWebSocketChannel = NewWebSocketChannelImpl::create(document, this, sourceURL, lineNumber); 208c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } else { 209c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_mainWebSocketChannel = MainThreadWebSocketChannel::create(document, this, sourceURL, lineNumber); 210c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 211197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_syncHelper->signalWorkerThread(); 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 214c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Peer::connect(const KURL& url, const String& protocol) 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isMainThread()); 217c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_syncHelper); 218323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (!m_mainWebSocketChannel) { 219f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu m_syncHelper->setConnectRequestResult(false); 220f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu } else { 221f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu bool connectRequestResult = m_mainWebSocketChannel->connect(url, protocol); 222f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu m_syncHelper->setConnectRequestResult(connectRequestResult); 223f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu } 224f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu m_syncHelper->signalWorkerThread(); 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 227c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Peer::send(const String& message) 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isMainThread()); 230c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_mainWebSocketChannel) 231c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_mainWebSocketChannel->send(message); 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 234c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Peer::sendArrayBuffer(PassOwnPtr<Vector<char> > data) 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isMainThread()); 237c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_mainWebSocketChannel) 238c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_mainWebSocketChannel->send(data); 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 241c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Peer::sendBlob(PassRefPtr<BlobDataHandle> blobData) 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 24309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ASSERT(isMainThread()); 244c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_mainWebSocketChannel) 245c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_mainWebSocketChannel->send(blobData); 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 248c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Peer::close(int code, const String& reason) 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isMainThread()); 251c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_syncHelper); 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_mainWebSocketChannel) 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_mainWebSocketChannel->close(code, reason); 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 257c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Peer::fail(const String& reason, MessageLevel level, const String& sourceURL, unsigned lineNumber) 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isMainThread()); 260c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_syncHelper); 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_mainWebSocketChannel) 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 26381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles) m_mainWebSocketChannel->fail(reason, level, sourceURL, lineNumber); 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 266c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Peer::disconnect() 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isMainThread()); 269c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_syncHelper); 270c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_mainWebSocketChannel) { 271c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_mainWebSocketChannel->disconnect(); 272c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_mainWebSocketChannel = nullptr; 273c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 274c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_syncHelper->signalWorkerThread(); 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2779e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)static void workerGlobalScopeDidConnect(ExecutionContext* context, Bridge* bridge, const String& subprotocol, const String& extensions) 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 279591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 2809e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) if (bridge->client()) 2819e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) bridge->client()->didConnect(subprotocol, extensions); 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 284c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Peer::didConnect(const String& subprotocol, const String& extensions) 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isMainThread()); 2879e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) m_loaderProxy.postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidConnect, m_bridge, subprotocol, extensions)); 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2909e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)static void workerGlobalScopeDidReceiveMessage(ExecutionContext* context, Bridge* bridge, const String& message) 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 292591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 2939e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) if (bridge->client()) 2949e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) bridge->client()->didReceiveMessage(message); 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 297c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Peer::didReceiveMessage(const String& message) 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isMainThread()); 3009e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) m_loaderProxy.postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidReceiveMessage, m_bridge, message)); 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3039e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)static void workerGlobalScopeDidReceiveBinaryData(ExecutionContext* context, Bridge* bridge, PassOwnPtr<Vector<char> > binaryData) 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 305591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 3069e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) if (bridge->client()) 3079e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) bridge->client()->didReceiveBinaryData(binaryData); 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 310c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Peer::didReceiveBinaryData(PassOwnPtr<Vector<char> > binaryData) 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isMainThread()); 3139e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) m_loaderProxy.postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidReceiveBinaryData, m_bridge, binaryData)); 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3169e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)static void workerGlobalScopeDidConsumeBufferedAmount(ExecutionContext* context, Bridge* bridge, unsigned long consumed) 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 318591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 3199e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) if (bridge->client()) 3209e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) bridge->client()->didConsumeBufferedAmount(consumed); 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 323c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Peer::didConsumeBufferedAmount(unsigned long consumed) 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isMainThread()); 3269e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) m_loaderProxy.postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidConsumeBufferedAmount, m_bridge, consumed)); 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3299e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)static void workerGlobalScopeDidStartClosingHandshake(ExecutionContext* context, Bridge* bridge) 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 331591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 3329e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) if (bridge->client()) 3339e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) bridge->client()->didStartClosingHandshake(); 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 336c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Peer::didStartClosingHandshake() 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isMainThread()); 3399e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) m_loaderProxy.postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidStartClosingHandshake, m_bridge)); 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3429e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)static void workerGlobalScopeDidClose(ExecutionContext* context, Bridge* bridge, WebSocketChannelClient::ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsigned short code, const String& reason) 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 344591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 3459e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) if (bridge->client()) 3469e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) bridge->client()->didClose(closingHandshakeCompletion, code, reason); 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 349c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Peer::didClose(ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsigned short code, const String& reason) 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(isMainThread()); 352c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_mainWebSocketChannel) { 353c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_mainWebSocketChannel->disconnect(); 354c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_mainWebSocketChannel = nullptr; 355c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 3569e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) m_loaderProxy.postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidClose, m_bridge, closingHandshakeCompletion, code, reason)); 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3599e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)static void workerGlobalScopeDidReceiveMessageError(ExecutionContext* context, Bridge* bridge) 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 361591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch ASSERT_UNUSED(context, context->isWorkerGlobalScope()); 3629e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) if (bridge->client()) 3639e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) bridge->client()->didReceiveMessageError(); 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 366c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Peer::didReceiveMessageError() 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 36853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) ASSERT(isMainThread()); 3699e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) m_loaderProxy.postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidReceiveMessageError, m_bridge)); 370197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 371197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 372c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Peer::trace(Visitor* visitor) 373197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 3749e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) visitor->trace(m_bridge); 375197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch visitor->trace(m_mainWebSocketChannel); 376197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch visitor->trace(m_syncHelper); 377197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WebSocketChannelClient::trace(visitor); 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3809e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)Bridge::Bridge(WebSocketChannelClient* client, WorkerGlobalScope& workerGlobalScope) 3819e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) : m_client(client) 382591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch , m_workerGlobalScope(workerGlobalScope) 383591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch , m_loaderProxy(m_workerGlobalScope->thread()->workerLoaderProxy()) 384e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) , m_syncHelper(ThreadableWebSocketChannelSyncHelper::create(adoptPtr(Platform::current()->createWaitableEvent()))) 3859e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) , m_peer(new Peer(this, m_loaderProxy, m_syncHelper)) 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 389c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)Bridge::~Bridge() 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 391c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(!m_peer); 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 394c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Bridge::initialize(const String& sourceURL, unsigned lineNumber) 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3969e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) if (!waitForMethodCompletion(createCrossThreadTask(&Peer::initialize, AllowCrossThreadAccess(m_peer.get()), sourceURL, lineNumber))) { 39709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // The worker thread has been signalled to shutdown before method completion. 398197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch disconnect(); 39909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 402c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)bool Bridge::connect(const KURL& url, const String& protocol) 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 404c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (!m_peer) 405f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return false; 406323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 407c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (!waitForMethodCompletion(createCrossThreadTask(&Peer::connect, m_peer.get(), url, protocol))) 408323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) return false; 409323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 410f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu return m_syncHelper->connectRequestResult(); 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 413c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Bridge::send(const String& message) 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 415c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_peer); 416c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_loaderProxy.postTaskToLoader(createCrossThreadTask(&Peer::send, m_peer.get(), message)); 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 419c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Bridge::send(const ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength) 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 421c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_peer); 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>. 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(byteLength)); 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (binaryData.byteLength()) 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteOffset, byteLength); 426f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 427c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_loaderProxy.postTaskToLoader(createCrossThreadTask(&Peer::sendArrayBuffer, m_peer.get(), data.release())); 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 430c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Bridge::send(PassRefPtr<BlobDataHandle> data) 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 432c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_peer); 433c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_loaderProxy.postTaskToLoader(createCrossThreadTask(&Peer::sendBlob, m_peer.get(), data)); 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 436c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Bridge::close(int code, const String& reason) 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 438c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_peer); 439c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_loaderProxy.postTaskToLoader(createCrossThreadTask(&Peer::close, m_peer.get(), code, reason)); 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 442c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Bridge::fail(const String& reason, MessageLevel level, const String& sourceURL, unsigned lineNumber) 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 444c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_peer); 445c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_loaderProxy.postTaskToLoader(createCrossThreadTask(&Peer::fail, m_peer.get(), reason, level, sourceURL, lineNumber)); 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 448c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Bridge::disconnect() 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 450c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (!m_peer) 451197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return; 452197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 453c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) waitForMethodCompletion(createCrossThreadTask(&Peer::disconnect, m_peer.get())); 454c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // Here |m_peer| is detached from the main thread and we can delete it. 455c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 4569e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) m_client = nullptr; 457c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_peer = nullptr; 458c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_syncHelper = nullptr; 459c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // We won't use this any more. 460c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_workerGlobalScope.clear(); 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 46309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// Caller of this function should hold a reference to the bridge, because this function may call WebSocket::didClose() in the end, 46409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// which causes the bridge to get disconnected from the WebSocket and deleted if there is no other reference. 465c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)bool Bridge::waitForMethodCompletion(PassOwnPtr<ExecutionContextTask> task) 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 467323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) ASSERT(m_workerGlobalScope); 468323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) ASSERT(m_syncHelper); 469323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) 470323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) m_loaderProxy.postTaskToLoader(task); 47109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 4725d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // We wait for the syncHelper event even if a shutdown event is fired. 4735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // See https://codereview.chromium.org/267323004/#msg43 for why we need to wait this. 474a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack); 475c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_syncHelper->wait(); 4765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // This is checking whether a shutdown event is fired or not. 477c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return !m_workerGlobalScope->thread()->terminated(); 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 480c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void Bridge::trace(Visitor* visitor) 481197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 4829e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) visitor->trace(m_client); 483197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch visitor->trace(m_workerGlobalScope); 484197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch visitor->trace(m_syncHelper); 485197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch visitor->trace(m_peer); 486197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 487197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 488c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 489