Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Side by Side Diff: Source/modules/websockets/WebSocket.cpp

Issue 311993006: [WebSocket] bufferedAmount should not decrease inside a task. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 220
221 const char* WebSocket::subprotocolSeperator() 221 const char* WebSocket::subprotocolSeperator()
222 { 222 {
223 return ", "; 223 return ", ";
224 } 224 }
225 225
226 WebSocket::WebSocket(ExecutionContext* context) 226 WebSocket::WebSocket(ExecutionContext* context)
227 : ActiveDOMObject(context) 227 : ActiveDOMObject(context)
228 , m_state(CONNECTING) 228 , m_state(CONNECTING)
229 , m_bufferedAmount(0) 229 , m_bufferedAmount(0)
230 , m_consumedBufferedAmount(0)
230 , m_bufferedAmountAfterClose(0) 231 , m_bufferedAmountAfterClose(0)
231 , m_binaryType(BinaryTypeBlob) 232 , m_binaryType(BinaryTypeBlob)
232 , m_subprotocol("") 233 , m_subprotocol("")
233 , m_extensions("") 234 , m_extensions("")
234 , m_eventQueue(EventQueue::create(this)) 235 , m_eventQueue(EventQueue::create(this))
236 , m_bufferedAmountConsumeTimer(this, &WebSocket::reflectBufferedAmountConsum ption)
235 { 237 {
236 ScriptWrappable::init(this); 238 ScriptWrappable::init(this);
237 } 239 }
238 240
239 WebSocket::~WebSocket() 241 WebSocket::~WebSocket()
240 { 242 {
241 ASSERT(!m_channel); 243 ASSERT(!m_channel);
242 } 244 }
243 245
244 void WebSocket::logError(const String& message) 246 void WebSocket::logError(const String& message)
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 } 367 }
366 368
367 void WebSocket::updateBufferedAmountAfterClose(unsigned long payloadSize) 369 void WebSocket::updateBufferedAmountAfterClose(unsigned long payloadSize)
368 { 370 {
369 m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, payload Size); 371 m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, payload Size);
370 m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFram ingOverhead(payloadSize)); 372 m_bufferedAmountAfterClose = saturateAdd(m_bufferedAmountAfterClose, getFram ingOverhead(payloadSize));
371 373
372 logError("WebSocket is already in CLOSING or CLOSED state."); 374 logError("WebSocket is already in CLOSING or CLOSED state.");
373 } 375 }
374 376
377 void WebSocket::reflectBufferedAmountConsumption(Timer<WebSocket>*)
378 {
379 ASSERT(m_bufferedAmount >= m_consumedBufferedAmount);
380 WTF_LOG(Network, "WebSocket %p decreaseBufferedAmount() %lu => %lu", this, m _bufferedAmount, m_bufferedAmount - m_consumedBufferedAmount);
tyoshino (SeeGerritForStatus) 2014/06/16 07:31:42 reflect
yhirano 2014/06/16 10:19:44 Done.
381
382 m_bufferedAmount -= m_consumedBufferedAmount;
383 m_consumedBufferedAmount = 0;
384 }
385
375 void WebSocket::releaseChannel() 386 void WebSocket::releaseChannel()
376 { 387 {
377 ASSERT(m_channel); 388 ASSERT(m_channel);
378 m_channel->disconnect(); 389 m_channel->disconnect();
379 m_channel = nullptr; 390 m_channel = nullptr;
380 } 391 }
381 392
382 void WebSocket::send(const String& message, ExceptionState& exceptionState) 393 void WebSocket::send(const String& message, ExceptionState& exceptionState)
383 { 394 {
384 WTF_LOG(Network, "WebSocket %p send() Sending String '%s'", this, message.ut f8().data()); 395 WTF_LOG(Network, "WebSocket %p send() Sending String '%s'", this, message.ut f8().data());
385 if (m_state == CONNECTING) { 396 if (m_state == CONNECTING) {
386 setInvalidStateErrorForSendMethod(exceptionState); 397 setInvalidStateErrorForSendMethod(exceptionState);
387 return; 398 return;
388 } 399 }
389 // No exception is raised if the connection was once established but has sub sequently been closed. 400 // No exception is raised if the connection was once established but has sub sequently been closed.
390 if (m_state == CLOSING || m_state == CLOSED) { 401 if (m_state == CLOSING || m_state == CLOSED) {
391 updateBufferedAmountAfterClose(message.utf8().length()); 402 updateBufferedAmountAfterClose(message.utf8().length());
392 return; 403 return;
393 } 404 }
394 ASSERT(m_channel); 405 ASSERT(m_channel);
406 m_bufferedAmount += message.utf8().length();
395 handleSendResult(m_channel->send(message), exceptionState, WebSocketSendType String); 407 handleSendResult(m_channel->send(message), exceptionState, WebSocketSendType String);
396 } 408 }
397 409
398 void WebSocket::send(ArrayBuffer* binaryData, ExceptionState& exceptionState) 410 void WebSocket::send(ArrayBuffer* binaryData, ExceptionState& exceptionState)
399 { 411 {
400 WTF_LOG(Network, "WebSocket %p send() Sending ArrayBuffer %p", this, binaryD ata); 412 WTF_LOG(Network, "WebSocket %p send() Sending ArrayBuffer %p", this, binaryD ata);
401 ASSERT(binaryData); 413 ASSERT(binaryData);
402 if (m_state == CONNECTING) { 414 if (m_state == CONNECTING) {
403 setInvalidStateErrorForSendMethod(exceptionState); 415 setInvalidStateErrorForSendMethod(exceptionState);
404 return; 416 return;
405 } 417 }
406 if (m_state == CLOSING || m_state == CLOSED) { 418 if (m_state == CLOSING || m_state == CLOSED) {
407 updateBufferedAmountAfterClose(binaryData->byteLength()); 419 updateBufferedAmountAfterClose(binaryData->byteLength());
408 return; 420 return;
409 } 421 }
410 ASSERT(m_channel); 422 ASSERT(m_channel);
423 m_bufferedAmount += binaryData->byteLength();
411 handleSendResult(m_channel->send(*binaryData, 0, binaryData->byteLength()), exceptionState, WebSocketSendTypeArrayBuffer); 424 handleSendResult(m_channel->send(*binaryData, 0, binaryData->byteLength()), exceptionState, WebSocketSendTypeArrayBuffer);
412 } 425 }
413 426
414 void WebSocket::send(ArrayBufferView* arrayBufferView, ExceptionState& exception State) 427 void WebSocket::send(ArrayBufferView* arrayBufferView, ExceptionState& exception State)
415 { 428 {
416 WTF_LOG(Network, "WebSocket %p send() Sending ArrayBufferView %p", this, arr ayBufferView); 429 WTF_LOG(Network, "WebSocket %p send() Sending ArrayBufferView %p", this, arr ayBufferView);
417 ASSERT(arrayBufferView); 430 ASSERT(arrayBufferView);
418 if (m_state == CONNECTING) { 431 if (m_state == CONNECTING) {
419 setInvalidStateErrorForSendMethod(exceptionState); 432 setInvalidStateErrorForSendMethod(exceptionState);
420 return; 433 return;
421 } 434 }
422 if (m_state == CLOSING || m_state == CLOSED) { 435 if (m_state == CLOSING || m_state == CLOSED) {
423 updateBufferedAmountAfterClose(arrayBufferView->byteLength()); 436 updateBufferedAmountAfterClose(arrayBufferView->byteLength());
424 return; 437 return;
425 } 438 }
426 ASSERT(m_channel); 439 ASSERT(m_channel);
440 m_bufferedAmount += arrayBufferView->byteLength();
427 RefPtr<ArrayBuffer> arrayBuffer(arrayBufferView->buffer()); 441 RefPtr<ArrayBuffer> arrayBuffer(arrayBufferView->buffer());
428 handleSendResult(m_channel->send(*arrayBuffer, arrayBufferView->byteOffset() , arrayBufferView->byteLength()), exceptionState, WebSocketSendTypeArrayBufferVi ew); 442 handleSendResult(m_channel->send(*arrayBuffer, arrayBufferView->byteOffset() , arrayBufferView->byteLength()), exceptionState, WebSocketSendTypeArrayBufferVi ew);
429 } 443 }
430 444
431 void WebSocket::send(Blob* binaryData, ExceptionState& exceptionState) 445 void WebSocket::send(Blob* binaryData, ExceptionState& exceptionState)
432 { 446 {
433 WTF_LOG(Network, "WebSocket %p send() Sending Blob '%s'", this, binaryData-> uuid().utf8().data()); 447 WTF_LOG(Network, "WebSocket %p send() Sending Blob '%s'", this, binaryData-> uuid().utf8().data());
434 ASSERT(binaryData); 448 ASSERT(binaryData);
435 if (m_state == CONNECTING) { 449 if (m_state == CONNECTING) {
436 setInvalidStateErrorForSendMethod(exceptionState); 450 setInvalidStateErrorForSendMethod(exceptionState);
437 return; 451 return;
438 } 452 }
439 if (m_state == CLOSING || m_state == CLOSED) { 453 if (m_state == CLOSING || m_state == CLOSED) {
440 updateBufferedAmountAfterClose(static_cast<unsigned long>(binaryData->si ze())); 454 updateBufferedAmountAfterClose(static_cast<unsigned long>(binaryData->si ze()));
441 return; 455 return;
442 } 456 }
457 m_bufferedAmount += binaryData->size();
443 ASSERT(m_channel); 458 ASSERT(m_channel);
444 handleSendResult(m_channel->send(binaryData->blobDataHandle()), exceptionSta te, WebSocketSendTypeBlob); 459 handleSendResult(m_channel->send(binaryData->blobDataHandle()), exceptionSta te, WebSocketSendTypeBlob);
445 } 460 }
446 461
447 void WebSocket::close(unsigned short code, const String& reason, ExceptionState& exceptionState) 462 void WebSocket::close(unsigned short code, const String& reason, ExceptionState& exceptionState)
448 { 463 {
449 closeInternal(code, reason, exceptionState); 464 closeInternal(code, reason, exceptionState);
450 } 465 }
451 466
452 void WebSocket::close(ExceptionState& exceptionState) 467 void WebSocket::close(ExceptionState& exceptionState)
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 } 647 }
633 } 648 }
634 649
635 void WebSocket::didReceiveMessageError() 650 void WebSocket::didReceiveMessageError()
636 { 651 {
637 WTF_LOG(Network, "WebSocket %p didReceiveMessageError()", this); 652 WTF_LOG(Network, "WebSocket %p didReceiveMessageError()", this);
638 m_state = CLOSED; 653 m_state = CLOSED;
639 m_eventQueue->dispatch(Event::create(EventTypeNames::error)); 654 m_eventQueue->dispatch(Event::create(EventTypeNames::error));
640 } 655 }
641 656
642 void WebSocket::didUpdateBufferedAmount(unsigned long bufferedAmount) 657 void WebSocket::didConsumeBufferedAmount(unsigned long consumed)
643 { 658 {
644 WTF_LOG(Network, "WebSocket %p didUpdateBufferedAmount() New bufferedAmount is %lu", this, bufferedAmount); 659 ASSERT(m_bufferedAmount >= consumed);
660 WTF_LOG(Network, "WebSocket %p didConsumeBufferedAmount(%lu)", this, consume d);
645 if (m_state == CLOSED) 661 if (m_state == CLOSED)
646 return; 662 return;
647 m_bufferedAmount = bufferedAmount; 663 m_consumedBufferedAmount += consumed;
664 if (!m_bufferedAmountConsumeTimer.isActive())
665 m_bufferedAmountConsumeTimer.startOneShot(0, FROM_HERE);
648 } 666 }
649 667
650 void WebSocket::didStartClosingHandshake() 668 void WebSocket::didStartClosingHandshake()
651 { 669 {
652 WTF_LOG(Network, "WebSocket %p didStartClosingHandshake()", this); 670 WTF_LOG(Network, "WebSocket %p didStartClosingHandshake()", this);
653 m_state = CLOSING; 671 m_state = CLOSING;
654 } 672 }
655 673
656 void WebSocket::didClose(unsigned long unhandledBufferedAmount, ClosingHandshake CompletionStatus closingHandshakeCompletion, unsigned short code, const String& reason) 674 void WebSocket::didClose(ClosingHandshakeCompletionStatus closingHandshakeComple tion, unsigned short code, const String& reason)
657 { 675 {
658 WTF_LOG(Network, "WebSocket %p didClose()", this); 676 WTF_LOG(Network, "WebSocket %p didClose()", this);
659 if (!m_channel) 677 if (!m_channel)
660 return; 678 return;
661 bool wasClean = m_state == CLOSING && !unhandledBufferedAmount && closingHan dshakeCompletion == ClosingHandshakeComplete && code != WebSocketChannel::CloseE ventCodeAbnormalClosure; 679 m_bufferedAmount -= m_consumedBufferedAmount;
tyoshino (SeeGerritForStatus) 2014/06/16 07:31:42 doesn't updating m_bufferedAmount here violate the
yhirano 2014/06/16 10:19:44 The spec says: The bufferedAmount attribute must r
yhirano 2014/06/16 11:53:23 Done.
680 m_consumedBufferedAmount = 0;
681 bool hasAllDataConsumed = !m_bufferedAmount;
682 bool wasClean = m_state == CLOSING && hasAllDataConsumed && closingHandshake Completion == ClosingHandshakeComplete && code != WebSocketChannel::CloseEventCo deAbnormalClosure;
683 m_state = CLOSED;
662 684
663 m_state = CLOSED;
664 m_bufferedAmount = unhandledBufferedAmount;
665 m_eventQueue->dispatch(CloseEvent::create(wasClean, code, reason)); 685 m_eventQueue->dispatch(CloseEvent::create(wasClean, code, reason));
666 releaseChannel(); 686 releaseChannel();
667 } 687 }
668 688
669 size_t WebSocket::getFramingOverhead(size_t payloadSize) 689 size_t WebSocket::getFramingOverhead(size_t payloadSize)
670 { 690 {
671 static const size_t hybiBaseFramingOverhead = 2; // Every frame has at least two-byte header. 691 static const size_t hybiBaseFramingOverhead = 2; // Every frame has at least two-byte header.
672 static const size_t hybiMaskingKeyLength = 4; // Every frame from client mus t have masking key. 692 static const size_t hybiMaskingKeyLength = 4; // Every frame from client mus t have masking key.
673 static const size_t minimumPayloadSizeWithTwoByteExtendedPayloadLength = 126 ; 693 static const size_t minimumPayloadSizeWithTwoByteExtendedPayloadLength = 126 ;
674 static const size_t minimumPayloadSizeWithEightByteExtendedPayloadLength = 0 x10000; 694 static const size_t minimumPayloadSizeWithEightByteExtendedPayloadLength = 0 x10000;
675 size_t overhead = hybiBaseFramingOverhead + hybiMaskingKeyLength; 695 size_t overhead = hybiBaseFramingOverhead + hybiMaskingKeyLength;
676 if (payloadSize >= minimumPayloadSizeWithEightByteExtendedPayloadLength) 696 if (payloadSize >= minimumPayloadSizeWithEightByteExtendedPayloadLength)
677 overhead += 8; 697 overhead += 8;
678 else if (payloadSize >= minimumPayloadSizeWithTwoByteExtendedPayloadLength) 698 else if (payloadSize >= minimumPayloadSizeWithTwoByteExtendedPayloadLength)
679 overhead += 2; 699 overhead += 2;
680 return overhead; 700 return overhead;
681 } 701 }
682 702
683 void WebSocket::trace(Visitor* visitor) 703 void WebSocket::trace(Visitor* visitor)
684 { 704 {
685 visitor->trace(m_channel); 705 visitor->trace(m_channel);
686 visitor->trace(m_eventQueue); 706 visitor->trace(m_eventQueue);
687 EventTargetWithInlineData::trace(visitor); 707 EventTargetWithInlineData::trace(visitor);
688 } 708 }
689 709
690 } // namespace WebCore 710 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698