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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 , m_bufferedAmount(0) | 113 , m_bufferedAmount(0) |
| 114 { | 114 { |
| 115 } | 115 } |
| 116 | 116 |
| 117 OwnPtr<blink::WebWaitableEvent> m_event; | 117 OwnPtr<blink::WebWaitableEvent> m_event; |
| 118 bool m_connectRequestResult; | 118 bool m_connectRequestResult; |
| 119 WebSocketChannel::SendResult m_sendRequestResult; | 119 WebSocketChannel::SendResult m_sendRequestResult; |
| 120 unsigned long m_bufferedAmount; | 120 unsigned long m_bufferedAmount; |
| 121 }; | 121 }; |
| 122 | 122 |
| 123 WorkerThreadableWebSocketChannel::WorkerThreadableWebSocketChannel(WorkerGlobalS cope& context, WebSocketChannelClient* client, const String& sourceURL, unsigned lineNumber) | 123 WorkerThreadableWebSocketChannel::WorkerThreadableWebSocketChannel(WorkerGlobalS cope& workerGlobalScope, WebSocketChannelClient* client, const String& sourceURL , unsigned lineNumber) |
| 124 : m_workerGlobalScope(context) | 124 : m_workerClientWrapper(ThreadableWebSocketChannelClientWrapper::create(clie nt)) |
| 125 , m_workerClientWrapper(ThreadableWebSocketChannelClientWrapper::create(clie nt)) | 125 , m_bridge(Bridge::create(m_workerClientWrapper, workerGlobalScope)) |
| 126 , m_bridge(Bridge::create(m_workerClientWrapper, m_workerGlobalScope)) | |
| 127 , m_sourceURLAtConnection(sourceURL) | 126 , m_sourceURLAtConnection(sourceURL) |
| 128 , m_lineNumberAtConnection(lineNumber) | 127 , m_lineNumberAtConnection(lineNumber) |
| 129 { | 128 { |
| 130 ASSERT(m_workerClientWrapper.get()); | 129 ASSERT(m_workerClientWrapper.get()); |
| 131 m_bridge->initialize(sourceURL, lineNumber); | 130 m_bridge->initialize(sourceURL, lineNumber); |
| 132 } | 131 } |
| 133 | 132 |
| 134 WorkerThreadableWebSocketChannel::~WorkerThreadableWebSocketChannel() | 133 WorkerThreadableWebSocketChannel::~WorkerThreadableWebSocketChannel() |
| 135 { | 134 { |
| 136 if (m_bridge) | 135 if (m_bridge) |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 450 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); | 449 ASSERT_UNUSED(context, context->isWorkerGlobalScope()); |
| 451 workerClientWrapper->didReceiveMessageError(); | 450 workerClientWrapper->didReceiveMessageError(); |
| 452 } | 451 } |
| 453 | 452 |
| 454 void WorkerThreadableWebSocketChannel::Peer::didReceiveMessageError() | 453 void WorkerThreadableWebSocketChannel::Peer::didReceiveMessageError() |
| 455 { | 454 { |
| 456 ASSERT(isMainThread()); | 455 ASSERT(isMainThread()); |
| 457 m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalSc opeDidReceiveMessageError, m_workerClientWrapper)); | 456 m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalSc opeDidReceiveMessageError, m_workerClientWrapper)); |
| 458 } | 457 } |
| 459 | 458 |
| 460 WorkerThreadableWebSocketChannel::Bridge::Bridge(PassRefPtr<ThreadableWebSocketC hannelClientWrapper> workerClientWrapper, PassRefPtrWillBeRawPtr<WorkerGlobalSco pe> workerGlobalScope) | 459 WorkerThreadableWebSocketChannel::Bridge::Bridge(PassRefPtr<ThreadableWebSocketC hannelClientWrapper> workerClientWrapper, WorkerGlobalScope& workerGlobalScope) |
| 461 : m_workerClientWrapper(workerClientWrapper) | 460 : m_workerClientWrapper(workerClientWrapper) |
| 462 , m_workerGlobalScope(workerGlobalScope) | 461 , m_workerGlobalScope(workerGlobalScope) |
| 463 , m_loaderProxy(m_workerGlobalScope->thread()->workerLoaderProxy()) | 462 , m_loaderProxy(m_workerGlobalScope->thread()->workerLoaderProxy()) |
| 464 , m_syncHelper(0) | 463 , m_syncHelper(0) |
| 465 { | 464 { |
| 466 ASSERT(m_workerClientWrapper.get()); | 465 ASSERT(m_workerClientWrapper.get()); |
| 467 } | 466 } |
| 468 | 467 |
| 469 WorkerThreadableWebSocketChannel::Bridge::~Bridge() | 468 WorkerThreadableWebSocketChannel::Bridge::~Bridge() |
| 470 { | 469 { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 483 RefPtr<Bridge> protect(this); | 482 RefPtr<Bridge> protect(this); |
| 484 m_loaderProxy.postTaskToLoader(createCallbackTask(&Peer::initialize, referen ce.release(), AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper, sou rceURL, lineNumber, syncHelper.release())); | 483 m_loaderProxy.postTaskToLoader(createCallbackTask(&Peer::initialize, referen ce.release(), AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper, sou rceURL, lineNumber, syncHelper.release())); |
| 485 if (!waitForMethodCompletion()) { | 484 if (!waitForMethodCompletion()) { |
| 486 // The worker thread has been signalled to shutdown before method comple tion. | 485 // The worker thread has been signalled to shutdown before method comple tion. |
| 487 terminatePeer(); | 486 terminatePeer(); |
| 488 } | 487 } |
| 489 } | 488 } |
| 490 | 489 |
| 491 bool WorkerThreadableWebSocketChannel::Bridge::connect(const KURL& url, const St ring& protocol) | 490 bool WorkerThreadableWebSocketChannel::Bridge::connect(const KURL& url, const St ring& protocol) |
| 492 { | 491 { |
| 493 if (!m_workerGlobalScope) | 492 if (hasTerminatedPeer()) |
| 494 return false; | 493 return false; |
| 495 ASSERT(m_syncHelper); | 494 |
| 495 RefPtr<Bridge> protect(this); | |
|
yhirano
2014/05/07 08:05:18
Can you tell me why this move is needed? I think p
tyoshino (SeeGerritForStatus)
2014/05/08 05:03:00
As discussed offline, it looks we no longer need t
| |
| 496 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::connect, m_peer, url.copy(), protocol.isolatedCopy()))); | 496 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::connect, m_peer, url.copy(), protocol.isolatedCopy()))); |
| 497 RefPtr<Bridge> protect(this); | 497 if (!waitForMethodCompletion()) |
|
yhirano
2014/05/07 08:05:18
[optional] We could have postTaskAndWait for this
tyoshino (SeeGerritForStatus)
2014/05/08 05:03:00
Done.
| |
| 498 waitForMethodCompletion(); | 498 return false; |
| 499 | |
| 499 return m_syncHelper->connectRequestResult(); | 500 return m_syncHelper->connectRequestResult(); |
| 500 } | 501 } |
| 501 | 502 |
| 502 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons t String& message) | 503 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons t String& message) |
| 503 { | 504 { |
| 504 if (!m_workerGlobalScope) | 505 if (hasTerminatedPeer()) |
| 505 return WebSocketChannel::SendFail; | 506 return WebSocketChannel::SendFail; |
| 506 ASSERT(m_syncHelper); | 507 |
| 508 RefPtr<Bridge> protect(this); | |
| 507 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::send, m_p eer, message.isolatedCopy()))); | 509 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::send, m_p eer, message.isolatedCopy()))); |
| 508 RefPtr<Bridge> protect(this); | 510 if (!waitForMethodCompletion()) |
| 509 waitForMethodCompletion(); | 511 return WebSocketChannel::SendFail; |
| 512 | |
| 510 return m_syncHelper->sendRequestResult(); | 513 return m_syncHelper->sendRequestResult(); |
| 511 } | 514 } |
| 512 | 515 |
| 513 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons t ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength) | 516 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(cons t ArrayBuffer& binaryData, unsigned byteOffset, unsigned byteLength) |
| 514 { | 517 { |
| 515 if (!m_workerGlobalScope) | 518 if (hasTerminatedPeer()) |
| 516 return WebSocketChannel::SendFail; | 519 return WebSocketChannel::SendFail; |
| 517 ASSERT(m_syncHelper); | 520 |
| 518 // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>. | 521 // ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>. |
| 519 OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(byteLength)); | 522 OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(byteLength)); |
| 520 if (binaryData.byteLength()) | 523 if (binaryData.byteLength()) |
| 521 memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteO ffset, byteLength); | 524 memcpy(data->data(), static_cast<const char*>(binaryData.data()) + byteO ffset, byteLength); |
| 522 | 525 |
| 526 RefPtr<Bridge> protect(this); | |
| 523 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::sendArray Buffer, m_peer, data.release()))); | 527 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::sendArray Buffer, m_peer, data.release()))); |
| 524 RefPtr<Bridge> protect(this); | 528 if (!waitForMethodCompletion()) |
| 525 waitForMethodCompletion(); | 529 return WebSocketChannel::SendFail; |
| 530 | |
| 526 return m_syncHelper->sendRequestResult(); | 531 return m_syncHelper->sendRequestResult(); |
| 527 } | 532 } |
| 528 | 533 |
| 529 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(Pass RefPtr<BlobDataHandle> data) | 534 WebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(Pass RefPtr<BlobDataHandle> data) |
| 530 { | 535 { |
| 531 if (!m_workerGlobalScope) | 536 if (hasTerminatedPeer()) |
| 532 return WebSocketChannel::SendFail; | 537 return WebSocketChannel::SendFail; |
| 533 ASSERT(m_syncHelper); | 538 |
| 539 RefPtr<Bridge> protect(this); | |
| 534 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::sendBlob, m_peer, data))); | 540 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::sendBlob, m_peer, data))); |
| 535 RefPtr<Bridge> protect(this); | 541 if (!waitForMethodCompletion()) |
| 536 waitForMethodCompletion(); | 542 return WebSocketChannel::SendFail; |
| 543 | |
| 537 return m_syncHelper->sendRequestResult(); | 544 return m_syncHelper->sendRequestResult(); |
| 538 } | 545 } |
| 539 | 546 |
| 540 unsigned long WorkerThreadableWebSocketChannel::Bridge::bufferedAmount() | 547 unsigned long WorkerThreadableWebSocketChannel::Bridge::bufferedAmount() |
| 541 { | 548 { |
| 542 if (!m_workerGlobalScope) | 549 if (hasTerminatedPeer()) |
| 543 return 0; | 550 return 0; |
| 544 ASSERT(m_syncHelper); | 551 |
| 552 RefPtr<Bridge> protect(this); | |
| 545 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::bufferedA mount, m_peer))); | 553 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::bufferedA mount, m_peer))); |
| 546 RefPtr<Bridge> protect(this); | 554 if (!waitForMethodCompletion()) |
| 547 waitForMethodCompletion(); | 555 return 0; |
| 556 | |
| 548 return m_syncHelper->bufferedAmount(); | 557 return m_syncHelper->bufferedAmount(); |
| 549 } | 558 } |
| 550 | 559 |
| 551 void WorkerThreadableWebSocketChannel::Bridge::close(int code, const String& rea son) | 560 void WorkerThreadableWebSocketChannel::Bridge::close(int code, const String& rea son) |
| 552 { | 561 { |
| 562 if (hasTerminatedPeer()) | |
| 563 return; | |
| 564 | |
| 553 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::close, m_ peer, code, reason.isolatedCopy()))); | 565 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::close, m_ peer, code, reason.isolatedCopy()))); |
| 554 } | 566 } |
| 555 | 567 |
| 556 void WorkerThreadableWebSocketChannel::Bridge::fail(const String& reason, Messag eLevel level, const String& sourceURL, unsigned lineNumber) | 568 void WorkerThreadableWebSocketChannel::Bridge::fail(const String& reason, Messag eLevel level, const String& sourceURL, unsigned lineNumber) |
| 557 { | 569 { |
| 570 if (hasTerminatedPeer()) | |
| 571 return; | |
| 572 | |
| 558 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::fail, m_p eer, reason.isolatedCopy(), level, sourceURL.isolatedCopy(), lineNumber))); | 573 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::fail, m_p eer, reason.isolatedCopy(), level, sourceURL.isolatedCopy(), lineNumber))); |
| 559 } | 574 } |
| 560 | 575 |
| 561 void WorkerThreadableWebSocketChannel::Bridge::disconnect() | 576 void WorkerThreadableWebSocketChannel::Bridge::disconnect() |
| 562 { | 577 { |
| 563 clearClientWrapper(); | 578 clearClientWrapper(); |
| 564 terminatePeer(); | 579 terminatePeer(); |
| 565 } | 580 } |
| 566 | 581 |
| 567 void WorkerThreadableWebSocketChannel::Bridge::suspend() | 582 void WorkerThreadableWebSocketChannel::Bridge::suspend() |
| 568 { | 583 { |
| 584 if (hasTerminatedPeer()) | |
| 585 return; | |
| 586 | |
| 569 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::suspend, m_peer))); | 587 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::suspend, m_peer))); |
| 570 } | 588 } |
| 571 | 589 |
| 572 void WorkerThreadableWebSocketChannel::Bridge::resume() | 590 void WorkerThreadableWebSocketChannel::Bridge::resume() |
| 573 { | 591 { |
| 592 if (hasTerminatedPeer()) | |
| 593 return; | |
| 594 | |
| 574 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::resume, m _peer))); | 595 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::resume, m _peer))); |
| 575 } | 596 } |
| 576 | 597 |
| 577 void WorkerThreadableWebSocketChannel::Bridge::clearClientWrapper() | 598 void WorkerThreadableWebSocketChannel::Bridge::clearClientWrapper() |
| 578 { | 599 { |
| 579 m_workerClientWrapper->clearClient(); | 600 m_workerClientWrapper->clearClient(); |
| 580 } | 601 } |
| 581 | 602 |
| 582 // Caller of this function should hold a reference to the bridge, because this f unction may call WebSocket::didClose() in the end, | 603 // Caller of this function should hold a reference to the bridge, because this f unction may call WebSocket::didClose() in the end, |
| 583 // which causes the bridge to get disconnected from the WebSocket and deleted if there is no other reference. | 604 // which causes the bridge to get disconnected from the WebSocket and deleted if there is no other reference. |
| 584 bool WorkerThreadableWebSocketChannel::Bridge::waitForMethodCompletion() | 605 bool WorkerThreadableWebSocketChannel::Bridge::waitForMethodCompletion() |
| 585 { | 606 { |
| 586 if (!m_syncHelper) | 607 ASSERT(m_workerGlobalScope); |
| 587 return true; | 608 ASSERT(m_syncHelper); |
| 588 | 609 |
| 589 blink::WebWaitableEvent* shutdownEvent = m_workerGlobalScope->thread()->shut downEvent(); | 610 blink::WebWaitableEvent* shutdownEvent = m_workerGlobalScope->thread()->shut downEvent(); |
| 590 Vector<blink::WebWaitableEvent*> events; | 611 Vector<blink::WebWaitableEvent*> events; |
| 591 events.append(shutdownEvent); | 612 events.append(shutdownEvent); |
| 592 events.append(m_syncHelper->event()); | 613 events.append(m_syncHelper->event()); |
| 593 | 614 |
| 594 ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack); | 615 ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack); |
| 595 blink::WebWaitableEvent* signalled = blink::Platform::current()->waitMultipl eEvents(events); | 616 blink::WebWaitableEvent* signalled = blink::Platform::current()->waitMultipl eEvents(events); |
| 596 return signalled != shutdownEvent; | 617 return signalled != shutdownEvent; |
| 597 } | 618 } |
| 598 | 619 |
| 599 void WorkerThreadableWebSocketChannel::Bridge::terminatePeer() | 620 void WorkerThreadableWebSocketChannel::Bridge::terminatePeer() |
| 600 { | 621 { |
| 601 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::destroy, m_peer))); | 622 m_loaderProxy.postTaskToLoader(CallClosureTask::create(bind(&Peer::destroy, m_peer))); |
| 623 // Peer::destroy() deletes m_peer and then m_syncHelper will be released. | |
| 624 // We must not touch m_syncHelper any more. | |
| 625 m_syncHelper = 0; | |
| 626 | |
| 627 // We won't use this any more. | |
| 602 m_workerGlobalScope = nullptr; | 628 m_workerGlobalScope = nullptr; |
| 603 m_syncHelper = 0; | |
| 604 } | 629 } |
| 605 | 630 |
| 606 } // namespace WebCore | 631 } // namespace WebCore |
| OLD | NEW |