1d0825bca7fe65beaee391d30da42e937db621564Steve Block/* 2d0825bca7fe65beaee391d30da42e937db621564Steve Block * Copyright (C) 2009 Google Inc. All rights reserved. 3d0825bca7fe65beaee391d30da42e937db621564Steve Block * 4d0825bca7fe65beaee391d30da42e937db621564Steve Block * Redistribution and use in source and binary forms, with or without 5d0825bca7fe65beaee391d30da42e937db621564Steve Block * modification, are permitted provided that the following conditions are 6d0825bca7fe65beaee391d30da42e937db621564Steve Block * met: 7d0825bca7fe65beaee391d30da42e937db621564Steve Block * 8d0825bca7fe65beaee391d30da42e937db621564Steve Block * * Redistributions of source code must retain the above copyright 9d0825bca7fe65beaee391d30da42e937db621564Steve Block * notice, this list of conditions and the following disclaimer. 10d0825bca7fe65beaee391d30da42e937db621564Steve Block * * Redistributions in binary form must reproduce the above 11d0825bca7fe65beaee391d30da42e937db621564Steve Block * copyright notice, this list of conditions and the following disclaimer 12d0825bca7fe65beaee391d30da42e937db621564Steve Block * in the documentation and/or other materials provided with the 13d0825bca7fe65beaee391d30da42e937db621564Steve Block * distribution. 14d0825bca7fe65beaee391d30da42e937db621564Steve Block * * Neither the name of Google Inc. nor the names of its 15d0825bca7fe65beaee391d30da42e937db621564Steve Block * contributors may be used to endorse or promote products derived from 16d0825bca7fe65beaee391d30da42e937db621564Steve Block * this software without specific prior written permission. 17d0825bca7fe65beaee391d30da42e937db621564Steve Block * 18d0825bca7fe65beaee391d30da42e937db621564Steve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19d0825bca7fe65beaee391d30da42e937db621564Steve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20d0825bca7fe65beaee391d30da42e937db621564Steve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21d0825bca7fe65beaee391d30da42e937db621564Steve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22d0825bca7fe65beaee391d30da42e937db621564Steve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23d0825bca7fe65beaee391d30da42e937db621564Steve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24d0825bca7fe65beaee391d30da42e937db621564Steve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25d0825bca7fe65beaee391d30da42e937db621564Steve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26d0825bca7fe65beaee391d30da42e937db621564Steve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27d0825bca7fe65beaee391d30da42e937db621564Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28d0825bca7fe65beaee391d30da42e937db621564Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29d0825bca7fe65beaee391d30da42e937db621564Steve Block */ 30d0825bca7fe65beaee391d30da42e937db621564Steve Block 31d0825bca7fe65beaee391d30da42e937db621564Steve Block#ifndef ThreadableWebSocketChannelClientWrapper_h 32d0825bca7fe65beaee391d30da42e937db621564Steve Block#define ThreadableWebSocketChannelClientWrapper_h 33d0825bca7fe65beaee391d30da42e937db621564Steve Block 34d0825bca7fe65beaee391d30da42e937db621564Steve Block#if ENABLE(WEB_SOCKETS) 35d0825bca7fe65beaee391d30da42e937db621564Steve Block 366c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#include "PlatformString.h" 37d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "WebSocketChannelClient.h" 38dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include <wtf/Forward.h> 39d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <wtf/PassRefPtr.h> 40d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <wtf/Threading.h> 416c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#include <wtf/Vector.h> 42d0825bca7fe65beaee391d30da42e937db621564Steve Block 43d0825bca7fe65beaee391d30da42e937db621564Steve Blocknamespace WebCore { 44d0825bca7fe65beaee391d30da42e937db621564Steve Block 452bde8e466a4451c7319e3a072d118917957d6554Steve Blockclass ThreadableWebSocketChannelClientWrapper : public ThreadSafeRefCounted<ThreadableWebSocketChannelClientWrapper> { 46d0825bca7fe65beaee391d30da42e937db621564Steve Blockpublic: 47d0825bca7fe65beaee391d30da42e937db621564Steve Block static PassRefPtr<ThreadableWebSocketChannelClientWrapper> create(WebSocketChannelClient* client) 48d0825bca7fe65beaee391d30da42e937db621564Steve Block { 49d0825bca7fe65beaee391d30da42e937db621564Steve Block return adoptRef(new ThreadableWebSocketChannelClientWrapper(client)); 50d0825bca7fe65beaee391d30da42e937db621564Steve Block } 51d0825bca7fe65beaee391d30da42e937db621564Steve Block 52d0825bca7fe65beaee391d30da42e937db621564Steve Block void clearSyncMethodDone() 53d0825bca7fe65beaee391d30da42e937db621564Steve Block { 54d0825bca7fe65beaee391d30da42e937db621564Steve Block m_syncMethodDone = false; 55d0825bca7fe65beaee391d30da42e937db621564Steve Block } 56d0825bca7fe65beaee391d30da42e937db621564Steve Block void setSyncMethodDone() 57d0825bca7fe65beaee391d30da42e937db621564Steve Block { 58d0825bca7fe65beaee391d30da42e937db621564Steve Block m_syncMethodDone = true; 59d0825bca7fe65beaee391d30da42e937db621564Steve Block } 60d0825bca7fe65beaee391d30da42e937db621564Steve Block 61d0825bca7fe65beaee391d30da42e937db621564Steve Block bool syncMethodDone() const 62d0825bca7fe65beaee391d30da42e937db621564Steve Block { 63d0825bca7fe65beaee391d30da42e937db621564Steve Block return m_syncMethodDone; 64d0825bca7fe65beaee391d30da42e937db621564Steve Block } 65d0825bca7fe65beaee391d30da42e937db621564Steve Block 66d0825bca7fe65beaee391d30da42e937db621564Steve Block bool sent() const 67d0825bca7fe65beaee391d30da42e937db621564Steve Block { 68d0825bca7fe65beaee391d30da42e937db621564Steve Block return m_sent; 69d0825bca7fe65beaee391d30da42e937db621564Steve Block } 70d0825bca7fe65beaee391d30da42e937db621564Steve Block void setSent(bool sent) 71d0825bca7fe65beaee391d30da42e937db621564Steve Block { 72d0825bca7fe65beaee391d30da42e937db621564Steve Block m_sent = sent; 73d0825bca7fe65beaee391d30da42e937db621564Steve Block m_syncMethodDone = true; 74d0825bca7fe65beaee391d30da42e937db621564Steve Block } 75d0825bca7fe65beaee391d30da42e937db621564Steve Block 76d0825bca7fe65beaee391d30da42e937db621564Steve Block unsigned long bufferedAmount() const 77d0825bca7fe65beaee391d30da42e937db621564Steve Block { 78d0825bca7fe65beaee391d30da42e937db621564Steve Block return m_bufferedAmount; 79d0825bca7fe65beaee391d30da42e937db621564Steve Block } 80d0825bca7fe65beaee391d30da42e937db621564Steve Block void setBufferedAmount(unsigned long bufferedAmount) 81d0825bca7fe65beaee391d30da42e937db621564Steve Block { 82d0825bca7fe65beaee391d30da42e937db621564Steve Block m_bufferedAmount = bufferedAmount; 83d0825bca7fe65beaee391d30da42e937db621564Steve Block m_syncMethodDone = true; 84d0825bca7fe65beaee391d30da42e937db621564Steve Block } 85d0825bca7fe65beaee391d30da42e937db621564Steve Block 86d0825bca7fe65beaee391d30da42e937db621564Steve Block void clearClient() 87d0825bca7fe65beaee391d30da42e937db621564Steve Block { 88d0825bca7fe65beaee391d30da42e937db621564Steve Block m_client = 0; 89d0825bca7fe65beaee391d30da42e937db621564Steve Block } 90d0825bca7fe65beaee391d30da42e937db621564Steve Block 91d0825bca7fe65beaee391d30da42e937db621564Steve Block void didConnect() 92d0825bca7fe65beaee391d30da42e937db621564Steve Block { 936c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_pendingConnected = true; 946c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (!m_suspended) 956c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen processPendingEvents(); 96d0825bca7fe65beaee391d30da42e937db621564Steve Block } 97d0825bca7fe65beaee391d30da42e937db621564Steve Block 98d0825bca7fe65beaee391d30da42e937db621564Steve Block void didReceiveMessage(const String& msg) 99d0825bca7fe65beaee391d30da42e937db621564Steve Block { 1006c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_pendingMessages.append(msg); 1016c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (!m_suspended) 1026c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen processPendingEvents(); 103d0825bca7fe65beaee391d30da42e937db621564Steve Block } 104d0825bca7fe65beaee391d30da42e937db621564Steve Block 1058a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block void didClose(unsigned long unhandledBufferedAmount) 106d0825bca7fe65beaee391d30da42e937db621564Steve Block { 1076c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_pendingClosed = true; 1086c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_bufferedAmount = unhandledBufferedAmount; 1096c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (!m_suspended) 1106c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen processPendingEvents(); 1116c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 1126c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 1136c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen void suspend() 1146c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen { 1156c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_suspended = true; 1166c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 1176c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 1186c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen void resume() 1196c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen { 1206c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_suspended = false; 1216c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen processPendingEvents(); 122d0825bca7fe65beaee391d30da42e937db621564Steve Block } 123d0825bca7fe65beaee391d30da42e937db621564Steve Block 124d0825bca7fe65beaee391d30da42e937db621564Steve Blockprotected: 125d0825bca7fe65beaee391d30da42e937db621564Steve Block ThreadableWebSocketChannelClientWrapper(WebSocketChannelClient* client) 126d0825bca7fe65beaee391d30da42e937db621564Steve Block : m_client(client) 127d0825bca7fe65beaee391d30da42e937db621564Steve Block , m_syncMethodDone(false) 128d0825bca7fe65beaee391d30da42e937db621564Steve Block , m_sent(false) 129d0825bca7fe65beaee391d30da42e937db621564Steve Block , m_bufferedAmount(0) 1306c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen , m_suspended(false) 1316c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen , m_pendingConnected(false) 1326c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen , m_pendingClosed(false) 1336c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen { 1346c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 1356c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 1366c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen void processPendingEvents() 137d0825bca7fe65beaee391d30da42e937db621564Steve Block { 1386c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen ASSERT(!m_suspended); 1396c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (m_pendingConnected) { 1406c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_pendingConnected = false; 1416c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (m_client) 1426c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_client->didConnect(); 1436c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 1446c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 1456c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen Vector<String> messages; 1466c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen messages.swap(m_pendingMessages); 1476c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen for (Vector<String>::const_iterator iter = messages.begin(); iter != messages.end(); ++iter) { 1486c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (m_client) 1496c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_client->didReceiveMessage(*iter); 1506c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 1516c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 1526c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (m_pendingClosed) { 1536c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_pendingClosed = false; 1546c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen if (m_client) 1556c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen m_client->didClose(m_bufferedAmount); 1566c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen } 157d0825bca7fe65beaee391d30da42e937db621564Steve Block } 158d0825bca7fe65beaee391d30da42e937db621564Steve Block 159d0825bca7fe65beaee391d30da42e937db621564Steve Block WebSocketChannelClient* m_client; 160d0825bca7fe65beaee391d30da42e937db621564Steve Block bool m_syncMethodDone; 161d0825bca7fe65beaee391d30da42e937db621564Steve Block bool m_sent; 162d0825bca7fe65beaee391d30da42e937db621564Steve Block unsigned long m_bufferedAmount; 1636c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen bool m_suspended; 1646c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen bool m_pendingConnected; 1656c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen Vector<String> m_pendingMessages; 1666c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen bool m_pendingClosed; 167d0825bca7fe65beaee391d30da42e937db621564Steve Block}; 168d0825bca7fe65beaee391d30da42e937db621564Steve Block 169d0825bca7fe65beaee391d30da42e937db621564Steve Block} // namespace WebCore 170d0825bca7fe65beaee391d30da42e937db621564Steve Block 171d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif // ENABLE(WEB_SOCKETS) 172d0825bca7fe65beaee391d30da42e937db621564Steve Block 173d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif // ThreadableWebSocketChannelClientWrapper_h 174