Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Unified Diff: third_party/WebKit/Source/modules/websockets/WorkerWebSocketChannel.cpp

Issue 2025783002: Worker: Introduce an observation mechanism for WorkerThread termination (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@delayed_task
Patch Set: maybe fix tests Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/modules/websockets/WorkerWebSocketChannel.cpp
diff --git a/third_party/WebKit/Source/modules/websockets/WorkerWebSocketChannel.cpp b/third_party/WebKit/Source/modules/websockets/WorkerWebSocketChannel.cpp
index 50bba63302bd43bdae2121cf5c017139ff0d082a..2c87092efc5f4453a713f26a2a0d88e15f467830 100644
--- a/third_party/WebKit/Source/modules/websockets/WorkerWebSocketChannel.cpp
+++ b/third_party/WebKit/Source/modules/websockets/WorkerWebSocketChannel.cpp
@@ -177,8 +177,9 @@ DEFINE_TRACE(WorkerWebSocketChannel)
WebSocketChannel::trace(visitor);
}
-Peer::Peer(Bridge* bridge, PassRefPtr<WorkerLoaderProxy> loaderProxy, WebSocketChannelSyncHelper* syncHelper)
- : m_bridge(bridge)
+Peer::Peer(Bridge* bridge, PassRefPtr<WorkerLoaderProxy> loaderProxy, WebSocketChannelSyncHelper* syncHelper, WorkerThread* workerThread)
+ : WorkerThreadLifecycleObserver(workerThread)
+ , m_bridge(bridge)
, m_loaderProxy(loaderProxy)
, m_mainWebSocketChannel(nullptr)
, m_syncHelper(syncHelper)
@@ -194,8 +195,10 @@ Peer::~Peer()
void Peer::initialize(PassOwnPtr<SourceLocation> location, ExecutionContext* context)
{
ASSERT(isMainThread());
- Document* document = toDocument(context);
- m_mainWebSocketChannel = DocumentWebSocketChannel::create(document, this, std::move(location));
+ if (!isWorkerThreadTerminated()) {
+ Document* document = toDocument(context);
+ m_mainWebSocketChannel = DocumentWebSocketChannel::create(document, this, std::move(location));
+ }
m_syncHelper->signalWorkerThread();
}
@@ -357,12 +360,22 @@ void Peer::didError()
m_loaderProxy->postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidError, m_bridge));
}
+void Peer::contextDestroyed()
+{
+ DCHECK(isMainThread());
+ if (m_mainWebSocketChannel) {
+ m_mainWebSocketChannel->disconnect();
+ m_mainWebSocketChannel = nullptr;
+ }
+}
+
DEFINE_TRACE(Peer)
{
visitor->trace(m_bridge);
visitor->trace(m_mainWebSocketChannel);
visitor->trace(m_syncHelper);
WebSocketChannelClient::trace(visitor);
+ WorkerThreadLifecycleObserver::trace(visitor);
}
Bridge::Bridge(WebSocketChannelClient* client, WorkerGlobalScope& workerGlobalScope)
@@ -370,7 +383,7 @@ Bridge::Bridge(WebSocketChannelClient* client, WorkerGlobalScope& workerGlobalSc
, m_workerGlobalScope(workerGlobalScope)
, m_loaderProxy(m_workerGlobalScope->thread()->workerLoaderProxy())
, m_syncHelper(WebSocketChannelSyncHelper::create(adoptPtr(new WaitableEvent())))
- , m_peer(new Peer(this, m_loaderProxy, m_syncHelper))
+ , m_peer(new Peer(this, m_loaderProxy, m_syncHelper, m_workerGlobalScope->thread()))
{
}
@@ -381,6 +394,13 @@ Bridge::~Bridge()
void Bridge::initialize(PassOwnPtr<SourceLocation> location)
{
+ // TODO(nhiroki): Stop waiting for completion of the task on the main
+ // thread and make this function async instead. This wait was necessary to
+ // prevent worker thread shutdown during initialization on the main thread.
+ // If it happens, the main thread may retain dangling pointers to objects on
+ // the worker thread. However, in the current implementation, the shutdown
+ // sequence always goes through the main thread and gives a chance to
+ // release pointers before they dangle. See Peer::contextDestroyed.
if (!waitForMethodCompletion(createCrossThreadTask(&Peer::initialize, wrapCrossThreadPersistent(m_peer.get()), passed(std::move(location))))) {
// The worker thread has been signalled to shutdown before method completion.
disconnect();
@@ -392,6 +412,9 @@ bool Bridge::connect(const KURL& url, const String& protocol)
if (!m_peer)
return false;
+ // TODO(nhiroki): Stop waiting for completion of the task on the main thread
+ // and make this function async instead. See a comment on Bridge::initialize
+ // for more details.
yhirano 2016/06/03 07:40:37 We need to wait here for the synchronous mixed con
nhiroki 2016/06/08 09:17:45 I see. Revised this comment.
if (!waitForMethodCompletion(createCrossThreadTask(&Peer::connect, wrapCrossThreadPersistent(m_peer.get()), url, protocol)))
return false;
@@ -442,6 +465,9 @@ void Bridge::disconnect()
if (!m_peer)
return;
+ // TODO(nhiroki): Stop waiting for completion of the task on the main thread
+ // and make this function async instead. See a comment on Bridge::initialize
+ // for more details.
waitForMethodCompletion(createCrossThreadTask(&Peer::disconnect, wrapCrossThreadPersistent(m_peer.get())));
// Here |m_peer| is detached from the main thread and we can delete it.

Powered by Google App Engine
This is Rietveld 408576698