| Index: Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp
|
| ===================================================================
|
| --- Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp (revision 115611)
|
| +++ Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp (working copy)
|
| @@ -57,6 +57,7 @@
|
| , m_workerClientWrapper(ThreadableWebSocketChannelClientWrapper::create(context, client))
|
| , m_bridge(Bridge::create(m_workerClientWrapper, m_workerContext, taskMode))
|
| {
|
| + m_bridge->initialize();
|
| }
|
|
|
| WorkerThreadableWebSocketChannel::~WorkerThreadableWebSocketChannel()
|
| @@ -344,49 +345,82 @@
|
| m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidClose, m_workerClientWrapper, unhandledBufferedAmount, closingHandshakeCompletion, code, reason), m_taskMode);
|
| }
|
|
|
| -void WorkerThreadableWebSocketChannel::Bridge::setWebSocketChannel(ScriptExecutionContext* context, Bridge* thisPtr, Peer* peer, PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, bool useHixie76Protocol)
|
| +WorkerThreadableWebSocketChannel::Bridge::Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassRefPtr<WorkerContext> workerContext, const String& taskMode)
|
| + : m_workerClientWrapper(workerClientWrapper)
|
| + , m_workerContext(workerContext)
|
| + , m_loaderProxy(m_workerContext->thread()->workerLoaderProxy())
|
| + , m_taskMode(taskMode)
|
| + , m_peer(0)
|
| {
|
| - ASSERT_UNUSED(context, context->isWorkerContext());
|
| - thisPtr->m_peer = peer;
|
| - workerClientWrapper->setUseHixie76Protocol(useHixie76Protocol);
|
| - workerClientWrapper->setSyncMethodDone();
|
| + ASSERT(m_workerClientWrapper.get());
|
| }
|
|
|
| -void WorkerThreadableWebSocketChannel::Bridge::mainThreadCreateWebSocketChannel(ScriptExecutionContext* context, Bridge* thisPtr, PassRefPtr<ThreadableWebSocketChannelClientWrapper> prpClientWrapper, const String& taskMode)
|
| +WorkerThreadableWebSocketChannel::Bridge::~Bridge()
|
| {
|
| + disconnect();
|
| +}
|
| +
|
| +class WorkerContextDidInitializeTask : public ScriptExecutionContext::Task {
|
| +public:
|
| + static PassOwnPtr<ScriptExecutionContext::Task> create(WorkerThreadableWebSocketChannel::Peer* peer,
|
| + PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper,
|
| + bool useHixie76Protocol)
|
| + {
|
| + return adoptPtr(new WorkerContextDidInitializeTask(peer, workerClientWrapper, useHixie76Protocol));
|
| + }
|
| +
|
| + virtual ~WorkerContextDidInitializeTask() { }
|
| + virtual void performTask(ScriptExecutionContext* context) OVERRIDE
|
| + {
|
| + ASSERT_UNUSED(context, context->isWorkerContext());
|
| + m_workerClientWrapper->didCreateWebSocketChannel(m_peer, m_useHixie76Protocol);
|
| + }
|
| + virtual bool isCleanupTask() const OVERRIDE { return true; }
|
| +
|
| +private:
|
| + WorkerContextDidInitializeTask(WorkerThreadableWebSocketChannel::Peer* peer,
|
| + PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper,
|
| + bool useHixie76Protocol)
|
| + : m_peer(peer)
|
| + , m_workerClientWrapper(workerClientWrapper)
|
| + , m_useHixie76Protocol(useHixie76Protocol)
|
| + {
|
| + }
|
| +
|
| + WorkerThreadableWebSocketChannel::Peer* m_peer;
|
| + RefPtr<ThreadableWebSocketChannelClientWrapper> m_workerClientWrapper;
|
| + bool m_useHixie76Protocol;
|
| +};
|
| +
|
| +void WorkerThreadableWebSocketChannel::Bridge::mainThreadInitialize(ScriptExecutionContext* context, WorkerLoaderProxy* loaderProxy, PassRefPtr<ThreadableWebSocketChannelClientWrapper> prpClientWrapper, const String& taskMode)
|
| +{
|
| ASSERT(isMainThread());
|
| ASSERT_UNUSED(context, context->isDocument());
|
|
|
| RefPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper = prpClientWrapper;
|
|
|
| - Peer* peer = Peer::create(clientWrapper, thisPtr->m_loaderProxy, context, taskMode);
|
| - thisPtr->m_loaderProxy.postTaskForModeToWorkerContext(
|
| - createCallbackTask(&Bridge::setWebSocketChannel,
|
| - AllowCrossThreadAccess(thisPtr),
|
| - AllowCrossThreadAccess(peer), clientWrapper, peer->useHixie76Protocol()), taskMode);
|
| + Peer* peer = Peer::create(clientWrapper, *loaderProxy, context, taskMode);
|
| + bool sent = loaderProxy->postTaskForModeToWorkerContext(
|
| + WorkerContextDidInitializeTask::create(peer, clientWrapper, peer->useHixie76Protocol()), taskMode);
|
| + if (!sent) {
|
| + clientWrapper->clearPeer();
|
| + delete peer;
|
| + }
|
| }
|
|
|
| -WorkerThreadableWebSocketChannel::Bridge::Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassRefPtr<WorkerContext> workerContext, const String& taskMode)
|
| - : m_workerClientWrapper(workerClientWrapper)
|
| - , m_workerContext(workerContext)
|
| - , m_loaderProxy(m_workerContext->thread()->workerLoaderProxy())
|
| - , m_taskMode(taskMode)
|
| - , m_peer(0)
|
| +void WorkerThreadableWebSocketChannel::Bridge::initialize()
|
| {
|
| - ASSERT(m_workerClientWrapper.get());
|
| + ASSERT(!m_peer);
|
| setMethodNotCompleted();
|
| + RefPtr<Bridge> protect(this);
|
| m_loaderProxy.postTaskToLoader(
|
| - createCallbackTask(&Bridge::mainThreadCreateWebSocketChannel,
|
| - AllowCrossThreadAccess(this), m_workerClientWrapper, m_taskMode));
|
| + createCallbackTask(&Bridge::mainThreadInitialize,
|
| + AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper, m_taskMode));
|
| waitForMethodCompletion();
|
| - ASSERT(m_peer);
|
| + // m_peer may be null when the nested runloop exited before a peer has created.
|
| + m_peer = m_workerClientWrapper->peer();
|
| }
|
|
|
| -WorkerThreadableWebSocketChannel::Bridge::~Bridge()
|
| -{
|
| - disconnect();
|
| -}
|
| -
|
| void WorkerThreadableWebSocketChannel::mainThreadConnect(ScriptExecutionContext* context, Peer* peer, const KURL& url, const String& protocol)
|
| {
|
| ASSERT(isMainThread());
|
| @@ -399,7 +433,8 @@
|
| void WorkerThreadableWebSocketChannel::Bridge::connect(const KURL& url, const String& protocol)
|
| {
|
| ASSERT(m_workerClientWrapper);
|
| - ASSERT(m_peer);
|
| + if (!m_peer)
|
| + return;
|
| m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadConnect, AllowCrossThreadAccess(m_peer), url, protocol));
|
| }
|
|
|
| @@ -434,9 +469,8 @@
|
|
|
| ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const String& message)
|
| {
|
| - if (!m_workerClientWrapper)
|
| + if (!m_workerClientWrapper || !m_peer)
|
| return ThreadableWebSocketChannel::SendFail;
|
| - ASSERT(m_peer);
|
| setMethodNotCompleted();
|
| m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSend, AllowCrossThreadAccess(m_peer), message));
|
| RefPtr<Bridge> protect(this);
|
| @@ -449,9 +483,8 @@
|
|
|
| ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const ArrayBuffer& binaryData)
|
| {
|
| - if (!m_workerClientWrapper)
|
| + if (!m_workerClientWrapper || !m_peer)
|
| return ThreadableWebSocketChannel::SendFail;
|
| - ASSERT(m_peer);
|
| // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>.
|
| OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(binaryData.byteLength()));
|
| if (binaryData.byteLength())
|
| @@ -468,9 +501,8 @@
|
|
|
| ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const Blob& binaryData)
|
| {
|
| - if (!m_workerClientWrapper)
|
| + if (!m_workerClientWrapper || !m_peer)
|
| return ThreadableWebSocketChannel::SendFail;
|
| - ASSERT(m_peer);
|
| setMethodNotCompleted();
|
| m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSendBlob, AllowCrossThreadAccess(m_peer), binaryData.url(), binaryData.type(), binaryData.size()));
|
| RefPtr<Bridge> protect(this);
|
| @@ -492,9 +524,8 @@
|
|
|
| unsigned long WorkerThreadableWebSocketChannel::Bridge::bufferedAmount()
|
| {
|
| - if (!m_workerClientWrapper)
|
| + if (!m_workerClientWrapper || !m_peer)
|
| return 0;
|
| - ASSERT(m_peer);
|
| setMethodNotCompleted();
|
| m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadBufferedAmount, AllowCrossThreadAccess(m_peer)));
|
| RefPtr<Bridge> protect(this);
|
| @@ -505,7 +536,7 @@
|
| return 0;
|
| }
|
|
|
| -void WorkerThreadableWebSocketChannel::mainThreadClose(ScriptExecutionContext* context, Peer* peer, int code, const String&reason)
|
| +void WorkerThreadableWebSocketChannel::mainThreadClose(ScriptExecutionContext* context, Peer* peer, int code, const String& reason)
|
| {
|
| ASSERT(isMainThread());
|
| ASSERT_UNUSED(context, context->isDocument());
|
| @@ -516,7 +547,8 @@
|
|
|
| void WorkerThreadableWebSocketChannel::Bridge::close(int code, const String& reason)
|
| {
|
| - ASSERT(m_peer);
|
| + if (!m_peer)
|
| + return;
|
| m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadClose, AllowCrossThreadAccess(m_peer), code, reason));
|
| }
|
|
|
| @@ -531,7 +563,8 @@
|
|
|
| void WorkerThreadableWebSocketChannel::Bridge::fail(const String& reason)
|
| {
|
| - ASSERT(m_peer);
|
| + if (!m_peer)
|
| + return;
|
| m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadFail, AllowCrossThreadAccess(m_peer), reason));
|
| }
|
|
|
| @@ -566,7 +599,8 @@
|
|
|
| void WorkerThreadableWebSocketChannel::Bridge::suspend()
|
| {
|
| - ASSERT(m_peer);
|
| + if (!m_peer)
|
| + return;
|
| m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSuspend, AllowCrossThreadAccess(m_peer)));
|
| }
|
|
|
| @@ -581,7 +615,8 @@
|
|
|
| void WorkerThreadableWebSocketChannel::Bridge::resume()
|
| {
|
| - ASSERT(m_peer);
|
| + if (!m_peer)
|
| + return;
|
| m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadResume, AllowCrossThreadAccess(m_peer)));
|
| }
|
|
|
|
|