#include "wtf/RefPtr.h"
#include "wtf/Threading.h"
#include "wtf/Vector.h"
+#include "wtf/WeakPtr.h"
#include "wtf/text/WTFString.h"
+namespace blink {
+class WebWaitableEvent;
+}
+
namespace WebCore {
class BlobDataHandle;
class KURL;
class ExecutionContext;
class ThreadableWebSocketChannelClientWrapper;
+class ThreadableWebSocketChannelSyncHelper;
class WorkerGlobalScope;
class WorkerLoaderProxy;
class WorkerRunLoop;
class WorkerThreadableWebSocketChannel FINAL : public RefCounted<WorkerThreadableWebSocketChannel>, public WebSocketChannel {
WTF_MAKE_FAST_ALLOCATED;
public:
- static PassRefPtr<WebSocketChannel> create(WorkerGlobalScope* workerGlobalScope, WebSocketChannelClient* client, const String& taskMode, const String& sourceURL, unsigned lineNumber)
+ static PassRefPtr<WebSocketChannel> create(WorkerGlobalScope* workerGlobalScope, WebSocketChannelClient* client, const String& sourceURL, unsigned lineNumber)
{
- return adoptRef(new WorkerThreadableWebSocketChannel(workerGlobalScope, client, taskMode, sourceURL, lineNumber));
+ return adoptRef(new WorkerThreadableWebSocketChannel(workerGlobalScope, client, sourceURL, lineNumber));
}
virtual ~WorkerThreadableWebSocketChannel();
virtual void suspend() OVERRIDE;
virtual void resume() OVERRIDE;
- // Generated by the bridge. The Peer and its bridge should have identical
- // lifetimes.
+ // Generated by the bridge. The Peer is destructed by an async call from
+ // Bridge, and may outlive the bridge. All methods of this class must
+ // be called on the main thread.
class Peer FINAL : public WebSocketChannelClient {
WTF_MAKE_NONCOPYABLE(Peer); WTF_MAKE_FAST_ALLOCATED;
public:
+ virtual ~Peer();
+
// sourceURLAtConnection and lineNumberAtConnection parameters may
// be shown when the connection fails.
- static Peer* create(PassRefPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper, WorkerLoaderProxy& loaderProxy, ExecutionContext* context, const String& taskMode, const String& sourceURLAtConnection, unsigned lineNumberAtConnection)
- {
- return new Peer(clientWrapper, loaderProxy, context, taskMode, sourceURLAtConnection, lineNumberAtConnection);
- }
- virtual ~Peer();
+ static void initialize(ExecutionContext*, PassRefPtr<WeakReference<Peer> >, WorkerLoaderProxy*, PassRefPtr<ThreadableWebSocketChannelClientWrapper>, const String& sourceURLAtConnection, unsigned lineNumberAtConnection, PassOwnPtr<ThreadableWebSocketChannelSyncHelper>);
+ void destroy();
void connect(const KURL&, const String& protocol);
void send(const String& message);
- void send(const ArrayBuffer&);
- void send(PassRefPtr<BlobDataHandle>);
+ void sendArrayBuffer(PassOwnPtr<Vector<char> >);
+ void sendBlob(PassRefPtr<BlobDataHandle>);
void bufferedAmount();
void close(int code, const String& reason);
void fail(const String& reason, MessageLevel, const String& sourceURL, unsigned lineNumber);
virtual void didReceiveMessageError() OVERRIDE;
private:
- Peer(PassRefPtr<ThreadableWebSocketChannelClientWrapper>, WorkerLoaderProxy&, ExecutionContext*, const String& taskMode, const String& sourceURL, unsigned lineNumber);
+ Peer(PassRefPtr<WeakReference<Peer> >, PassRefPtr<ThreadableWebSocketChannelClientWrapper>, WorkerLoaderProxy&, ExecutionContext*, const String& sourceURL, unsigned lineNumber, PassOwnPtr<ThreadableWebSocketChannelSyncHelper>);
RefPtr<ThreadableWebSocketChannelClientWrapper> m_workerClientWrapper;
WorkerLoaderProxy& m_loaderProxy;
RefPtr<WebSocketChannel> m_mainWebSocketChannel;
- String m_taskMode;
+ OwnPtr<ThreadableWebSocketChannelSyncHelper> m_syncHelper;
+ WeakPtrFactory<Peer> m_weakFactory;
};
using RefCounted<WorkerThreadableWebSocketChannel>::ref;
// Bridge for Peer. Running on the worker thread.
class Bridge : public RefCounted<Bridge> {
public:
- static PassRefPtr<Bridge> create(PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassRefPtr<WorkerGlobalScope> workerGlobalScope, const String& taskMode)
+ static PassRefPtr<Bridge> create(PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassRefPtr<WorkerGlobalScope> workerGlobalScope)
{
- return adoptRef(new Bridge(workerClientWrapper, workerGlobalScope, taskMode));
+ return adoptRef(new Bridge(workerClientWrapper, workerGlobalScope));
}
~Bridge();
// sourceURLAtConnection and lineNumberAtConnection parameters may
using RefCounted<Bridge>::deref;
private:
- Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper>, PassRefPtr<WorkerGlobalScope>, const String& taskMode);
+ Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper>, PassRefPtr<WorkerGlobalScope>);
static void setWebSocketChannel(ExecutionContext*, Bridge* thisPtr, Peer*, PassRefPtr<ThreadableWebSocketChannelClientWrapper>);
- // Executed on the main thread to create a Peer for this bridge.
- // sourceURL and lineNumber provides the source filename and
- // the line number information at the connection initiation
- // respectively. They may be shown when the connection fails.
- static void mainThreadInitialize(ExecutionContext*, WorkerLoaderProxy*, PassRefPtr<ThreadableWebSocketChannelClientWrapper>, const String& taskMode, const String& sourceURL, unsigned lineNumber);
-
// Executed on the worker context's thread.
void clearClientWrapper();
- void setMethodNotCompleted();
- void waitForMethodCompletion();
+ // Returns false if shutdown event is received before method completion.
+ bool waitForMethodCompletion();
+
+ void terminatePeer();
RefPtr<ThreadableWebSocketChannelClientWrapper> m_workerClientWrapper;
RefPtr<WorkerGlobalScope> m_workerGlobalScope;
WorkerLoaderProxy& m_loaderProxy;
- String m_taskMode;
- Peer* m_peer;
+ ThreadableWebSocketChannelSyncHelper* m_syncHelper;
+ WeakPtr<Peer> m_peer;
};
- WorkerThreadableWebSocketChannel(WorkerGlobalScope*, WebSocketChannelClient*, const String& taskMode, const String& sourceURL, unsigned lineNumber);
-
- static void mainThreadConnect(ExecutionContext*, Peer*, const KURL&, const String& protocol);
- static void mainThreadSend(ExecutionContext*, Peer*, const String& message);
- static void mainThreadSendArrayBuffer(ExecutionContext*, Peer*, PassOwnPtr<Vector<char> >);
- static void mainThreadSendBlob(ExecutionContext*, Peer*, PassRefPtr<BlobDataHandle>);
- static void mainThreadBufferedAmount(ExecutionContext*, Peer*);
- static void mainThreadClose(ExecutionContext*, Peer*, int code, const String& reason);
- static void mainThreadFail(ExecutionContext*, Peer*, const String& reason, MessageLevel, const String& sourceURL, unsigned lineNumber);
- static void mainThreadDestroy(ExecutionContext*, PassOwnPtr<Peer>);
- static void mainThreadSuspend(ExecutionContext*, Peer*);
- static void mainThreadResume(ExecutionContext*, Peer*);
-
- class WorkerGlobalScopeDidInitializeTask;
+ WorkerThreadableWebSocketChannel(WorkerGlobalScope*, WebSocketChannelClient*, const String& sourceURL, unsigned lineNumber);
RefPtr<WorkerGlobalScope> m_workerGlobalScope;
RefPtr<ThreadableWebSocketChannelClientWrapper> m_workerClientWrapper;