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 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 |