Commit cd9e2f9f authored by Adam Rice's avatar Adam Rice Committed by Commit Bot

[WebSocket] Don't use timers to post tasks

Replace the use of zero-length timers in blink::DOMWebSocket with direct
use of the PostTask API. This slightly improves clarity and efficiency.

BUG=856651

Change-Id: Ib6003fb9861a59513477eafcaa07e02eacef1271
Reviewed-on: https://chromium-review.googlesource.com/1151045
Commit-Queue: Adam Rice <ricea@chromium.org>
Reviewed-by: default avatarYutaka Hirano <yhirano@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580053}
parent 9659ddbb
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "third_party/blink/renderer/modules/websockets/dom_websocket.h" #include "third_party/blink/renderer/modules/websockets/dom_websocket.h"
#include "base/location.h"
#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_insecure_request_policy.h" #include "third_party/blink/public/platform/web_insecure_request_policy.h"
...@@ -51,6 +52,7 @@ ...@@ -51,6 +52,7 @@
#include "third_party/blink/renderer/modules/websockets/close_event.h" #include "third_party/blink/renderer/modules/websockets/close_event.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h" #include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/histogram.h" #include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/network/network_log.h" #include "third_party/blink/renderer/platform/network/network_log.h"
#include "third_party/blink/renderer/platform/weborigin/known_ports.h" #include "third_party/blink/renderer/platform/weborigin/known_ports.h"
...@@ -69,12 +71,7 @@ static const char kWebSocketSubprotocolSeparator[] = ", "; ...@@ -69,12 +71,7 @@ static const char kWebSocketSubprotocolSeparator[] = ", ";
namespace blink { namespace blink {
DOMWebSocket::EventQueue::EventQueue(EventTarget* target) DOMWebSocket::EventQueue::EventQueue(EventTarget* target)
: state_(kActive), : state_(kActive), target_(target) {}
target_(target),
resume_timer_(
target->GetExecutionContext()->GetTaskRunner(TaskType::kWebSocket),
this,
&EventQueue::ResumeTimerFired) {}
DOMWebSocket::EventQueue::~EventQueue() { DOMWebSocket::EventQueue::~EventQueue() {
ContextDestroyed(); ContextDestroyed();
...@@ -88,6 +85,7 @@ void DOMWebSocket::EventQueue::Dispatch(Event* event) { ...@@ -88,6 +85,7 @@ void DOMWebSocket::EventQueue::Dispatch(Event* event) {
target_->DispatchEvent(event); target_->DispatchEvent(event);
break; break;
case kPaused: case kPaused:
case kUnpausePosted:
events_.push_back(event); events_.push_back(event);
break; break;
case kStopped: case kStopped:
...@@ -102,18 +100,21 @@ bool DOMWebSocket::EventQueue::IsEmpty() const { ...@@ -102,18 +100,21 @@ bool DOMWebSocket::EventQueue::IsEmpty() const {
} }
void DOMWebSocket::EventQueue::Pause() { void DOMWebSocket::EventQueue::Pause() {
resume_timer_.Stop(); if (state_ != kActive && state_ != kUnpausePosted)
if (state_ != kActive)
return; return;
state_ = kPaused; state_ = kPaused;
} }
void DOMWebSocket::EventQueue::Unpause() { void DOMWebSocket::EventQueue::Unpause() {
if (state_ != kPaused || resume_timer_.IsActive()) if (state_ != kPaused || state_ == kUnpausePosted)
return; return;
resume_timer_.StartOneShot(TimeDelta(), FROM_HERE); state_ = kUnpausePosted;
target_->GetExecutionContext()
->GetTaskRunner(TaskType::kWebSocket)
->PostTask(FROM_HERE,
WTF::Bind(&EventQueue::UnpauseTask, WrapWeakPersistent(this)));
} }
void DOMWebSocket::EventQueue::ContextDestroyed() { void DOMWebSocket::EventQueue::ContextDestroyed() {
...@@ -121,7 +122,6 @@ void DOMWebSocket::EventQueue::ContextDestroyed() { ...@@ -121,7 +122,6 @@ void DOMWebSocket::EventQueue::ContextDestroyed() {
return; return;
state_ = kStopped; state_ = kStopped;
resume_timer_.Stop();
events_.clear(); events_.clear();
} }
...@@ -132,22 +132,23 @@ void DOMWebSocket::EventQueue::DispatchQueuedEvents() { ...@@ -132,22 +132,23 @@ void DOMWebSocket::EventQueue::DispatchQueuedEvents() {
HeapDeque<Member<Event>> events; HeapDeque<Member<Event>> events;
events.Swap(events_); events.Swap(events_);
while (!events.IsEmpty()) { while (!events.IsEmpty()) {
if (state_ == kStopped || state_ == kPaused) if (state_ == kStopped || state_ == kPaused || state_ == kUnpausePosted)
break; break;
DCHECK_EQ(state_, kActive); DCHECK_EQ(state_, kActive);
DCHECK(target_->GetExecutionContext()); DCHECK(target_->GetExecutionContext());
target_->DispatchEvent(events.TakeFirst()); target_->DispatchEvent(events.TakeFirst());
// |this| can be stopped here. // |this| can be stopped here.
} }
if (state_ == kPaused) { if (state_ == kPaused || state_ == kUnpausePosted) {
while (!events_.IsEmpty()) while (!events_.IsEmpty())
events.push_back(events_.TakeFirst()); events.push_back(events_.TakeFirst());
events.Swap(events_); events.Swap(events_);
} }
} }
void DOMWebSocket::EventQueue::ResumeTimerFired(TimerBase*) { void DOMWebSocket::EventQueue::UnpauseTask() {
DCHECK_EQ(state_, kPaused); if (state_ != kUnpausePosted)
return;
state_ = kActive; state_ = kActive;
DispatchQueuedEvents(); DispatchQueuedEvents();
} }
...@@ -226,10 +227,7 @@ DOMWebSocket::DOMWebSocket(ExecutionContext* context) ...@@ -226,10 +227,7 @@ DOMWebSocket::DOMWebSocket(ExecutionContext* context)
subprotocol_(""), subprotocol_(""),
extensions_(""), extensions_(""),
event_queue_(EventQueue::Create(this)), event_queue_(EventQueue::Create(this)),
buffered_amount_consume_timer_( buffered_amount_update_task_pending_(false) {}
context->GetTaskRunner(TaskType::kWebSocket),
this,
&DOMWebSocket::ReflectBufferedAmountConsumption) {}
DOMWebSocket::~DOMWebSocket() { DOMWebSocket::~DOMWebSocket() {
DCHECK(!channel_); DCHECK(!channel_);
...@@ -393,7 +391,12 @@ void DOMWebSocket::UpdateBufferedAmountAfterClose(uint64_t payload_size) { ...@@ -393,7 +391,12 @@ void DOMWebSocket::UpdateBufferedAmountAfterClose(uint64_t payload_size) {
LogError("WebSocket is already in CLOSING or CLOSED state."); LogError("WebSocket is already in CLOSING or CLOSED state.");
} }
void DOMWebSocket::ReflectBufferedAmountConsumption(TimerBase*) { void DOMWebSocket::BufferedAmountUpdateTask() {
buffered_amount_update_task_pending_ = false;
ReflectBufferedAmountConsumption();
}
void DOMWebSocket::ReflectBufferedAmountConsumption() {
DCHECK_GE(buffered_amount_, consumed_buffered_amount_); DCHECK_GE(buffered_amount_, consumed_buffered_amount_);
// Cast to unsigned long long is required since clang doesn't accept // Cast to unsigned long long is required since clang doesn't accept
// combination of %llu and uint64_t (known as unsigned long). // combination of %llu and uint64_t (known as unsigned long).
...@@ -727,8 +730,12 @@ void DOMWebSocket::DidConsumeBufferedAmount(uint64_t consumed) { ...@@ -727,8 +730,12 @@ void DOMWebSocket::DidConsumeBufferedAmount(uint64_t consumed) {
if (state_ == kClosed) if (state_ == kClosed)
return; return;
consumed_buffered_amount_ += consumed; consumed_buffered_amount_ += consumed;
if (!buffered_amount_consume_timer_.IsActive()) if (buffered_amount_update_task_pending_)
buffered_amount_consume_timer_.StartOneShot(TimeDelta(), FROM_HERE); return;
GetExecutionContext()
->GetTaskRunner(TaskType::kWebSocket)
->PostTask(FROM_HERE, WTF::Bind(&DOMWebSocket::BufferedAmountUpdateTask,
WrapWeakPersistent(this)));
} }
void DOMWebSocket::DidStartClosingHandshake() { void DOMWebSocket::DidStartClosingHandshake() {
......
...@@ -174,6 +174,7 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData, ...@@ -174,6 +174,7 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
enum State { enum State {
kActive, kActive,
kPaused, kPaused,
kUnpausePosted,
kStopped, kStopped,
}; };
...@@ -182,12 +183,11 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData, ...@@ -182,12 +183,11 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
// Dispatches queued events if this queue is active. // Dispatches queued events if this queue is active.
// Does nothing otherwise. // Does nothing otherwise.
void DispatchQueuedEvents(); void DispatchQueuedEvents();
void ResumeTimerFired(TimerBase*); void UnpauseTask();
State state_; State state_;
Member<EventTarget> target_; Member<EventTarget> target_;
HeapDeque<Member<Event>> events_; HeapDeque<Member<Event>> events_;
TaskRunnerTimer<EventQueue> resume_timer_;
}; };
enum WebSocketSendType { enum WebSocketSendType {
...@@ -225,7 +225,8 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData, ...@@ -225,7 +225,8 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
// Updates |buffered_amount_after_close_| given the amount of data passed to // Updates |buffered_amount_after_close_| given the amount of data passed to
// send() method after the state changed to CLOSING or CLOSED. // send() method after the state changed to CLOSING or CLOSED.
void UpdateBufferedAmountAfterClose(uint64_t); void UpdateBufferedAmountAfterClose(uint64_t);
void ReflectBufferedAmountConsumption(TimerBase*); void BufferedAmountUpdateTask();
void ReflectBufferedAmountConsumption();
void ReleaseChannel(); void ReleaseChannel();
void RecordSendTypeHistogram(WebSocketSendType); void RecordSendTypeHistogram(WebSocketSendType);
...@@ -251,7 +252,8 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData, ...@@ -251,7 +252,8 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData,
String extensions_; String extensions_;
Member<EventQueue> event_queue_; Member<EventQueue> event_queue_;
TaskRunnerTimer<DOMWebSocket> buffered_amount_consume_timer_;
bool buffered_amount_update_task_pending_;
}; };
} // namespace blink } // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment