1d0825bca7fe65beaee391d30da42e937db621564Steve Block/*
2d0825bca7fe65beaee391d30da42e937db621564Steve Block * Copyright (C) 2009, 2010 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 WorkerThreadableWebSocketChannel_h
32d0825bca7fe65beaee391d30da42e937db621564Steve Block#define WorkerThreadableWebSocketChannel_h
33d0825bca7fe65beaee391d30da42e937db621564Steve Block
34d0825bca7fe65beaee391d30da42e937db621564Steve Block#if ENABLE(WEB_SOCKETS) && ENABLE(WORKERS)
35d0825bca7fe65beaee391d30da42e937db621564Steve Block
36d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "PlatformString.h"
37d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "ThreadableWebSocketChannel.h"
38d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "WebSocketChannelClient.h"
39d0825bca7fe65beaee391d30da42e937db621564Steve Block
40d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <wtf/PassRefPtr.h>
41d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <wtf/RefCounted.h>
42d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <wtf/RefPtr.h>
43d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <wtf/Threading.h>
44d0825bca7fe65beaee391d30da42e937db621564Steve Block
45d0825bca7fe65beaee391d30da42e937db621564Steve Blocknamespace WebCore {
46d0825bca7fe65beaee391d30da42e937db621564Steve Block
47d0825bca7fe65beaee391d30da42e937db621564Steve Blockclass KURL;
48d0825bca7fe65beaee391d30da42e937db621564Steve Blockclass ScriptExecutionContext;
49d0825bca7fe65beaee391d30da42e937db621564Steve Blockclass ThreadableWebSocketChannelClientWrapper;
50d0825bca7fe65beaee391d30da42e937db621564Steve Blockclass WorkerContext;
51d0825bca7fe65beaee391d30da42e937db621564Steve Blockclass WorkerLoaderProxy;
52d0825bca7fe65beaee391d30da42e937db621564Steve Blockclass WorkerRunLoop;
53d0825bca7fe65beaee391d30da42e937db621564Steve Block
54d0825bca7fe65beaee391d30da42e937db621564Steve Blockclass WorkerThreadableWebSocketChannel : public RefCounted<WorkerThreadableWebSocketChannel>, public ThreadableWebSocketChannel {
55ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    WTF_MAKE_FAST_ALLOCATED;
56d0825bca7fe65beaee391d30da42e937db621564Steve Blockpublic:
57d0825bca7fe65beaee391d30da42e937db621564Steve Block    static PassRefPtr<ThreadableWebSocketChannel> create(WorkerContext* workerContext, WebSocketChannelClient* client, const String& taskMode, const KURL& url, const String& protocol)
58d0825bca7fe65beaee391d30da42e937db621564Steve Block    {
59d0825bca7fe65beaee391d30da42e937db621564Steve Block        return adoptRef(new WorkerThreadableWebSocketChannel(workerContext, client, taskMode, url, protocol));
60d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
61d0825bca7fe65beaee391d30da42e937db621564Steve Block    virtual ~WorkerThreadableWebSocketChannel();
62d0825bca7fe65beaee391d30da42e937db621564Steve Block
63d0825bca7fe65beaee391d30da42e937db621564Steve Block    virtual void connect();
64d0825bca7fe65beaee391d30da42e937db621564Steve Block    virtual bool send(const String& message);
65d0825bca7fe65beaee391d30da42e937db621564Steve Block    virtual unsigned long bufferedAmount() const;
66d0825bca7fe65beaee391d30da42e937db621564Steve Block    virtual void close();
67d0825bca7fe65beaee391d30da42e937db621564Steve Block    virtual void disconnect(); // Will suppress didClose().
686c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    virtual void suspend();
696c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    virtual void resume();
70d0825bca7fe65beaee391d30da42e937db621564Steve Block
71d0825bca7fe65beaee391d30da42e937db621564Steve Block    using RefCounted<WorkerThreadableWebSocketChannel>::ref;
72d0825bca7fe65beaee391d30da42e937db621564Steve Block    using RefCounted<WorkerThreadableWebSocketChannel>::deref;
73d0825bca7fe65beaee391d30da42e937db621564Steve Block
74d0825bca7fe65beaee391d30da42e937db621564Steve Blockprotected:
75d0825bca7fe65beaee391d30da42e937db621564Steve Block    virtual void refThreadableWebSocketChannel() { ref(); }
76d0825bca7fe65beaee391d30da42e937db621564Steve Block    virtual void derefThreadableWebSocketChannel() { deref(); }
77d0825bca7fe65beaee391d30da42e937db621564Steve Block
78d0825bca7fe65beaee391d30da42e937db621564Steve Blockprivate:
79d0825bca7fe65beaee391d30da42e937db621564Steve Block    // Generated by the bridge.  The Peer and its bridge should have identical
80d0825bca7fe65beaee391d30da42e937db621564Steve Block    // lifetimes.
81ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    class Peer : public WebSocketChannelClient {
82ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        WTF_MAKE_NONCOPYABLE(Peer); WTF_MAKE_FAST_ALLOCATED;
83d0825bca7fe65beaee391d30da42e937db621564Steve Block    public:
84d0825bca7fe65beaee391d30da42e937db621564Steve Block        static Peer* create(RefPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper, WorkerLoaderProxy& loaderProxy, ScriptExecutionContext* context, const String& taskMode, const KURL& url, const String& protocol)
85d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
86d0825bca7fe65beaee391d30da42e937db621564Steve Block            return new Peer(clientWrapper, loaderProxy, context, taskMode, url, protocol);
87d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
88d0825bca7fe65beaee391d30da42e937db621564Steve Block        ~Peer();
89d0825bca7fe65beaee391d30da42e937db621564Steve Block
90d0825bca7fe65beaee391d30da42e937db621564Steve Block        void connect();
91d0825bca7fe65beaee391d30da42e937db621564Steve Block        void send(const String& message);
92d0825bca7fe65beaee391d30da42e937db621564Steve Block        void bufferedAmount();
93d0825bca7fe65beaee391d30da42e937db621564Steve Block        void close();
94d0825bca7fe65beaee391d30da42e937db621564Steve Block        void disconnect();
956c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        void suspend();
966c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        void resume();
97d0825bca7fe65beaee391d30da42e937db621564Steve Block
98d0825bca7fe65beaee391d30da42e937db621564Steve Block        virtual void didConnect();
99d0825bca7fe65beaee391d30da42e937db621564Steve Block        virtual void didReceiveMessage(const String& message);
1008a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        virtual void didClose(unsigned long unhandledBufferedAmount);
101d0825bca7fe65beaee391d30da42e937db621564Steve Block
102d0825bca7fe65beaee391d30da42e937db621564Steve Block    private:
103d0825bca7fe65beaee391d30da42e937db621564Steve Block        Peer(RefPtr<ThreadableWebSocketChannelClientWrapper>, WorkerLoaderProxy&, ScriptExecutionContext*, const String& taskMode, const KURL&, const String& protocol);
104d0825bca7fe65beaee391d30da42e937db621564Steve Block
105d0825bca7fe65beaee391d30da42e937db621564Steve Block        RefPtr<ThreadableWebSocketChannelClientWrapper> m_workerClientWrapper;
106d0825bca7fe65beaee391d30da42e937db621564Steve Block        WorkerLoaderProxy& m_loaderProxy;
107d0825bca7fe65beaee391d30da42e937db621564Steve Block        RefPtr<ThreadableWebSocketChannel> m_mainWebSocketChannel;
108d0825bca7fe65beaee391d30da42e937db621564Steve Block        String m_taskMode;
109d0825bca7fe65beaee391d30da42e937db621564Steve Block    };
110d0825bca7fe65beaee391d30da42e937db621564Steve Block
111d0825bca7fe65beaee391d30da42e937db621564Steve Block    // Bridge for Peer.  Running on the worker thread.
112d0825bca7fe65beaee391d30da42e937db621564Steve Block    class Bridge : public RefCounted<Bridge> {
113d0825bca7fe65beaee391d30da42e937db621564Steve Block    public:
114dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        static PassRefPtr<Bridge> create(PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassRefPtr<WorkerContext> workerContext, const String& taskMode, const KURL& url, const String& protocol)
115dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        {
116dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return adoptRef(new Bridge(workerClientWrapper, workerContext, taskMode, url, protocol));
117dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
118d0825bca7fe65beaee391d30da42e937db621564Steve Block        ~Bridge();
119d0825bca7fe65beaee391d30da42e937db621564Steve Block        void connect();
120d0825bca7fe65beaee391d30da42e937db621564Steve Block        bool send(const String& message);
121d0825bca7fe65beaee391d30da42e937db621564Steve Block        unsigned long bufferedAmount();
122d0825bca7fe65beaee391d30da42e937db621564Steve Block        void close();
123d0825bca7fe65beaee391d30da42e937db621564Steve Block        void disconnect();
1246c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        void suspend();
1256c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        void resume();
126d0825bca7fe65beaee391d30da42e937db621564Steve Block
127d0825bca7fe65beaee391d30da42e937db621564Steve Block        using RefCounted<Bridge>::ref;
128d0825bca7fe65beaee391d30da42e937db621564Steve Block        using RefCounted<Bridge>::deref;
129d0825bca7fe65beaee391d30da42e937db621564Steve Block
130d0825bca7fe65beaee391d30da42e937db621564Steve Block    private:
131dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper>, PassRefPtr<WorkerContext>, const String& taskMode, const KURL&, const String& protocol);
132dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
133d0825bca7fe65beaee391d30da42e937db621564Steve Block        static void setWebSocketChannel(ScriptExecutionContext*, Bridge* thisPtr, Peer*, RefPtr<ThreadableWebSocketChannelClientWrapper>);
134d0825bca7fe65beaee391d30da42e937db621564Steve Block
135d0825bca7fe65beaee391d30da42e937db621564Steve Block        // Executed on the main thread to create a Peer for this bridge.
136d0825bca7fe65beaee391d30da42e937db621564Steve Block        static void mainThreadCreateWebSocketChannel(ScriptExecutionContext*, Bridge* thisPtr, RefPtr<ThreadableWebSocketChannelClientWrapper>, const String& taskMode, const KURL&, const String& protocol);
137d0825bca7fe65beaee391d30da42e937db621564Steve Block
138d0825bca7fe65beaee391d30da42e937db621564Steve Block        // Executed on the worker context's thread.
139d0825bca7fe65beaee391d30da42e937db621564Steve Block        void clearClientWrapper();
140d0825bca7fe65beaee391d30da42e937db621564Steve Block
141d0825bca7fe65beaee391d30da42e937db621564Steve Block        void setMethodNotCompleted();
142d0825bca7fe65beaee391d30da42e937db621564Steve Block        void waitForMethodCompletion();
143d0825bca7fe65beaee391d30da42e937db621564Steve Block
144d0825bca7fe65beaee391d30da42e937db621564Steve Block        RefPtr<ThreadableWebSocketChannelClientWrapper> m_workerClientWrapper;
145d0825bca7fe65beaee391d30da42e937db621564Steve Block        RefPtr<WorkerContext> m_workerContext;
146d0825bca7fe65beaee391d30da42e937db621564Steve Block        WorkerLoaderProxy& m_loaderProxy;
147d0825bca7fe65beaee391d30da42e937db621564Steve Block        String m_taskMode;
148d0825bca7fe65beaee391d30da42e937db621564Steve Block        Peer* m_peer;
149d0825bca7fe65beaee391d30da42e937db621564Steve Block    };
150d0825bca7fe65beaee391d30da42e937db621564Steve Block
151d0825bca7fe65beaee391d30da42e937db621564Steve Block    WorkerThreadableWebSocketChannel(WorkerContext*, WebSocketChannelClient*, const String& taskMode, const KURL&, const String& protocol);
152d0825bca7fe65beaee391d30da42e937db621564Steve Block
153d0825bca7fe65beaee391d30da42e937db621564Steve Block    static void mainThreadConnect(ScriptExecutionContext*, Peer*);
154d0825bca7fe65beaee391d30da42e937db621564Steve Block    static void mainThreadSend(ScriptExecutionContext*, Peer*, const String& message);
155d0825bca7fe65beaee391d30da42e937db621564Steve Block    static void mainThreadBufferedAmount(ScriptExecutionContext*, Peer*);
156d0825bca7fe65beaee391d30da42e937db621564Steve Block    static void mainThreadClose(ScriptExecutionContext*, Peer*);
157d0825bca7fe65beaee391d30da42e937db621564Steve Block    static void mainThreadDestroy(ScriptExecutionContext*, Peer*);
1586c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    static void mainThreadSuspend(ScriptExecutionContext*, Peer*);
1596c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    static void mainThreadResume(ScriptExecutionContext*, Peer*);
160d0825bca7fe65beaee391d30da42e937db621564Steve Block
161d0825bca7fe65beaee391d30da42e937db621564Steve Block    RefPtr<WorkerContext> m_workerContext;
162d0825bca7fe65beaee391d30da42e937db621564Steve Block    RefPtr<ThreadableWebSocketChannelClientWrapper> m_workerClientWrapper;
163d0825bca7fe65beaee391d30da42e937db621564Steve Block    RefPtr<Bridge> m_bridge;
164d0825bca7fe65beaee391d30da42e937db621564Steve Block};
165d0825bca7fe65beaee391d30da42e937db621564Steve Block
166d0825bca7fe65beaee391d30da42e937db621564Steve Block} // namespace WebCore
167d0825bca7fe65beaee391d30da42e937db621564Steve Block
168d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif // ENABLE(WEB_SOCKETS)
169d0825bca7fe65beaee391d30da42e937db621564Steve Block
170d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif // WorkerThreadableWebSocketChannel_h
171