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

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

Powered by Google App Engine
This is Rietveld 408576698