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 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
448 RefPtr<WeakReference<Peer> > reference = WeakReference<Peer>::createUnbound( ); | 448 RefPtr<WeakReference<Peer> > reference = WeakReference<Peer>::createUnbound( ); |
449 m_peer = WeakPtr<Peer>(reference); | 449 m_peer = WeakPtr<Peer>(reference); |
450 #endif | 450 #endif |
451 | 451 |
452 RefPtrWillBeRawPtr<ThreadableWebSocketChannelSyncHelper> syncHelper = Thread ableWebSocketChannelSyncHelper::create(adoptPtr(blink::Platform::current()->crea teWaitableEvent())); | 452 RefPtrWillBeRawPtr<ThreadableWebSocketChannelSyncHelper> syncHelper = Thread ableWebSocketChannelSyncHelper::create(adoptPtr(blink::Platform::current()->crea teWaitableEvent())); |
453 // This pointer is guaranteed to be valid until we call terminatePeer. | 453 // This pointer is guaranteed to be valid until we call terminatePeer. |
454 m_syncHelper = syncHelper.get(); | 454 m_syncHelper = syncHelper.get(); |
455 | 455 |
456 RefPtrWillBeRawPtr<Bridge> protect(this); | 456 RefPtrWillBeRawPtr<Bridge> protect(this); |
457 #if ENABLE(OILPAN) | 457 #if ENABLE(OILPAN) |
458 if (!waitForMethodCompletion(createCallbackTask(&Peer::initialize, &m_peer, AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(), sourceURL, lineNumber, syncHelper.get()))) { | 458 // In order to assure all temporally objects to be destroyed before |
459 // posting the task, we should bind the task. In other words, it is | |
460 // dangerous to have a complicated expression as a waitForMethodCompletion | |
461 // argument. | |
462 OwnPtr<ExecutionContextTask> task = createCallbackTask(&Peer::initialize, &m _peer, AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(), sour ceURL, lineNumber, syncHelper.get()); | |
459 #else | 463 #else |
460 if (!waitForMethodCompletion(createCallbackTask(&Peer::initialize, reference , AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(), sourceURL , lineNumber, syncHelper.get()))) { | 464 // See the above comment. |
465 OwnPtr<ExecutionContextTask> task = createCallbackTask(&Peer::initialize, re ference, AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper.get(), so urceURL, lineNumber, syncHelper.get()); | |
461 #endif | 466 #endif |
467 if (!waitForMethodCompletion(task.release())) { | |
462 // The worker thread has been signalled to shutdown before method comple tion. | 468 // The worker thread has been signalled to shutdown before method comple tion. |
463 disconnect(); | 469 disconnect(); |
464 } | 470 } |
465 } | 471 } |
466 | 472 |
467 bool WorkerThreadableWebSocketChannel::Bridge::connect(const KURL& url, const St ring& protocol) | 473 bool WorkerThreadableWebSocketChannel::Bridge::connect(const KURL& url, const St ring& protocol) |
468 { | 474 { |
469 if (hasTerminatedPeer()) | 475 if (hasTerminatedPeer()) |
470 return false; | 476 return false; |
471 | 477 |
472 RefPtrWillBeRawPtr<Bridge> protect(this); | 478 RefPtrWillBeRawPtr<Bridge> protect(this); |
473 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::connect, m_ peer, url.copy(), protocol.isolatedCopy())))) | 479 // It is important to seprate the task creation from the |
480 // waitForMethodCompletion call. See the above comment. | |
481 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::conn ect, m_peer, url.copy(), protocol.isolatedCopy())); | |
482 if (!waitForMethodCompletion(task.release())) | |
474 return false; | 483 return false; |
475 | 484 |
476 return m_syncHelper->connectRequestResult(); | 485 return m_syncHelper->connectRequestResult(); |
477 } | 486 } |
478 | 487 |
479 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons t String& message) | 488 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons t String& message) |
480 { | 489 { |
481 if (hasTerminatedPeer()) | 490 if (hasTerminatedPeer()) |
482 return WebSocketChannel::SendFail; | 491 return WebSocketChannel::SendFail; |
483 | 492 |
484 RefPtrWillBeRawPtr<Bridge> protect(this); | 493 RefPtrWillBeRawPtr<Bridge> protect(this); |
485 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::send, m_pee r, message.isolatedCopy())))) | 494 // It is important to seprate the task creation from the |
495 // waitForMethodCompletion call. See the above comment. | |
496 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::send , m_peer, message.isolatedCopy())); | |
497 if (!waitForMethodCompletion(task.release())) | |
486 return WebSocketChannel::SendFail; | 498 return WebSocketChannel::SendFail; |
487 | 499 |
488 return m_syncHelper->sendRequestResult(); | 500 return m_syncHelper->sendRequestResult(); |
489 } | 501 } |
490 | 502 |
491 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons t ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength) | 503 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons t ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength) |
492 { | 504 { |
493 if (hasTerminatedPeer()) | 505 if (hasTerminatedPeer()) |
494 return WebSocketChannel::SendFail; | 506 return WebSocketChannel::SendFail; |
495 | 507 |
496 // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>. | 508 // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>. |
497 OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(byteLength)); | 509 OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(byteLength)); |
498 if (binaryData.byteLength()) | 510 if (binaryData.byteLength()) |
499 memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteO ffset, byteLength); | 511 memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteO ffset, byteLength); |
500 | 512 |
501 RefPtrWillBeRawPtr<Bridge> protect(this); | 513 RefPtrWillBeRawPtr<Bridge> protect(this); |
502 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::sendArrayBu ffer, m_peer, data.release())))) | 514 // It is important to seprate the task creation from the |
515 // waitForMethodCompletion call. See the above comment. | |
516 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::send ArrayBuffer, m_peer, data.release())); | |
517 if (!waitForMethodCompletion(task.release())) | |
503 return WebSocketChannel::SendFail; | 518 return WebSocketChannel::SendFail; |
504 | 519 |
505 return m_syncHelper->sendRequestResult(); | 520 return m_syncHelper->sendRequestResult(); |
506 } | 521 } |
507 | 522 |
508 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(Pass RefPtr<BlobDataHandle> data) | 523 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(Pass RefPtr<BlobDataHandle> data) |
509 { | 524 { |
510 if (hasTerminatedPeer()) | 525 if (hasTerminatedPeer()) |
511 return WebSocketChannel::SendFail; | 526 return WebSocketChannel::SendFail; |
512 | 527 |
513 RefPtrWillBeRawPtr<Bridge> protect(this); | 528 RefPtrWillBeRawPtr<Bridge> protect(this); |
514 if (!waitForMethodCompletion(CallClosureTask::create(bind(&Peer::sendBlob, m _peer, data)))) | 529 // It is important to seprate the task creation from the |
530 // waitForMethodCompletion call. See the above comment. | |
531 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::send Blob, m_peer, data)); | |
532 if (!waitForMethodCompletion(task.release())) | |
515 return WebSocketChannel::SendFail; | 533 return WebSocketChannel::SendFail; |
516 | 534 |
517 return m_syncHelper->sendRequestResult(); | 535 return m_syncHelper->sendRequestResult(); |
518 } | 536 } |
519 | 537 |
520 void WorkerThreadableWebSocketChannel::Bridge::close(int code, const String& rea son) | 538 void WorkerThreadableWebSocketChannel::Bridge::close(int code, const String& rea son) |
521 { | 539 { |
522 if (hasTerminatedPeer()) | 540 if (hasTerminatedPeer()) |
523 return; | 541 return; |
524 | 542 |
525 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::close, m_ peer, code, reason.isolatedCopy()))); | 543 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::close, m_ peer, code, reason.isolatedCopy()))); |
hiroshige
2014/07/01 14:13:41
Should we modify this line as well?
The temporary
yhirano
2014/07/02 01:35:23
Thanks, done.
| |
526 } | 544 } |
527 | 545 |
528 void WorkerThreadableWebSocketChannel::Bridge::fail(const String& reason, Messag eLevel level, const String& sourceURL, unsigned lineNumber) | 546 void WorkerThreadableWebSocketChannel::Bridge::fail(const String& reason, Messag eLevel level, const String& sourceURL, unsigned lineNumber) |
529 { | 547 { |
530 if (hasTerminatedPeer()) | 548 if (hasTerminatedPeer()) |
531 return; | 549 return; |
532 | 550 |
533 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::fail, m_p eer, reason.isolatedCopy(), level, sourceURL.isolatedCopy(), lineNumber))); | 551 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::fail, m_p eer, reason.isolatedCopy(), level, sourceURL.isolatedCopy(), lineNumber))); |
hiroshige
2014/07/01 14:13:41
same as above.
yhirano
2014/07/02 01:35:23
Done.
| |
534 } | 552 } |
535 | 553 |
536 void WorkerThreadableWebSocketChannel::Bridge::disconnect() | 554 void WorkerThreadableWebSocketChannel::Bridge::disconnect() |
537 { | 555 { |
538 if (hasTerminatedPeer()) | 556 if (hasTerminatedPeer()) |
539 return; | 557 return; |
540 | 558 |
541 clearClientWrapper(); | 559 clearClientWrapper(); |
542 terminatePeer(); | 560 terminatePeer(); |
543 } | 561 } |
(...skipping 18 matching lines...) Expand all Loading... | |
562 events.append(m_syncHelper->event()); | 580 events.append(m_syncHelper->event()); |
563 ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack); | 581 ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack); |
564 blink::Platform::current()->waitMultipleEvents(events); | 582 blink::Platform::current()->waitMultipleEvents(events); |
565 // This is checking whether a shutdown event is fired or not. | 583 // This is checking whether a shutdown event is fired or not. |
566 return !m_workerGlobalScope->thread()->runLoop().terminated(); | 584 return !m_workerGlobalScope->thread()->runLoop().terminated(); |
567 } | 585 } |
568 | 586 |
569 void WorkerThreadableWebSocketChannel::Bridge::terminatePeer() | 587 void WorkerThreadableWebSocketChannel::Bridge::terminatePeer() |
570 { | 588 { |
571 ASSERT(!hasTerminatedPeer()); | 589 ASSERT(!hasTerminatedPeer()); |
590 | |
591 // It is important to seprate the task creation from the | |
592 // waitForMethodCompletion call. See the above comment. | |
593 OwnPtr<ExecutionContextTask> task = CallClosureTask::create(bind(&Peer::dest roy, m_peer)); | |
572 #if ENABLE(OILPAN) | 594 #if ENABLE(OILPAN) |
573 // The worker thread has to wait for the main thread to complete Peer::destr oy, | 595 // The worker thread has to wait for the main thread to complete Peer::destr oy, |
574 // because the worker thread has to make sure that the main thread does not have any | 596 // because the worker thread has to make sure that the main thread does not have any |
575 // references to on-heap objects allocated in the thread heap of the worker thread | 597 // references to on-heap objects allocated in the thread heap of the worker thread |
576 // before the worker thread shuts down. | 598 // before the worker thread shuts down. |
577 waitForMethodCompletion(CallClosureTask::create(bind(&Peer::destroy, m_peer) )); | 599 waitForMethodCompletion(task.release()); |
578 #else | 600 #else |
579 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::destroy, m_peer))); | 601 m_loaderProxy.postTaskToLoader(task.release()); |
580 #endif | 602 #endif |
581 | 603 |
582 // Peer::destroy() deletes m_peer and then m_syncHelper will be released. | 604 // Peer::destroy() deletes m_peer and then m_syncHelper will be released. |
583 // We must not touch m_syncHelper any more. | 605 // We must not touch m_syncHelper any more. |
584 m_syncHelper = nullptr; | 606 m_syncHelper = nullptr; |
585 | 607 |
586 // We won't use this any more. | 608 // We won't use this any more. |
587 m_workerGlobalScope = nullptr; | 609 m_workerGlobalScope = nullptr; |
588 } | 610 } |
589 | 611 |
590 void WorkerThreadableWebSocketChannel::Bridge::trace(Visitor* visitor) | 612 void WorkerThreadableWebSocketChannel::Bridge::trace(Visitor* visitor) |
591 { | 613 { |
592 visitor->trace(m_workerClientWrapper); | 614 visitor->trace(m_workerClientWrapper); |
593 visitor->trace(m_workerGlobalScope); | 615 visitor->trace(m_workerGlobalScope); |
594 visitor->trace(m_syncHelper); | 616 visitor->trace(m_syncHelper); |
595 visitor->trace(m_peer); | 617 visitor->trace(m_peer); |
596 } | 618 } |
597 | 619 |
598 } // namespace WebCore | 620 } // namespace WebCore |
OLD | NEW |