Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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, WorkerThread* workerThread) |
| 181 : m_bridge(bridge) | 181 : WorkerThreadLifecycleObserver(workerThread) |
| 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 ASSERT(!isMainThread()); |
| 187 } | 188 } |
| 188 | 189 |
| 189 Peer::~Peer() | 190 Peer::~Peer() |
| 190 { | 191 { |
| 191 ASSERT(!isMainThread()); | 192 ASSERT(!isMainThread()); |
| 192 } | 193 } |
| 193 | 194 |
| 194 void Peer::initialize(PassOwnPtr<SourceLocation> location, ExecutionContext* con text) | 195 void Peer::initialize(PassOwnPtr<SourceLocation> location, ExecutionContext* con text) |
| 195 { | 196 { |
| 196 ASSERT(isMainThread()); | 197 ASSERT(isMainThread()); |
| 197 Document* document = toDocument(context); | 198 if (!isWorkerThreadTerminated()) { |
| 198 m_mainWebSocketChannel = DocumentWebSocketChannel::create(document, this, st d::move(location)); | 199 Document* document = toDocument(context); |
| 200 m_mainWebSocketChannel = DocumentWebSocketChannel::create(document, this , std::move(location)); | |
| 201 } | |
| 199 m_syncHelper->signalWorkerThread(); | 202 m_syncHelper->signalWorkerThread(); |
| 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 { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 } | |
| 371 | |
| 360 DEFINE_TRACE(Peer) | 372 DEFINE_TRACE(Peer) |
| 361 { | 373 { |
| 362 visitor->trace(m_bridge); | 374 visitor->trace(m_bridge); |
| 363 visitor->trace(m_mainWebSocketChannel); | 375 visitor->trace(m_mainWebSocketChannel); |
| 364 visitor->trace(m_syncHelper); | 376 visitor->trace(m_syncHelper); |
| 365 WebSocketChannelClient::trace(visitor); | 377 WebSocketChannelClient::trace(visitor); |
| 378 WorkerThreadLifecycleObserver::trace(visitor); | |
| 366 } | 379 } |
| 367 | 380 |
| 368 Bridge::Bridge(WebSocketChannelClient* client, WorkerGlobalScope& workerGlobalSc ope) | 381 Bridge::Bridge(WebSocketChannelClient* client, WorkerGlobalScope& workerGlobalSc ope) |
| 369 : m_client(client) | 382 : m_client(client) |
| 370 , m_workerGlobalScope(workerGlobalScope) | 383 , m_workerGlobalScope(workerGlobalScope) |
| 371 , m_loaderProxy(m_workerGlobalScope->thread()->workerLoaderProxy()) | 384 , m_loaderProxy(m_workerGlobalScope->thread()->workerLoaderProxy()) |
| 372 , m_syncHelper(WebSocketChannelSyncHelper::create(adoptPtr(new WaitableEvent ()))) | 385 , m_syncHelper(WebSocketChannelSyncHelper::create(adoptPtr(new WaitableEvent ()))) |
| 373 , m_peer(new Peer(this, m_loaderProxy, m_syncHelper)) | 386 , m_peer(new Peer(this, m_loaderProxy, m_syncHelper, m_workerGlobalScope->th read())) |
| 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 |
| 382 void Bridge::initialize(PassOwnPtr<SourceLocation> location) | 395 void Bridge::initialize(PassOwnPtr<SourceLocation> location) |
| 383 { | 396 { |
| 397 // TODO(nhiroki): Stop waiting for completion of the task on the main | |
| 398 // thread and make this function async instead. This wait was necessary to | |
| 399 // prevent worker thread shutdown during initialization on the main thread. | |
| 400 // If it happens, the main thread may retain dangling pointers to objects on | |
| 401 // the worker thread. However, in the current implementation, the shutdown | |
| 402 // sequence always goes through the main thread and gives a chance to | |
| 403 // release pointers before they dangle. See Peer::contextDestroyed. | |
| 384 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::initialize, wrapCr ossThreadPersistent(m_peer.get()), passed(std::move(location))))) { | 404 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::initialize, wrapCr ossThreadPersistent(m_peer.get()), passed(std::move(location))))) { |
| 385 // The worker thread has been signalled to shutdown before method comple tion. | 405 // The worker thread has been signalled to shutdown before method comple tion. |
| 386 disconnect(); | 406 disconnect(); |
| 387 } | 407 } |
| 388 } | 408 } |
| 389 | 409 |
| 390 bool Bridge::connect(const KURL& url, const String& protocol) | 410 bool Bridge::connect(const KURL& url, const String& protocol) |
| 391 { | 411 { |
| 392 if (!m_peer) | 412 if (!m_peer) |
| 393 return false; | 413 return false; |
| 394 | 414 |
| 415 // TODO(nhiroki): Stop waiting for completion of the task on the main thread | |
| 416 // and make this function async instead. See a comment on Bridge::initialize | |
| 417 // 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.
| |
| 395 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::connect, wrapCross ThreadPersistent(m_peer.get()), url, protocol))) | 418 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::connect, wrapCross ThreadPersistent(m_peer.get()), url, protocol))) |
| 396 return false; | 419 return false; |
| 397 | 420 |
| 398 return m_syncHelper->connectRequestResult(); | 421 return m_syncHelper->connectRequestResult(); |
| 399 } | 422 } |
| 400 | 423 |
| 401 void Bridge::send(const CString& message) | 424 void Bridge::send(const CString& message) |
| 402 { | 425 { |
| 403 ASSERT(m_peer); | 426 ASSERT(m_peer); |
| 404 OwnPtr<Vector<char>> data = adoptPtr(new Vector<char>(message.length())); | 427 OwnPtr<Vector<char>> data = adoptPtr(new Vector<char>(message.length())); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 435 { | 458 { |
| 436 ASSERT(m_peer); | 459 ASSERT(m_peer); |
| 437 m_loaderProxy->postTaskToLoader(createCrossThreadTask(&Peer::fail, wrapCross ThreadPersistent(m_peer.get()), reason, level, passed(std::move(location)))); | 460 m_loaderProxy->postTaskToLoader(createCrossThreadTask(&Peer::fail, wrapCross ThreadPersistent(m_peer.get()), reason, level, passed(std::move(location)))); |
| 438 } | 461 } |
| 439 | 462 |
| 440 void Bridge::disconnect() | 463 void Bridge::disconnect() |
| 441 { | 464 { |
| 442 if (!m_peer) | 465 if (!m_peer) |
| 443 return; | 466 return; |
| 444 | 467 |
| 468 // TODO(nhiroki): Stop waiting for completion of the task on the main thread | |
| 469 // and make this function async instead. See a comment on Bridge::initialize | |
| 470 // for more details. | |
| 445 waitForMethodCompletion(createCrossThreadTask(&Peer::disconnect, wrapCrossTh readPersistent(m_peer.get()))); | 471 waitForMethodCompletion(createCrossThreadTask(&Peer::disconnect, wrapCrossTh readPersistent(m_peer.get()))); |
| 446 // Here |m_peer| is detached from the main thread and we can delete it. | 472 // Here |m_peer| is detached from the main thread and we can delete it. |
| 447 | 473 |
| 448 m_client = nullptr; | 474 m_client = nullptr; |
| 449 m_peer = nullptr; | 475 m_peer = nullptr; |
| 450 m_syncHelper = nullptr; | 476 m_syncHelper = nullptr; |
| 451 // We won't use this any more. | 477 // We won't use this any more. |
| 452 m_workerGlobalScope.clear(); | 478 m_workerGlobalScope.clear(); |
| 453 } | 479 } |
| 454 | 480 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 471 | 497 |
| 472 DEFINE_TRACE(Bridge) | 498 DEFINE_TRACE(Bridge) |
| 473 { | 499 { |
| 474 visitor->trace(m_client); | 500 visitor->trace(m_client); |
| 475 visitor->trace(m_workerGlobalScope); | 501 visitor->trace(m_workerGlobalScope); |
| 476 visitor->trace(m_syncHelper); | 502 visitor->trace(m_syncHelper); |
| 477 visitor->trace(m_peer); | 503 visitor->trace(m_peer); |
| 478 } | 504 } |
| 479 | 505 |
| 480 } // namespace blink | 506 } // namespace blink |
| OLD | NEW |