| 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 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 static void workerGlobalScopeDidConnect(Bridge* bridge, const String& subprotoco
l, const String& extensions, ExecutionContext* context) | 270 static void workerGlobalScopeDidConnect(Bridge* bridge, const String& subprotoco
l, const String& extensions, ExecutionContext* context) |
| 271 { | 271 { |
| 272 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 272 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
| 273 if (bridge && bridge->client()) | 273 if (bridge && bridge->client()) |
| 274 bridge->client()->didConnect(subprotocol, extensions); | 274 bridge->client()->didConnect(subprotocol, extensions); |
| 275 } | 275 } |
| 276 | 276 |
| 277 void Peer::didConnect(const String& subprotocol, const String& extensions) | 277 void Peer::didConnect(const String& subprotocol, const String& extensions) |
| 278 { | 278 { |
| 279 ASSERT(isMainThread()); | 279 ASSERT(isMainThread()); |
| 280 m_loaderProxy->postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlob
alScopeDidConnect, m_bridge, subprotocol, extensions)); | 280 m_loaderProxy->postTaskToWorkerGlobalScope(BLINK_FROM_HERE, createCrossThrea
dTask(&workerGlobalScopeDidConnect, m_bridge, subprotocol, extensions)); |
| 281 } | 281 } |
| 282 | 282 |
| 283 static void workerGlobalScopeDidReceiveTextMessage(Bridge* bridge, const String&
payload, ExecutionContext* context) | 283 static void workerGlobalScopeDidReceiveTextMessage(Bridge* bridge, const String&
payload, ExecutionContext* context) |
| 284 { | 284 { |
| 285 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 285 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
| 286 if (bridge && bridge->client()) | 286 if (bridge && bridge->client()) |
| 287 bridge->client()->didReceiveTextMessage(payload); | 287 bridge->client()->didReceiveTextMessage(payload); |
| 288 } | 288 } |
| 289 | 289 |
| 290 void Peer::didReceiveTextMessage(const String& payload) | 290 void Peer::didReceiveTextMessage(const String& payload) |
| 291 { | 291 { |
| 292 ASSERT(isMainThread()); | 292 ASSERT(isMainThread()); |
| 293 m_loaderProxy->postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlob
alScopeDidReceiveTextMessage, m_bridge, payload)); | 293 m_loaderProxy->postTaskToWorkerGlobalScope(BLINK_FROM_HERE, createCrossThrea
dTask(&workerGlobalScopeDidReceiveTextMessage, m_bridge, payload)); |
| 294 } | 294 } |
| 295 | 295 |
| 296 static void workerGlobalScopeDidReceiveBinaryMessage(Bridge* bridge, std::unique
_ptr<Vector<char>> payload, ExecutionContext* context) | 296 static void workerGlobalScopeDidReceiveBinaryMessage(Bridge* bridge, std::unique
_ptr<Vector<char>> payload, ExecutionContext* context) |
| 297 { | 297 { |
| 298 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 298 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
| 299 if (bridge && bridge->client()) | 299 if (bridge && bridge->client()) |
| 300 bridge->client()->didReceiveBinaryMessage(std::move(payload)); | 300 bridge->client()->didReceiveBinaryMessage(std::move(payload)); |
| 301 } | 301 } |
| 302 | 302 |
| 303 void Peer::didReceiveBinaryMessage(std::unique_ptr<Vector<char>> payload) | 303 void Peer::didReceiveBinaryMessage(std::unique_ptr<Vector<char>> payload) |
| 304 { | 304 { |
| 305 ASSERT(isMainThread()); | 305 ASSERT(isMainThread()); |
| 306 m_loaderProxy->postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlob
alScopeDidReceiveBinaryMessage, m_bridge, passed(std::move(payload)))); | 306 m_loaderProxy->postTaskToWorkerGlobalScope(BLINK_FROM_HERE, createCrossThrea
dTask(&workerGlobalScopeDidReceiveBinaryMessage, m_bridge, passed(std::move(payl
oad)))); |
| 307 } | 307 } |
| 308 | 308 |
| 309 static void workerGlobalScopeDidConsumeBufferedAmount(Bridge* bridge, uint64_t c
onsumed, ExecutionContext* context) | 309 static void workerGlobalScopeDidConsumeBufferedAmount(Bridge* bridge, uint64_t c
onsumed, ExecutionContext* context) |
| 310 { | 310 { |
| 311 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 311 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
| 312 if (bridge && bridge->client()) | 312 if (bridge && bridge->client()) |
| 313 bridge->client()->didConsumeBufferedAmount(consumed); | 313 bridge->client()->didConsumeBufferedAmount(consumed); |
| 314 } | 314 } |
| 315 | 315 |
| 316 void Peer::didConsumeBufferedAmount(uint64_t consumed) | 316 void Peer::didConsumeBufferedAmount(uint64_t consumed) |
| 317 { | 317 { |
| 318 ASSERT(isMainThread()); | 318 ASSERT(isMainThread()); |
| 319 m_loaderProxy->postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlob
alScopeDidConsumeBufferedAmount, m_bridge, consumed)); | 319 m_loaderProxy->postTaskToWorkerGlobalScope(BLINK_FROM_HERE, createCrossThrea
dTask(&workerGlobalScopeDidConsumeBufferedAmount, m_bridge, consumed)); |
| 320 } | 320 } |
| 321 | 321 |
| 322 static void workerGlobalScopeDidStartClosingHandshake(Bridge* bridge, ExecutionC
ontext* context) | 322 static void workerGlobalScopeDidStartClosingHandshake(Bridge* bridge, ExecutionC
ontext* context) |
| 323 { | 323 { |
| 324 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 324 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
| 325 if (bridge && bridge->client()) | 325 if (bridge && bridge->client()) |
| 326 bridge->client()->didStartClosingHandshake(); | 326 bridge->client()->didStartClosingHandshake(); |
| 327 } | 327 } |
| 328 | 328 |
| 329 void Peer::didStartClosingHandshake() | 329 void Peer::didStartClosingHandshake() |
| 330 { | 330 { |
| 331 ASSERT(isMainThread()); | 331 ASSERT(isMainThread()); |
| 332 m_loaderProxy->postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlob
alScopeDidStartClosingHandshake, m_bridge)); | 332 m_loaderProxy->postTaskToWorkerGlobalScope(BLINK_FROM_HERE, createCrossThrea
dTask(&workerGlobalScopeDidStartClosingHandshake, m_bridge)); |
| 333 } | 333 } |
| 334 | 334 |
| 335 static void workerGlobalScopeDidClose(Bridge* bridge, WebSocketChannelClient::Cl
osingHandshakeCompletionStatus closingHandshakeCompletion, unsigned short code,
const String& reason, ExecutionContext* context) | 335 static void workerGlobalScopeDidClose(Bridge* bridge, WebSocketChannelClient::Cl
osingHandshakeCompletionStatus closingHandshakeCompletion, unsigned short code,
const String& reason, ExecutionContext* context) |
| 336 { | 336 { |
| 337 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 337 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
| 338 if (bridge && bridge->client()) | 338 if (bridge && bridge->client()) |
| 339 bridge->client()->didClose(closingHandshakeCompletion, code, reason); | 339 bridge->client()->didClose(closingHandshakeCompletion, code, reason); |
| 340 } | 340 } |
| 341 | 341 |
| 342 void Peer::didClose(ClosingHandshakeCompletionStatus closingHandshakeCompletion,
unsigned short code, const String& reason) | 342 void Peer::didClose(ClosingHandshakeCompletionStatus closingHandshakeCompletion,
unsigned short code, const String& reason) |
| 343 { | 343 { |
| 344 ASSERT(isMainThread()); | 344 ASSERT(isMainThread()); |
| 345 if (m_mainWebSocketChannel) { | 345 if (m_mainWebSocketChannel) { |
| 346 m_mainWebSocketChannel->disconnect(); | 346 m_mainWebSocketChannel->disconnect(); |
| 347 m_mainWebSocketChannel = nullptr; | 347 m_mainWebSocketChannel = nullptr; |
| 348 } | 348 } |
| 349 m_loaderProxy->postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlob
alScopeDidClose, m_bridge, closingHandshakeCompletion, code, reason)); | 349 m_loaderProxy->postTaskToWorkerGlobalScope(BLINK_FROM_HERE, createCrossThrea
dTask(&workerGlobalScopeDidClose, m_bridge, closingHandshakeCompletion, code, re
ason)); |
| 350 } | 350 } |
| 351 | 351 |
| 352 static void workerGlobalScopeDidError(Bridge* bridge, ExecutionContext* context) | 352 static void workerGlobalScopeDidError(Bridge* bridge, ExecutionContext* context) |
| 353 { | 353 { |
| 354 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 354 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
| 355 if (bridge && bridge->client()) | 355 if (bridge && bridge->client()) |
| 356 bridge->client()->didError(); | 356 bridge->client()->didError(); |
| 357 } | 357 } |
| 358 | 358 |
| 359 void Peer::didError() | 359 void Peer::didError() |
| 360 { | 360 { |
| 361 ASSERT(isMainThread()); | 361 ASSERT(isMainThread()); |
| 362 m_loaderProxy->postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlob
alScopeDidError, m_bridge)); | 362 m_loaderProxy->postTaskToWorkerGlobalScope(BLINK_FROM_HERE, createCrossThrea
dTask(&workerGlobalScopeDidError, m_bridge)); |
| 363 } | 363 } |
| 364 | 364 |
| 365 void Peer::contextDestroyed() | 365 void Peer::contextDestroyed() |
| 366 { | 366 { |
| 367 DCHECK(isMainThread()); | 367 DCHECK(isMainThread()); |
| 368 if (m_mainWebSocketChannel) { | 368 if (m_mainWebSocketChannel) { |
| 369 m_mainWebSocketChannel->disconnect(); | 369 m_mainWebSocketChannel->disconnect(); |
| 370 m_mainWebSocketChannel = nullptr; | 370 m_mainWebSocketChannel = nullptr; |
| 371 } | 371 } |
| 372 m_bridge = nullptr; | 372 m_bridge = nullptr; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 400 Peer* peer = new Peer(this, m_loaderProxy, m_syncHelper, workerThreadLifecyc
leContext); | 400 Peer* peer = new Peer(this, m_loaderProxy, m_syncHelper, workerThreadLifecyc
leContext); |
| 401 if (peer->initialize(std::move(location), context)) | 401 if (peer->initialize(std::move(location), context)) |
| 402 m_peer = peer; | 402 m_peer = peer; |
| 403 m_syncHelper->signalWorkerThread(); | 403 m_syncHelper->signalWorkerThread(); |
| 404 } | 404 } |
| 405 | 405 |
| 406 void Bridge::initialize(std::unique_ptr<SourceLocation> location) | 406 void Bridge::initialize(std::unique_ptr<SourceLocation> location) |
| 407 { | 407 { |
| 408 // Wait for completion of the task on the main thread because the connection | 408 // Wait for completion of the task on the main thread because the connection |
| 409 // must synchronously be established (see Bridge::connect). | 409 // must synchronously be established (see Bridge::connect). |
| 410 if (!waitForMethodCompletion(createCrossThreadTask(&Bridge::createPeerOnMain
Thread, wrapCrossThreadPersistent(this), passed(std::move(location)), wrapCrossT
hreadPersistent(m_workerGlobalScope->thread()->getWorkerThreadLifecycleContext()
)))) { | 410 if (!waitForMethodCompletion(BLINK_FROM_HERE, createCrossThreadTask(&Bridge:
:createPeerOnMainThread, wrapCrossThreadPersistent(this), passed(std::move(locat
ion)), wrapCrossThreadPersistent(m_workerGlobalScope->thread()->getWorkerThreadL
ifecycleContext())))) { |
| 411 // The worker thread has been signalled to shutdown before method comple
tion. | 411 // The worker thread has been signalled to shutdown before method comple
tion. |
| 412 disconnect(); | 412 disconnect(); |
| 413 } | 413 } |
| 414 } | 414 } |
| 415 | 415 |
| 416 bool Bridge::connect(const KURL& url, const String& protocol) | 416 bool Bridge::connect(const KURL& url, const String& protocol) |
| 417 { | 417 { |
| 418 if (!m_peer) | 418 if (!m_peer) |
| 419 return false; | 419 return false; |
| 420 | 420 |
| 421 // Wait for completion of the task on the main thread because the mixed | 421 // Wait for completion of the task on the main thread because the mixed |
| 422 // content check must synchronously be conducted. | 422 // content check must synchronously be conducted. |
| 423 if (!waitForMethodCompletion(createCrossThreadTask(&Peer::connect, wrapCross
ThreadPersistent(m_peer.get()), url, protocol))) | 423 if (!waitForMethodCompletion(BLINK_FROM_HERE, createCrossThreadTask(&Peer::c
onnect, wrapCrossThreadPersistent(m_peer.get()), url, protocol))) |
| 424 return false; | 424 return false; |
| 425 | 425 |
| 426 return m_syncHelper->connectRequestResult(); | 426 return m_syncHelper->connectRequestResult(); |
| 427 } | 427 } |
| 428 | 428 |
| 429 void Bridge::send(const CString& message) | 429 void Bridge::send(const CString& message) |
| 430 { | 430 { |
| 431 ASSERT(m_peer); | 431 ASSERT(m_peer); |
| 432 std::unique_ptr<Vector<char>> data = wrapUnique(new Vector<char>(message.len
gth())); | 432 std::unique_ptr<Vector<char>> data = wrapUnique(new Vector<char>(message.len
gth())); |
| 433 if (message.length()) | 433 if (message.length()) |
| 434 memcpy(data->data(), static_cast<const char*>(message.data()), message.l
ength()); | 434 memcpy(data->data(), static_cast<const char*>(message.data()), message.l
ength()); |
| 435 | 435 |
| 436 m_loaderProxy->postTaskToLoader(createCrossThreadTask(&Peer::sendTextAsCharV
ector, wrapCrossThreadPersistent(m_peer.get()), passed(std::move(data)))); | 436 m_loaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&Peer
::sendTextAsCharVector, wrapCrossThreadPersistent(m_peer.get()), passed(std::mov
e(data)))); |
| 437 } | 437 } |
| 438 | 438 |
| 439 void Bridge::send(const DOMArrayBuffer& binaryData, unsigned byteOffset, unsigne
d byteLength) | 439 void Bridge::send(const DOMArrayBuffer& binaryData, unsigned byteOffset, unsigne
d byteLength) |
| 440 { | 440 { |
| 441 ASSERT(m_peer); | 441 ASSERT(m_peer); |
| 442 // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied
into Vector<char>. | 442 // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied
into Vector<char>. |
| 443 std::unique_ptr<Vector<char>> data = wrapUnique(new Vector<char>(byteLength)
); | 443 std::unique_ptr<Vector<char>> data = wrapUnique(new Vector<char>(byteLength)
); |
| 444 if (binaryData.byteLength()) | 444 if (binaryData.byteLength()) |
| 445 memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteO
ffset, byteLength); | 445 memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteO
ffset, byteLength); |
| 446 | 446 |
| 447 m_loaderProxy->postTaskToLoader(createCrossThreadTask(&Peer::sendBinaryAsCha
rVector, wrapCrossThreadPersistent(m_peer.get()), passed(std::move(data)))); | 447 m_loaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&Peer
::sendBinaryAsCharVector, wrapCrossThreadPersistent(m_peer.get()), passed(std::m
ove(data)))); |
| 448 } | 448 } |
| 449 | 449 |
| 450 void Bridge::send(PassRefPtr<BlobDataHandle> data) | 450 void Bridge::send(PassRefPtr<BlobDataHandle> data) |
| 451 { | 451 { |
| 452 ASSERT(m_peer); | 452 ASSERT(m_peer); |
| 453 m_loaderProxy->postTaskToLoader(createCrossThreadTask(&Peer::sendBlob, wrapC
rossThreadPersistent(m_peer.get()), data)); | 453 m_loaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&Peer
::sendBlob, wrapCrossThreadPersistent(m_peer.get()), data)); |
| 454 } | 454 } |
| 455 | 455 |
| 456 void Bridge::close(int code, const String& reason) | 456 void Bridge::close(int code, const String& reason) |
| 457 { | 457 { |
| 458 ASSERT(m_peer); | 458 ASSERT(m_peer); |
| 459 m_loaderProxy->postTaskToLoader(createCrossThreadTask(&Peer::close, wrapCros
sThreadPersistent(m_peer.get()), code, reason)); | 459 m_loaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&Peer
::close, wrapCrossThreadPersistent(m_peer.get()), code, reason)); |
| 460 } | 460 } |
| 461 | 461 |
| 462 void Bridge::fail(const String& reason, MessageLevel level, std::unique_ptr<Sour
ceLocation> location) | 462 void Bridge::fail(const String& reason, MessageLevel level, std::unique_ptr<Sour
ceLocation> location) |
| 463 { | 463 { |
| 464 ASSERT(m_peer); | 464 ASSERT(m_peer); |
| 465 m_loaderProxy->postTaskToLoader(createCrossThreadTask(&Peer::fail, wrapCross
ThreadPersistent(m_peer.get()), reason, level, passed(std::move(location)))); | 465 m_loaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&Peer
::fail, wrapCrossThreadPersistent(m_peer.get()), reason, level, passed(std::move
(location)))); |
| 466 } | 466 } |
| 467 | 467 |
| 468 void Bridge::disconnect() | 468 void Bridge::disconnect() |
| 469 { | 469 { |
| 470 if (!m_peer) | 470 if (!m_peer) |
| 471 return; | 471 return; |
| 472 | 472 |
| 473 // Wait for completion of the task on the main thread to ensure that | 473 // Wait for completion of the task on the main thread to ensure that |
| 474 // |m_peer| does not touch this Bridge object after this point. | 474 // |m_peer| does not touch this Bridge object after this point. |
| 475 waitForMethodCompletion(createCrossThreadTask(&Peer::disconnect, wrapCrossTh
readPersistent(m_peer.get()))); | 475 waitForMethodCompletion(BLINK_FROM_HERE, createCrossThreadTask(&Peer::discon
nect, wrapCrossThreadPersistent(m_peer.get()))); |
| 476 | 476 |
| 477 m_client = nullptr; | 477 m_client = nullptr; |
| 478 m_peer = nullptr; | 478 m_peer = nullptr; |
| 479 m_syncHelper = nullptr; | 479 m_syncHelper = nullptr; |
| 480 // We won't use this any more. | 480 // We won't use this any more. |
| 481 m_workerGlobalScope.clear(); | 481 m_workerGlobalScope.clear(); |
| 482 } | 482 } |
| 483 | 483 |
| 484 // Caller of this function should hold a reference to the bridge, because this f
unction may call WebSocket::didClose() in the end, | 484 // Caller of this function should hold a reference to the bridge, because this f
unction may call WebSocket::didClose() in the end, |
| 485 // which causes the bridge to get disconnected from the WebSocket and deleted if
there is no other reference. | 485 // which causes the bridge to get disconnected from the WebSocket and deleted if
there is no other reference. |
| 486 bool Bridge::waitForMethodCompletion(std::unique_ptr<ExecutionContextTask> task) | 486 bool Bridge::waitForMethodCompletion(const WebTraceLocation& location, std::uniq
ue_ptr<ExecutionContextTask> task) |
| 487 { | 487 { |
| 488 ASSERT(m_workerGlobalScope); | 488 ASSERT(m_workerGlobalScope); |
| 489 ASSERT(m_syncHelper); | 489 ASSERT(m_syncHelper); |
| 490 | 490 |
| 491 m_loaderProxy->postTaskToLoader(std::move(task)); | 491 m_loaderProxy->postTaskToLoader(location, std::move(task)); |
| 492 | 492 |
| 493 // We wait for the syncHelper event even if a shutdown event is fired. | 493 // We wait for the syncHelper event even if a shutdown event is fired. |
| 494 // See https://codereview.chromium.org/267323004/#msg43 for why we need to w
ait this. | 494 // See https://codereview.chromium.org/267323004/#msg43 for why we need to w
ait this. |
| 495 SafePointScope scope(BlinkGC::HeapPointersOnStack); | 495 SafePointScope scope(BlinkGC::HeapPointersOnStack); |
| 496 m_syncHelper->wait(); | 496 m_syncHelper->wait(); |
| 497 // This is checking whether a shutdown event is fired or not. | 497 // This is checking whether a shutdown event is fired or not. |
| 498 return !m_workerGlobalScope->thread()->terminated(); | 498 return !m_workerGlobalScope->thread()->terminated(); |
| 499 } | 499 } |
| 500 | 500 |
| 501 DEFINE_TRACE(Bridge) | 501 DEFINE_TRACE(Bridge) |
| 502 { | 502 { |
| 503 visitor->trace(m_client); | 503 visitor->trace(m_client); |
| 504 visitor->trace(m_workerGlobalScope); | 504 visitor->trace(m_workerGlobalScope); |
| 505 visitor->trace(m_syncHelper); | 505 visitor->trace(m_syncHelper); |
| 506 } | 506 } |
| 507 | 507 |
| 508 } // namespace blink | 508 } // namespace blink |
| OLD | NEW |