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, 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 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 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |