1/* 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#ifndef WorkerThreadableWebSocketChannel_h 32#define WorkerThreadableWebSocketChannel_h 33 34#include "core/dom/ExecutionContextTask.h" 35#include "core/frame/ConsoleTypes.h" 36#include "core/workers/WorkerGlobalScope.h" 37#include "modules/websockets/WebSocketChannel.h" 38#include "modules/websockets/WebSocketChannelClient.h" 39#include "platform/heap/Handle.h" 40#include "wtf/Assertions.h" 41#include "wtf/PassOwnPtr.h" 42#include "wtf/PassRefPtr.h" 43#include "wtf/RefCounted.h" 44#include "wtf/RefPtr.h" 45#include "wtf/Threading.h" 46#include "wtf/Vector.h" 47#include "wtf/WeakPtr.h" 48#include "wtf/text/WTFString.h" 49 50namespace blink { 51class WebWaitableEvent; 52} 53 54namespace WebCore { 55 56class BlobDataHandle; 57class KURL; 58class ExecutionContext; 59class ThreadableWebSocketChannelClientWrapper; 60class ThreadableWebSocketChannelSyncHelper; 61class WorkerGlobalScope; 62class WorkerLoaderProxy; 63class WorkerRunLoop; 64 65class WorkerThreadableWebSocketChannel FINAL : public WebSocketChannel { 66 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED; 67public: 68 static PassRefPtrWillBeRawPtr<WebSocketChannel> create(WorkerGlobalScope& workerGlobalScope, WebSocketChannelClient* client, const String& sourceURL, unsigned lineNumber) 69 { 70 return adoptRefWillBeRefCountedGarbageCollected(new WorkerThreadableWebSocketChannel(workerGlobalScope, client, sourceURL, lineNumber)); 71 } 72 virtual ~WorkerThreadableWebSocketChannel(); 73 74 // WebSocketChannel functions. 75 virtual bool connect(const KURL&, const String& protocol) OVERRIDE; 76 virtual WebSocketChannel::SendResult send(const String& message) OVERRIDE; 77 virtual WebSocketChannel::SendResult send(const ArrayBuffer&, unsigned byteOffset, unsigned byteLength) OVERRIDE; 78 virtual WebSocketChannel::SendResult send(PassRefPtr<BlobDataHandle>) OVERRIDE; 79 virtual WebSocketChannel::SendResult send(PassOwnPtr<Vector<char> >) OVERRIDE 80 { 81 ASSERT_NOT_REACHED(); 82 return WebSocketChannel::SendFail; 83 } 84 virtual void close(int code, const String& reason) OVERRIDE; 85 virtual void fail(const String& reason, MessageLevel, const String&, unsigned) OVERRIDE; 86 virtual void disconnect() OVERRIDE; // Will suppress didClose(). 87 virtual void suspend() OVERRIDE { } 88 virtual void resume() OVERRIDE { } 89 90 virtual void trace(Visitor*) OVERRIDE; 91 92 // Generated by the bridge. The Peer is destructed by an async call from 93 // Bridge, and may outlive the bridge. All methods of this class must 94 // be called on the main thread. 95 class Peer FINAL : public WebSocketChannelClient { 96 WTF_MAKE_NONCOPYABLE(Peer); WTF_MAKE_FAST_ALLOCATED; 97 public: 98 virtual ~Peer(); 99 100 // sourceURLAtConnection and lineNumberAtConnection parameters may 101 // be shown when the connection fails. 102 static void initialize(ExecutionContext*, PassRefPtr<WeakReference<Peer> >, WorkerLoaderProxy*, PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper>, const String& sourceURLAtConnection, unsigned lineNumberAtConnection, PassOwnPtr<ThreadableWebSocketChannelSyncHelper>); 103 void destroy(); 104 105 void connect(const KURL&, const String& protocol); 106 void send(const String& message); 107 void sendArrayBuffer(PassOwnPtr<Vector<char> >); 108 void sendBlob(PassRefPtr<BlobDataHandle>); 109 void bufferedAmount(); 110 void close(int code, const String& reason); 111 void fail(const String& reason, MessageLevel, const String& sourceURL, unsigned lineNumber); 112 void disconnect(); 113 114 // WebSocketChannelClient functions. 115 virtual void didConnect(const String& subprotocol, const String& extensions) OVERRIDE; 116 virtual void didReceiveMessage(const String& message) OVERRIDE; 117 virtual void didReceiveBinaryData(PassOwnPtr<Vector<char> >) OVERRIDE; 118 virtual void didConsumeBufferedAmount(unsigned long) OVERRIDE; 119 virtual void didStartClosingHandshake() OVERRIDE; 120 virtual void didClose(ClosingHandshakeCompletionStatus, unsigned short code, const String& reason) OVERRIDE; 121 virtual void didReceiveMessageError() OVERRIDE; 122 123 private: 124 Peer(PassRefPtr<WeakReference<Peer> >, PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper>, WorkerLoaderProxy&, ExecutionContext*, const String& sourceURL, unsigned lineNumber, PassOwnPtr<ThreadableWebSocketChannelSyncHelper>); 125 126 const RefPtrWillBePersistent<ThreadableWebSocketChannelClientWrapper> m_workerClientWrapper; 127 WorkerLoaderProxy& m_loaderProxy; 128 RefPtrWillBePersistent<WebSocketChannel> m_mainWebSocketChannel; 129 OwnPtr<ThreadableWebSocketChannelSyncHelper> m_syncHelper; 130 WeakPtrFactory<Peer> m_weakFactory; 131 }; 132 133private: 134 // Bridge for Peer. Running on the worker thread. 135 class Bridge : public RefCounted<Bridge> { 136 public: 137 static PassRefPtr<Bridge> create(PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, WorkerGlobalScope& workerGlobalScope) 138 { 139 return adoptRef(new Bridge(workerClientWrapper, workerGlobalScope)); 140 } 141 ~Bridge(); 142 // sourceURLAtConnection and lineNumberAtConnection parameters may 143 // be shown when the connection fails. 144 void initialize(const String& sourceURLAtConnection, unsigned lineNumberAtConnection); 145 bool connect(const KURL&, const String& protocol); 146 WebSocketChannel::SendResult send(const String& message); 147 WebSocketChannel::SendResult send(const ArrayBuffer&, unsigned byteOffset, unsigned byteLength); 148 WebSocketChannel::SendResult send(PassRefPtr<BlobDataHandle>); 149 unsigned long bufferedAmount(); 150 void close(int code, const String& reason); 151 void fail(const String& reason, MessageLevel, const String& sourceURL, unsigned lineNumber); 152 void disconnect(); 153 154 private: 155 Bridge(PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper>, WorkerGlobalScope&); 156 157 static void setWebSocketChannel(ExecutionContext*, Bridge* thisPtr, Peer*, PassRefPtrWillBeRawPtr<ThreadableWebSocketChannelClientWrapper>); 158 159 // Executed on the worker context's thread. 160 void clearClientWrapper(); 161 162 // Returns false if shutdown event is received before method completion. 163 bool waitForMethodCompletion(PassOwnPtr<ExecutionContextTask>); 164 165 void terminatePeer(); 166 167 bool hasTerminatedPeer() { return !m_syncHelper; } 168 169 const RefPtrWillBePersistent<ThreadableWebSocketChannelClientWrapper> m_workerClientWrapper; 170 RefPtrWillBePersistent<WorkerGlobalScope> m_workerGlobalScope; 171 WorkerLoaderProxy& m_loaderProxy; 172 ThreadableWebSocketChannelSyncHelper* m_syncHelper; 173 WeakPtr<Peer> m_peer; 174 }; 175 176 WorkerThreadableWebSocketChannel(WorkerGlobalScope&, WebSocketChannelClient*, const String& sourceURL, unsigned lineNumber); 177 178 const RefPtrWillBeMember<ThreadableWebSocketChannelClientWrapper> m_workerClientWrapper; 179 RefPtr<Bridge> m_bridge; 180 String m_sourceURLAtConnection; 181 unsigned m_lineNumberAtConnection; 182}; 183 184} // namespace WebCore 185 186#endif // WorkerThreadableWebSocketChannel_h 187