Chromium Code Reviews| Index: Source/modules/websockets/WorkerThreadableWebSocketChannel.cpp |
| diff --git a/Source/modules/websockets/WorkerThreadableWebSocketChannel.cpp b/Source/modules/websockets/WorkerThreadableWebSocketChannel.cpp |
| index ccd5fcc111119a4a7322c0c6885f300cd99a2fe7..cd6c3213939c1ad5150fcd0233eef16b9e2bec8a 100644 |
| --- a/Source/modules/websockets/WorkerThreadableWebSocketChannel.cpp |
| +++ b/Source/modules/websockets/WorkerThreadableWebSocketChannel.cpp |
| @@ -120,10 +120,9 @@ private: |
| unsigned long m_bufferedAmount; |
| }; |
| -WorkerThreadableWebSocketChannel::WorkerThreadableWebSocketChannel(WorkerGlobalScope& context, WebSocketChannelClient* client, const String& sourceURL, unsigned lineNumber) |
| - : m_workerGlobalScope(context) |
| - , m_workerClientWrapper(ThreadableWebSocketChannelClientWrapper::create(client)) |
| - , m_bridge(Bridge::create(m_workerClientWrapper, m_workerGlobalScope)) |
| +WorkerThreadableWebSocketChannel::WorkerThreadableWebSocketChannel(WorkerGlobalScope& workerGlobalScope, WebSocketChannelClient* client, const String& sourceURL, unsigned lineNumber) |
| + : m_workerClientWrapper(ThreadableWebSocketChannelClientWrapper::create(client)) |
| + , m_bridge(Bridge::create(m_workerClientWrapper, workerGlobalScope)) |
| , m_sourceURLAtConnection(sourceURL) |
| , m_lineNumberAtConnection(lineNumber) |
| { |
| @@ -457,7 +456,7 @@ void WorkerThreadableWebSocketChannel::Peer::didReceiveMessageError() |
| m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidReceiveMessageError, m_workerClientWrapper)); |
| } |
| -WorkerThreadableWebSocketChannel::Bridge::Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassRefPtrWillBeRawPtr<WorkerGlobalScope> workerGlobalScope) |
| +WorkerThreadableWebSocketChannel::Bridge::Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, WorkerGlobalScope& workerGlobalScope) |
| : m_workerClientWrapper(workerClientWrapper) |
| , m_workerGlobalScope(workerGlobalScope) |
| , m_loaderProxy(m_workerGlobalScope->thread()->workerLoaderProxy()) |
| @@ -490,71 +489,87 @@ void WorkerThreadableWebSocketChannel::Bridge::initialize(const String& sourceUR |
| bool WorkerThreadableWebSocketChannel::Bridge::connect(const KURL& url, const String& protocol) |
| { |
| - if (!m_workerGlobalScope) |
| + if (hasTerminatedPeer()) |
| return false; |
| - ASSERT(m_syncHelper); |
| - m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::connect, m_peer, url.copy(), protocol.isolatedCopy()))); |
| + |
| RefPtr<Bridge> protect(this); |
|
yhirano
2014/05/07 08:05:18
Can you tell me why this move is needed? I think p
tyoshino (SeeGerritForStatus)
2014/05/08 05:03:00
As discussed offline, it looks we no longer need t
|
| - waitForMethodCompletion(); |
| + m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::connect, m_peer, url.copy(), protocol.isolatedCopy()))); |
| + if (!waitForMethodCompletion()) |
|
yhirano
2014/05/07 08:05:18
[optional] We could have postTaskAndWait for this
tyoshino (SeeGerritForStatus)
2014/05/08 05:03:00
Done.
|
| + return false; |
| + |
| return m_syncHelper->connectRequestResult(); |
| } |
| WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const String& message) |
| { |
| - if (!m_workerGlobalScope) |
| + if (hasTerminatedPeer()) |
| return WebSocketChannel::SendFail; |
| - ASSERT(m_syncHelper); |
| - m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::send, m_peer, message.isolatedCopy()))); |
| + |
| RefPtr<Bridge> protect(this); |
| - waitForMethodCompletion(); |
| + m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::send, m_peer, message.isolatedCopy()))); |
| + if (!waitForMethodCompletion()) |
| + return WebSocketChannel::SendFail; |
| + |
| return m_syncHelper->sendRequestResult(); |
| } |
| WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength) |
| { |
| - if (!m_workerGlobalScope) |
| + if (hasTerminatedPeer()) |
| return WebSocketChannel::SendFail; |
| - ASSERT(m_syncHelper); |
| + |
| // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>. |
| OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(byteLength)); |
| if (binaryData.byteLength()) |
| memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteOffset, byteLength); |
| - m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::sendArrayBuffer, m_peer, data.release()))); |
| RefPtr<Bridge> protect(this); |
| - waitForMethodCompletion(); |
| + m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::sendArrayBuffer, m_peer, data.release()))); |
| + if (!waitForMethodCompletion()) |
| + return WebSocketChannel::SendFail; |
| + |
| return m_syncHelper->sendRequestResult(); |
| } |
| WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(PassRefPtr<BlobDataHandle> data) |
| { |
| - if (!m_workerGlobalScope) |
| + if (hasTerminatedPeer()) |
| return WebSocketChannel::SendFail; |
| - ASSERT(m_syncHelper); |
| - m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::sendBlob, m_peer, data))); |
| + |
| RefPtr<Bridge> protect(this); |
| - waitForMethodCompletion(); |
| + m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::sendBlob, m_peer, data))); |
| + if (!waitForMethodCompletion()) |
| + return WebSocketChannel::SendFail; |
| + |
| return m_syncHelper->sendRequestResult(); |
| } |
| unsigned long WorkerThreadableWebSocketChannel::Bridge::bufferedAmount() |
| { |
| - if (!m_workerGlobalScope) |
| + if (hasTerminatedPeer()) |
| return 0; |
| - ASSERT(m_syncHelper); |
| - m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::bufferedAmount, m_peer))); |
| + |
| RefPtr<Bridge> protect(this); |
| - waitForMethodCompletion(); |
| + m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::bufferedAmount, m_peer))); |
| + if (!waitForMethodCompletion()) |
| + return 0; |
| + |
| return m_syncHelper->bufferedAmount(); |
| } |
| void WorkerThreadableWebSocketChannel::Bridge::close(int code, const String& reason) |
| { |
| + if (hasTerminatedPeer()) |
| + return; |
| + |
| m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::close, m_peer, code, reason.isolatedCopy()))); |
| } |
| void WorkerThreadableWebSocketChannel::Bridge::fail(const String& reason, MessageLevel level, const String& sourceURL, unsigned lineNumber) |
| { |
| + if (hasTerminatedPeer()) |
| + return; |
| + |
| m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::fail, m_peer, reason.isolatedCopy(), level, sourceURL.isolatedCopy(), lineNumber))); |
| } |
| @@ -566,11 +581,17 @@ void WorkerThreadableWebSocketChannel::Bridge::disconnect() |
| void WorkerThreadableWebSocketChannel::Bridge::suspend() |
| { |
| + if (hasTerminatedPeer()) |
| + return; |
| + |
| m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::suspend, m_peer))); |
| } |
| void WorkerThreadableWebSocketChannel::Bridge::resume() |
| { |
| + if (hasTerminatedPeer()) |
| + return; |
| + |
| m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::resume, m_peer))); |
| } |
| @@ -583,8 +604,8 @@ void WorkerThreadableWebSocketChannel::Bridge::clearClientWrapper() |
| // which causes the bridge to get disconnected from the WebSocket and deleted if there is no other reference. |
| bool WorkerThreadableWebSocketChannel::Bridge::waitForMethodCompletion() |
| { |
| - if (!m_syncHelper) |
| - return true; |
| + ASSERT(m_workerGlobalScope); |
| + ASSERT(m_syncHelper); |
| blink::WebWaitableEvent* shutdownEvent = m_workerGlobalScope->thread()->shutdownEvent(); |
| Vector<blink::WebWaitableEvent*> events; |
| @@ -599,8 +620,12 @@ bool WorkerThreadableWebSocketChannel::Bridge::waitForMethodCompletion() |
| void WorkerThreadableWebSocketChannel::Bridge::terminatePeer() |
| { |
| m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::destroy, m_peer))); |
| - m_workerGlobalScope = nullptr; |
| + // Peer::destroy() deletes m_peer and then m_syncHelper will be released. |
| + // We must not touch m_syncHelper any more. |
| m_syncHelper = 0; |
| + |
| + // We won't use this any more. |
| + m_workerGlobalScope = nullptr; |
| } |
| } // namespace WebCore |