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 |