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 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 { | 379 { |
380 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 380 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
381 workerClientWrapper->setSubprotocol(subprotocol); | 381 workerClientWrapper->setSubprotocol(subprotocol); |
382 workerClientWrapper->setExtensions(extensions); | 382 workerClientWrapper->setExtensions(extensions); |
383 workerClientWrapper->didConnect(); | 383 workerClientWrapper->didConnect(); |
384 } | 384 } |
385 | 385 |
386 void WorkerThreadableWebSocketChannel::Peer::didConnect() | 386 void WorkerThreadableWebSocketChannel::Peer::didConnect() |
387 { | 387 { |
388 ASSERT(isMainThread()); | 388 ASSERT(isMainThread()); |
389 m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalSc
opeDidConnect, m_workerClientWrapper, m_mainWebSocketChannel->subprotocol(), m_m
ainWebSocketChannel->extensions())); | 389 // It is important to seprate task creation from posting |
| 390 // the task. See the above comment. |
| 391 OwnPtr<ExecutionContextTask> task = createCallbackTask(&workerGlobalScopeDid
Connect, m_workerClientWrapper, m_mainWebSocketChannel->subprotocol(), m_mainWeb
SocketChannel->extensions()); |
| 392 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); |
390 } | 393 } |
391 | 394 |
392 static void workerGlobalScopeDidReceiveMessage(ExecutionContext* context, PassRe
fPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, const String&
message) | 395 static void workerGlobalScopeDidReceiveMessage(ExecutionContext* context, PassRe
fPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, const String&
message) |
393 { | 396 { |
394 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 397 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
395 workerClientWrapper->didReceiveMessage(message); | 398 workerClientWrapper->didReceiveMessage(message); |
396 } | 399 } |
397 | 400 |
398 void WorkerThreadableWebSocketChannel::Peer::didReceiveMessage(const String& mes
sage) | 401 void WorkerThreadableWebSocketChannel::Peer::didReceiveMessage(const String& mes
sage) |
399 { | 402 { |
400 ASSERT(isMainThread()); | 403 ASSERT(isMainThread()); |
401 m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalSc
opeDidReceiveMessage, m_workerClientWrapper, message)); | 404 // It is important to seprate task creation from posting |
| 405 // the task. See the above comment. |
| 406 OwnPtr<ExecutionContextTask> task = createCallbackTask(&workerGlobalScopeDid
ReceiveMessage, m_workerClientWrapper, message); |
| 407 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); |
402 } | 408 } |
403 | 409 |
404 static void workerGlobalScopeDidReceiveBinaryData(ExecutionContext* context, Pas
sRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassOwnPtr
<Vector<char> > binaryData) | 410 static void workerGlobalScopeDidReceiveBinaryData(ExecutionContext* context, Pas
sRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassOwnPtr
<Vector<char> > binaryData) |
405 { | 411 { |
406 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 412 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
407 workerClientWrapper->didReceiveBinaryData(binaryData); | 413 workerClientWrapper->didReceiveBinaryData(binaryData); |
408 } | 414 } |
409 | 415 |
410 void WorkerThreadableWebSocketChannel::Peer::didReceiveBinaryData(PassOwnPtr<Vec
tor<char> > binaryData) | 416 void WorkerThreadableWebSocketChannel::Peer::didReceiveBinaryData(PassOwnPtr<Vec
tor<char> > binaryData) |
411 { | 417 { |
412 ASSERT(isMainThread()); | 418 ASSERT(isMainThread()); |
413 m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalSc
opeDidReceiveBinaryData, m_workerClientWrapper, binaryData)); | 419 // It is important to seprate task creation from posting |
| 420 // the task. See the above comment. |
| 421 OwnPtr<ExecutionContextTask> task = createCallbackTask(&workerGlobalScopeDid
ReceiveBinaryData, m_workerClientWrapper, binaryData); |
| 422 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); |
414 } | 423 } |
415 | 424 |
416 static void workerGlobalScopeDidUpdateBufferedAmount(ExecutionContext* context,
PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, unsigne
d long bufferedAmount) | 425 static void workerGlobalScopeDidUpdateBufferedAmount(ExecutionContext* context,
PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, unsigne
d long bufferedAmount) |
417 { | 426 { |
418 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 427 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
419 workerClientWrapper->didUpdateBufferedAmount(bufferedAmount); | 428 workerClientWrapper->didUpdateBufferedAmount(bufferedAmount); |
420 } | 429 } |
421 | 430 |
422 void WorkerThreadableWebSocketChannel::Peer::didUpdateBufferedAmount(unsigned lo
ng bufferedAmount) | 431 void WorkerThreadableWebSocketChannel::Peer::didUpdateBufferedAmount(unsigned lo
ng bufferedAmount) |
423 { | 432 { |
424 ASSERT(isMainThread()); | 433 ASSERT(isMainThread()); |
425 m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalSc
opeDidUpdateBufferedAmount, m_workerClientWrapper, bufferedAmount)); | 434 // It is important to seprate task creation from posting |
| 435 // the task. See the above comment. |
| 436 OwnPtr<ExecutionContextTask> task = createCallbackTask(&workerGlobalScopeDid
UpdateBufferedAmount, m_workerClientWrapper, bufferedAmount); |
| 437 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); |
426 } | 438 } |
427 | 439 |
428 static void workerGlobalScopeDidStartClosingHandshake(ExecutionContext* context,
PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper) | 440 static void workerGlobalScopeDidStartClosingHandshake(ExecutionContext* context,
PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper) |
429 { | 441 { |
430 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 442 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
431 workerClientWrapper->didStartClosingHandshake(); | 443 workerClientWrapper->didStartClosingHandshake(); |
432 } | 444 } |
433 | 445 |
434 void WorkerThreadableWebSocketChannel::Peer::didStartClosingHandshake() | 446 void WorkerThreadableWebSocketChannel::Peer::didStartClosingHandshake() |
435 { | 447 { |
436 ASSERT(isMainThread()); | 448 ASSERT(isMainThread()); |
437 m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalSc
opeDidStartClosingHandshake, m_workerClientWrapper)); | 449 // It is important to seprate task creation from posting |
| 450 // the task. See the above comment. |
| 451 OwnPtr<ExecutionContextTask> task = createCallbackTask(&workerGlobalScopeDid
StartClosingHandshake, m_workerClientWrapper); |
| 452 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); |
438 } | 453 } |
439 | 454 |
440 static void workerGlobalScopeDidClose(ExecutionContext* context, PassRefPtr<Thre
adableWebSocketChannelClientWrapper> workerClientWrapper, unsigned long unhandle
dBufferedAmount, WebSocketChannelClient::ClosingHandshakeCompletionStatus closin
gHandshakeCompletion, unsigned short code, const String& reason) | 455 static void workerGlobalScopeDidClose(ExecutionContext* context, PassRefPtr<Thre
adableWebSocketChannelClientWrapper> workerClientWrapper, unsigned long unhandle
dBufferedAmount, WebSocketChannelClient::ClosingHandshakeCompletionStatus closin
gHandshakeCompletion, unsigned short code, const String& reason) |
441 { | 456 { |
442 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 457 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
443 workerClientWrapper->didClose(unhandledBufferedAmount, closingHandshakeCompl
etion, code, reason); | 458 workerClientWrapper->didClose(unhandledBufferedAmount, closingHandshakeCompl
etion, code, reason); |
444 } | 459 } |
445 | 460 |
446 void WorkerThreadableWebSocketChannel::Peer::didClose(unsigned long unhandledBuf
feredAmount, ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsign
ed short code, const String& reason) | 461 void WorkerThreadableWebSocketChannel::Peer::didClose(unsigned long unhandledBuf
feredAmount, ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsign
ed short code, const String& reason) |
447 { | 462 { |
448 ASSERT(isMainThread()); | 463 ASSERT(isMainThread()); |
449 m_mainWebSocketChannel = nullptr; | 464 m_mainWebSocketChannel = nullptr; |
450 m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalSc
opeDidClose, m_workerClientWrapper, unhandledBufferedAmount, closingHandshakeCom
pletion, code, reason)); | 465 // It is important to seprate task creation from posting |
| 466 // the task. See the above comment. |
| 467 OwnPtr<ExecutionContextTask> task = createCallbackTask(&workerGlobalScopeDid
Close, m_workerClientWrapper, unhandledBufferedAmount, closingHandshakeCompletio
n, code, reason); |
| 468 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); |
451 } | 469 } |
452 | 470 |
453 static void workerGlobalScopeDidReceiveMessageError(ExecutionContext* context, P
assRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper) | 471 static void workerGlobalScopeDidReceiveMessageError(ExecutionContext* context, P
assRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper) |
454 { | 472 { |
455 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 473 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
456 workerClientWrapper->didReceiveMessageError(); | 474 workerClientWrapper->didReceiveMessageError(); |
457 } | 475 } |
458 | 476 |
459 void WorkerThreadableWebSocketChannel::Peer::didReceiveMessageError() | 477 void WorkerThreadableWebSocketChannel::Peer::didReceiveMessageError() |
460 { | 478 { |
461 ASSERT(isMainThread()); | 479 ASSERT(isMainThread()); |
462 m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalSc
opeDidReceiveMessageError, m_workerClientWrapper)); | 480 // It is important to seprate task creation from posting |
| 481 // the task. See the above comment. |
| 482 OwnPtr<ExecutionContextTask> task = createCallbackTask(&workerGlobalScopeDid
ReceiveMessageError, m_workerClientWrapper); |
| 483 m_loaderProxy.postTaskToWorkerGlobalScope(task.release()); |
463 } | 484 } |
464 | 485 |
465 WorkerThreadableWebSocketChannel::Bridge::Bridge(PassRefPtr<ThreadableWebSocketC
hannelClientWrapper> workerClientWrapper, WorkerGlobalScope& workerGlobalScope) | 486 WorkerThreadableWebSocketChannel::Bridge::Bridge(PassRefPtr<ThreadableWebSocketC
hannelClientWrapper> workerClientWrapper, WorkerGlobalScope& workerGlobalScope) |
466 : m_workerClientWrapper(workerClientWrapper) | 487 : m_workerClientWrapper(workerClientWrapper) |
467 , m_workerGlobalScope(workerGlobalScope) | 488 , m_workerGlobalScope(workerGlobalScope) |
468 , m_loaderProxy(m_workerGlobalScope->thread()->workerLoaderProxy()) | 489 , m_loaderProxy(m_workerGlobalScope->thread()->workerLoaderProxy()) |
469 , m_syncHelper(0) | 490 , m_syncHelper(0) |
470 { | 491 { |
471 ASSERT(m_workerClientWrapper.get()); | 492 ASSERT(m_workerClientWrapper.get()); |
472 } | 493 } |
473 | 494 |
474 WorkerThreadableWebSocketChannel::Bridge::~Bridge() | 495 WorkerThreadableWebSocketChannel::Bridge::~Bridge() |
475 { | 496 { |
476 disconnect(); | 497 disconnect(); |
477 } | 498 } |
478 | 499 |
479 void WorkerThreadableWebSocketChannel::Bridge::initialize(const String& sourceUR
L, unsigned lineNumber) | 500 void WorkerThreadableWebSocketChannel::Bridge::initialize(const String& sourceUR
L, unsigned lineNumber) |
480 { | 501 { |
481 RefPtr<WeakReference<Peer> > reference = WeakReference<Peer>::createUnbound(
); | 502 RefPtr<WeakReference<Peer> > reference = WeakReference<Peer>::createUnbound(
); |
482 m_peer = WeakPtr<Peer>(reference); | 503 m_peer = WeakPtr<Peer>(reference); |
483 | 504 |
484 OwnPtr<ThreadableWebSocketChannelSyncHelper> syncHelper = ThreadableWebSocke
tChannelSyncHelper::create(adoptPtr(blink::Platform::current()->createWaitableEv
ent())); | 505 OwnPtr<ThreadableWebSocketChannelSyncHelper> syncHelper = ThreadableWebSocke
tChannelSyncHelper::create(adoptPtr(blink::Platform::current()->createWaitableEv
ent())); |
485 // This pointer is guaranteed to be valid until we call terminatePeer. | 506 // This pointer is guaranteed to be valid until we call terminatePeer. |
486 m_syncHelper = syncHelper.get(); | 507 m_syncHelper = syncHelper.get(); |
487 | 508 |
488 RefPtr<Bridge> protect(this); | 509 RefPtr<Bridge> protect(this); |
489 if (!waitForMethodCompletion(createCallbackTask(&Peer::initialize, reference
.release(), AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper, sourc
eURL, lineNumber, syncHelper.release()))) { | 510 OwnPtr<ExecutionContextTask> task = createCallbackTask(&Peer::initialize, re
ference.release(), AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper
, sourceURL, lineNumber, syncHelper.release()); |
| 511 if (!waitForMethodCompletion(task.release())) { |
490 // The worker thread has been signalled to shutdown before method comple
tion. | 512 // The worker thread has been signalled to shutdown before method comple
tion. |
491 terminatePeer(); | 513 terminatePeer(); |
492 } | 514 } |
493 } | 515 } |
494 | 516 |
495 bool WorkerThreadableWebSocketChannel::Bridge::connect(const KURL& url, const St
ring& protocol) | 517 bool WorkerThreadableWebSocketChannel::Bridge::connect(const KURL& url, const St
ring& protocol) |
496 { | 518 { |
497 if (hasTerminatedPeer()) | 519 if (hasTerminatedPeer()) |
498 return false; | 520 return false; |
499 | 521 |
500 RefPtr<Bridge> protect(this); | 522 RefPtr<Bridge> protect(this); |
501 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::connect, m_
peer, url.copy(), protocol.isolatedCopy())))) | 523 // It is important to seprate task creation from calling |
| 524 // waitForMethodCompletion. See the above comment. |
| 525 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::conn
ect, m_peer, url.copy(), protocol.isolatedCopy())); |
| 526 if (!waitForMethodCompletion(task.release())) |
502 return false; | 527 return false; |
503 | 528 |
504 return m_syncHelper->connectRequestResult(); | 529 return m_syncHelper->connectRequestResult(); |
505 } | 530 } |
506 | 531 |
507 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons
t String& message) | 532 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons
t String& message) |
508 { | 533 { |
509 if (hasTerminatedPeer()) | 534 if (hasTerminatedPeer()) |
510 return WebSocketChannel::SendFail; | 535 return WebSocketChannel::SendFail; |
511 | 536 |
512 RefPtr<Bridge> protect(this); | 537 RefPtr<Bridge> protect(this); |
513 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::send, m_pee
r, message.isolatedCopy())))) | 538 // It is important to seprate task creation from calling |
| 539 // waitForMethodCompletion. See the above comment. |
| 540 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::send
, m_peer, message.isolatedCopy())); |
| 541 if (!waitForMethodCompletion(task.release())) |
514 return WebSocketChannel::SendFail; | 542 return WebSocketChannel::SendFail; |
515 | 543 |
516 return m_syncHelper->sendRequestResult(); | 544 return m_syncHelper->sendRequestResult(); |
517 } | 545 } |
518 | 546 |
519 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons
t ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength) | 547 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons
t ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength) |
520 { | 548 { |
521 if (hasTerminatedPeer()) | 549 if (hasTerminatedPeer()) |
522 return WebSocketChannel::SendFail; | 550 return WebSocketChannel::SendFail; |
523 | 551 |
524 // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied
into Vector<char>. | 552 // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied
into Vector<char>. |
525 OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(byteLength)); | 553 OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(byteLength)); |
526 if (binaryData.byteLength()) | 554 if (binaryData.byteLength()) |
527 memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteO
ffset, byteLength); | 555 memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteO
ffset, byteLength); |
528 | 556 |
529 RefPtr<Bridge> protect(this); | 557 RefPtr<Bridge> protect(this); |
530 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::sendArrayBu
ffer, m_peer, data.release())))) | 558 // It is important to seprate task creation from calling |
| 559 // waitForMethodCompletion. See the above comment. |
| 560 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::send
ArrayBuffer, m_peer, data.release())); |
| 561 if (!waitForMethodCompletion(task.release())) |
531 return WebSocketChannel::SendFail; | 562 return WebSocketChannel::SendFail; |
532 | 563 |
533 return m_syncHelper->sendRequestResult(); | 564 return m_syncHelper->sendRequestResult(); |
534 } | 565 } |
535 | 566 |
536 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(Pass
RefPtr<BlobDataHandle> data) | 567 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(Pass
RefPtr<BlobDataHandle> data) |
537 { | 568 { |
538 if (hasTerminatedPeer()) | 569 if (hasTerminatedPeer()) |
539 return WebSocketChannel::SendFail; | 570 return WebSocketChannel::SendFail; |
540 | 571 |
541 RefPtr<Bridge> protect(this); | 572 RefPtr<Bridge> protect(this); |
542 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::sendBlob, m
_peer, data)))) | 573 // It is important to seprate task creation from calling |
| 574 // waitForMethodCompletion. See the above comment. |
| 575 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::send
Blob, m_peer, data)); |
| 576 if (!waitForMethodCompletion(task.release())) |
543 return WebSocketChannel::SendFail; | 577 return WebSocketChannel::SendFail; |
544 | 578 |
545 return m_syncHelper->sendRequestResult(); | 579 return m_syncHelper->sendRequestResult(); |
546 } | 580 } |
547 | 581 |
548 unsigned long WorkerThreadableWebSocketChannel::Bridge::bufferedAmount() | 582 unsigned long WorkerThreadableWebSocketChannel::Bridge::bufferedAmount() |
549 { | 583 { |
550 if (hasTerminatedPeer()) | 584 if (hasTerminatedPeer()) |
551 return 0; | 585 return 0; |
552 | 586 |
553 RefPtr<Bridge> protect(this); | 587 RefPtr<Bridge> protect(this); |
554 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::bufferedAmo
unt, m_peer)))) | 588 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::bufferedAmo
unt, m_peer)))) |
555 return 0; | 589 return 0; |
556 | 590 |
557 return m_syncHelper->bufferedAmount(); | 591 return m_syncHelper->bufferedAmount(); |
558 } | 592 } |
559 | 593 |
560 void WorkerThreadableWebSocketChannel::Bridge::close(int code, const String& rea
son) | 594 void WorkerThreadableWebSocketChannel::Bridge::close(int code, const String& rea
son) |
561 { | 595 { |
562 if (hasTerminatedPeer()) | 596 if (hasTerminatedPeer()) |
563 return; | 597 return; |
564 | 598 |
565 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::close, m_
peer, code, reason.isolatedCopy()))); | 599 // It is important to seprate task creation from calling |
| 600 // waitForMethodCompletion. See the above comment. |
| 601 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::clos
e, m_peer, code, reason.isolatedCopy())); |
| 602 m_loaderProxy.postTaskToLoader(task.release()); |
566 } | 603 } |
567 | 604 |
568 void WorkerThreadableWebSocketChannel::Bridge::fail(const String& reason, Messag
eLevel level, const String& sourceURL, unsigned lineNumber) | 605 void WorkerThreadableWebSocketChannel::Bridge::fail(const String& reason, Messag
eLevel level, const String& sourceURL, unsigned lineNumber) |
569 { | 606 { |
570 if (hasTerminatedPeer()) | 607 if (hasTerminatedPeer()) |
571 return; | 608 return; |
572 | 609 |
573 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::fail, m_p
eer, reason.isolatedCopy(), level, sourceURL.isolatedCopy(), lineNumber))); | 610 // It is important to seprate task creation from calling |
| 611 // waitForMethodCompletion. See the above comment. |
| 612 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::fail
, m_peer, reason.isolatedCopy(), level, sourceURL.isolatedCopy(), lineNumber)); |
| 613 m_loaderProxy.postTaskToLoader(task.release()); |
574 } | 614 } |
575 | 615 |
576 void WorkerThreadableWebSocketChannel::Bridge::disconnect() | 616 void WorkerThreadableWebSocketChannel::Bridge::disconnect() |
577 { | 617 { |
578 clearClientWrapper(); | 618 clearClientWrapper(); |
579 terminatePeer(); | 619 terminatePeer(); |
580 } | 620 } |
581 | 621 |
582 void WorkerThreadableWebSocketChannel::Bridge::suspend() | 622 void WorkerThreadableWebSocketChannel::Bridge::suspend() |
583 { | 623 { |
(...skipping 30 matching lines...) Expand all Loading... |
614 events.append(shutdownEvent); | 654 events.append(shutdownEvent); |
615 events.append(m_syncHelper->event()); | 655 events.append(m_syncHelper->event()); |
616 | 656 |
617 ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack); | 657 ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack); |
618 blink::WebWaitableEvent* signalled = blink::Platform::current()->waitMultipl
eEvents(events); | 658 blink::WebWaitableEvent* signalled = blink::Platform::current()->waitMultipl
eEvents(events); |
619 return signalled != shutdownEvent; | 659 return signalled != shutdownEvent; |
620 } | 660 } |
621 | 661 |
622 void WorkerThreadableWebSocketChannel::Bridge::terminatePeer() | 662 void WorkerThreadableWebSocketChannel::Bridge::terminatePeer() |
623 { | 663 { |
624 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::destroy,
m_peer))); | 664 // It is important to seprate task creation from calling |
| 665 // waitForMethodCompletion. See the above comment. |
| 666 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::dest
roy, m_peer)); |
| 667 m_loaderProxy.postTaskToLoader(task.release()); |
625 // Peer::destroy() deletes m_peer and then m_syncHelper will be released. | 668 // Peer::destroy() deletes m_peer and then m_syncHelper will be released. |
626 // We must not touch m_syncHelper any more. | 669 // We must not touch m_syncHelper any more. |
627 m_syncHelper = 0; | 670 m_syncHelper = 0; |
628 | 671 |
629 // We won't use this any more. | 672 // We won't use this any more. |
630 m_workerGlobalScope = nullptr; | 673 m_workerGlobalScope = nullptr; |
631 } | 674 } |
632 | 675 |
633 } // namespace WebCore | 676 } // namespace WebCore |
OLD | NEW |