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

Side by Side 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: update implementation comments Created 4 years, 6 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 m_bridge->disconnect(); 170 m_bridge->disconnect();
171 m_bridge.clear(); 171 m_bridge.clear();
172 } 172 }
173 173
174 DEFINE_TRACE(WorkerWebSocketChannel) 174 DEFINE_TRACE(WorkerWebSocketChannel)
175 { 175 {
176 visitor->trace(m_bridge); 176 visitor->trace(m_bridge);
177 WebSocketChannel::trace(visitor); 177 WebSocketChannel::trace(visitor);
178 } 178 }
179 179
180 Peer::Peer(Bridge* bridge, PassRefPtr<WorkerLoaderProxy> loaderProxy, WebSocketC hannelSyncHelper* syncHelper) 180 Peer::Peer(Bridge* bridge, PassRefPtr<WorkerLoaderProxy> loaderProxy, WebSocketC hannelSyncHelper* syncHelper, WorkerThreadContext* workerThreadContext)
181 : m_bridge(bridge) 181 : WorkerThreadLifecycleObserver(workerThreadContext)
182 , m_bridge(bridge)
182 , m_loaderProxy(loaderProxy) 183 , m_loaderProxy(loaderProxy)
183 , m_mainWebSocketChannel(nullptr) 184 , m_mainWebSocketChannel(nullptr)
184 , m_syncHelper(syncHelper) 185 , m_syncHelper(syncHelper)
185 { 186 {
186 ASSERT(!isMainThread()); 187 DCHECK(isMainThread());
187 } 188 }
188 189
189 Peer::~Peer() 190 Peer::~Peer()
190 { 191 {
191 ASSERT(!isMainThread()); 192 DCHECK(isMainThread());
192 } 193 }
193 194
194 void Peer::initialize(PassOwnPtr<SourceLocation> location, ExecutionContext* con text) 195 bool Peer::initialize(PassOwnPtr<SourceLocation> location, ExecutionContext* con text)
195 { 196 {
196 ASSERT(isMainThread()); 197 ASSERT(isMainThread());
198 if (wasContextDestroyedBeforeObserverCreation())
199 return false;
197 Document* document = toDocument(context); 200 Document* document = toDocument(context);
198 m_mainWebSocketChannel = DocumentWebSocketChannel::create(document, this, st d::move(location)); 201 m_mainWebSocketChannel = DocumentWebSocketChannel::create(document, this, st d::move(location));
199 m_syncHelper->signalWorkerThread(); 202 return true;
200 } 203 }
201 204
202 void Peer::connect(const KURL& url, const String& protocol) 205 void Peer::connect(const KURL& url, const String& protocol)
203 { 206 {
204 ASSERT(isMainThread()); 207 ASSERT(isMainThread());
205 ASSERT(m_syncHelper); 208 ASSERT(m_syncHelper);
206 if (!m_mainWebSocketChannel) { 209 if (!m_mainWebSocketChannel) {
207 m_syncHelper->setConnectRequestResult(false); 210 m_syncHelper->setConnectRequestResult(false);
208 } else { 211 } else {
209 bool connectRequestResult = m_mainWebSocketChannel->connect(url, protoco l); 212 bool connectRequestResult = m_mainWebSocketChannel->connect(url, protoco l);
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 if (bridge->client()) 353 if (bridge->client())
351 bridge->client()->didError(); 354 bridge->client()->didError();
352 } 355 }
353 356
354 void Peer::didError() 357 void Peer::didError()
355 { 358 {
356 ASSERT(isMainThread()); 359 ASSERT(isMainThread());
357 m_loaderProxy->postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlob alScopeDidError, m_bridge)); 360 m_loaderProxy->postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlob alScopeDidError, m_bridge));
358 } 361 }
359 362
363 void Peer::contextDestroyed()
364 {
365 DCHECK(isMainThread());
366 if (m_mainWebSocketChannel) {
367 m_mainWebSocketChannel->disconnect();
368 m_mainWebSocketChannel = nullptr;
369 }
370 m_bridge = nullptr;
371 }
372
360 DEFINE_TRACE(Peer) 373 DEFINE_TRACE(Peer)
361 { 374 {
362 visitor->trace(m_bridge); 375 visitor->trace(m_bridge);
yhirano 2016/06/09 11:36:20 Peer::m_bridge is not Member. Should we keep this?
nhiroki 2016/06/09 13:23:51 Removed.
363 visitor->trace(m_mainWebSocketChannel); 376 visitor->trace(m_mainWebSocketChannel);
364 visitor->trace(m_syncHelper); 377 visitor->trace(m_syncHelper);
365 WebSocketChannelClient::trace(visitor); 378 WebSocketChannelClient::trace(visitor);
379 WorkerThreadLifecycleObserver::trace(visitor);
366 } 380 }
367 381
368 Bridge::Bridge(WebSocketChannelClient* client, WorkerGlobalScope& workerGlobalSc ope) 382 Bridge::Bridge(WebSocketChannelClient* client, WorkerGlobalScope& workerGlobalSc ope)
369 : m_client(client) 383 : m_client(client)
370 , m_workerGlobalScope(workerGlobalScope) 384 , m_workerGlobalScope(workerGlobalScope)
371 , m_loaderProxy(m_workerGlobalScope->thread()->workerLoaderProxy()) 385 , m_loaderProxy(m_workerGlobalScope->thread()->workerLoaderProxy())
372 , m_syncHelper(WebSocketChannelSyncHelper::create(adoptPtr(new WaitableEvent ()))) 386 , m_syncHelper(WebSocketChannelSyncHelper::create(adoptPtr(new WaitableEvent ())))
373 , m_peer(new Peer(this, m_loaderProxy, m_syncHelper))
374 { 387 {
375 } 388 }
376 389
377 Bridge::~Bridge() 390 Bridge::~Bridge()
378 { 391 {
379 ASSERT(!m_peer); 392 ASSERT(!m_peer);
380 } 393 }
381 394
395 void Bridge::createPeerOnMainThread(PassOwnPtr<SourceLocation> location, WorkerT hreadContext* workerThreadContext, ExecutionContext* context)
396 {
397 DCHECK(isMainThread());
398 DCHECK(!m_peer);
399 Peer* peer = new Peer(this, m_loaderProxy, m_syncHelper, workerThreadContext );
400 if (peer->initialize(std::move(location), context))
401 m_peer = peer;
402 m_syncHelper->signalWorkerThread();
403 }
404
382 void Bridge::initialize(PassOwnPtr<SourceLocation> location) 405 void Bridge::initialize(PassOwnPtr<SourceLocation> location)
383 { 406 {
384 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::initialize, wrapCr ossThreadPersistent(m_peer.get()), passed(std::move(location))))) { 407 // Wait for completion of the task on the main thread because the connection
408 // must synchronously be established (see Bridge::connect).
409 if (!waitForMethodCompletion(createCrossThreadTask(&Bridge::createPeerOnMain Thread, wrapCrossThreadPersistent(this), passed(std::move(location)), wrapCrossT hreadPersistent(m_workerGlobalScope->thread()->workerThreadContext())))) {
385 // The worker thread has been signalled to shutdown before method comple tion. 410 // The worker thread has been signalled to shutdown before method comple tion.
386 disconnect(); 411 disconnect();
387 } 412 }
388 } 413 }
389 414
390 bool Bridge::connect(const KURL& url, const String& protocol) 415 bool Bridge::connect(const KURL& url, const String& protocol)
391 { 416 {
392 if (!m_peer) 417 if (!m_peer)
393 return false; 418 return false;
394 419
420 // Wait for completion of the task on the main thread because the mixed
421 // content check must synchronously be conducted.
395 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::connect, wrapCross ThreadPersistent(m_peer.get()), url, protocol))) 422 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::connect, wrapCross ThreadPersistent(m_peer.get()), url, protocol)))
396 return false; 423 return false;
397 424
398 return m_syncHelper->connectRequestResult(); 425 return m_syncHelper->connectRequestResult();
399 } 426 }
400 427
401 void Bridge::send(const CString& message) 428 void Bridge::send(const CString& message)
402 { 429 {
403 ASSERT(m_peer); 430 ASSERT(m_peer);
404 OwnPtr<Vector<char>> data = adoptPtr(new Vector<char>(message.length())); 431 OwnPtr<Vector<char>> data = adoptPtr(new Vector<char>(message.length()));
(...skipping 30 matching lines...) Expand all
435 { 462 {
436 ASSERT(m_peer); 463 ASSERT(m_peer);
437 m_loaderProxy->postTaskToLoader(createCrossThreadTask(&Peer::fail, wrapCross ThreadPersistent(m_peer.get()), reason, level, passed(std::move(location)))); 464 m_loaderProxy->postTaskToLoader(createCrossThreadTask(&Peer::fail, wrapCross ThreadPersistent(m_peer.get()), reason, level, passed(std::move(location))));
438 } 465 }
439 466
440 void Bridge::disconnect() 467 void Bridge::disconnect()
441 { 468 {
442 if (!m_peer) 469 if (!m_peer)
443 return; 470 return;
444 471
472 // Wait for completion of the task on the main thread to ensure that
473 // |m_peer| does not touch this Bridge object after this point.
445 waitForMethodCompletion(createCrossThreadTask(&Peer::disconnect, wrapCrossTh readPersistent(m_peer.get()))); 474 waitForMethodCompletion(createCrossThreadTask(&Peer::disconnect, wrapCrossTh readPersistent(m_peer.get())));
446 // Here |m_peer| is detached from the main thread and we can delete it.
447 475
448 m_client = nullptr; 476 m_client = nullptr;
449 m_peer = nullptr; 477 m_peer = nullptr;
450 m_syncHelper = nullptr; 478 m_syncHelper = nullptr;
451 // We won't use this any more. 479 // We won't use this any more.
452 m_workerGlobalScope.clear(); 480 m_workerGlobalScope.clear();
453 } 481 }
454 482
455 // Caller of this function should hold a reference to the bridge, because this f unction may call WebSocket::didClose() in the end, 483 // Caller of this function should hold a reference to the bridge, because this f unction may call WebSocket::didClose() in the end,
456 // which causes the bridge to get disconnected from the WebSocket and deleted if there is no other reference. 484 // which causes the bridge to get disconnected from the WebSocket and deleted if there is no other reference.
(...skipping 10 matching lines...) Expand all
467 m_syncHelper->wait(); 495 m_syncHelper->wait();
468 // This is checking whether a shutdown event is fired or not. 496 // This is checking whether a shutdown event is fired or not.
469 return !m_workerGlobalScope->thread()->terminated(); 497 return !m_workerGlobalScope->thread()->terminated();
470 } 498 }
471 499
472 DEFINE_TRACE(Bridge) 500 DEFINE_TRACE(Bridge)
473 { 501 {
474 visitor->trace(m_client); 502 visitor->trace(m_client);
475 visitor->trace(m_workerGlobalScope); 503 visitor->trace(m_workerGlobalScope);
476 visitor->trace(m_syncHelper); 504 visitor->trace(m_syncHelper);
477 visitor->trace(m_peer); 505 visitor->trace(m_peer);
yhirano 2016/06/09 11:36:20 Bridge::m_peer is not Member. Should we keep this?
nhiroki 2016/06/09 13:23:51 Removed.
478 } 506 }
479 507
480 } // namespace blink 508 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698