Commit 9a17290b authored by Hayato Ito's avatar Hayato Ito Committed by Commit Bot

ServiceWorkerEventQueue: Prefer separate functions to one PushTask(Task) function

Follow-up of the review comment:
https://crrev.com/c/1906452/6/third_party/blink/renderer/modules/service_worker/service_worker_timeout_timer.h#109

Prefer separate functions, EnqueueNormal(...) and EnqueuePending(...),
to just one PushTask(Task) function, so that callers don't have to
create a Task on caller sides.

This CL also renames ServiceWorkerEventQueue::Task to
ServiceWorkerEventQueue::Event, and does necessary changes accordingly.
We no longer use a word of *task* in ServiceWorkerEventQueue because using
both tasks and events in ServiceWorkerEventQueue is slightly confusing.
It would be better to use Event consistently because its meaning is clear
in this context.

Bug: 965802

Change-Id: I18b133429e4636eef69cfc4e79c33b13be978ef7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1948368
Commit-Queue: Hayato Ito <hayato@chromium.org>
Reviewed-by: default avatarMakoto Shimazu <shimazu@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#721885}
parent d32dda5b
......@@ -80,61 +80,73 @@ void ServiceWorkerEventQueue::Start() {
WTF::Unretained(this)));
}
void ServiceWorkerEventQueue::PushTask(std::unique_ptr<Task> task) {
DCHECK(task->type != Task::Type::Pending || did_idle_timeout());
bool can_start_processing_tasks =
!processing_tasks_ && task->type != Task::Type::Pending;
task_queue_.emplace_back(std::move(task));
if (!can_start_processing_tasks)
void ServiceWorkerEventQueue::EnqueueNormal(
StartCallback start_callback,
AbortCallback abort_callback,
base::Optional<base::TimeDelta> custom_timeout) {
EnqueueEvent(std::make_unique<Event>(
Event::Type::Normal, std::move(start_callback), std::move(abort_callback),
std::move(custom_timeout)));
}
void ServiceWorkerEventQueue::EnqueuePending(
StartCallback start_callback,
AbortCallback abort_callback,
base::Optional<base::TimeDelta> custom_timeout) {
EnqueueEvent(std::make_unique<Event>(
Event::Type::Pending, std::move(start_callback),
std::move(abort_callback), std::move(custom_timeout)));
}
void ServiceWorkerEventQueue::EnqueueEvent(std::unique_ptr<Event> event) {
DCHECK(event->type != Event::Type::Pending || did_idle_timeout());
bool can_start_processing_events =
!processing_events_ && event->type != Event::Type::Pending;
queue_.emplace_back(std::move(event));
if (!can_start_processing_events)
return;
if (did_idle_timeout()) {
idle_time_ = base::TimeTicks();
did_idle_timeout_ = false;
}
ProcessTasks();
ProcessEvents();
}
void ServiceWorkerEventQueue::ProcessTasks() {
DCHECK(!processing_tasks_);
processing_tasks_ = true;
while (!task_queue_.IsEmpty()) {
StartTask(task_queue_.TakeFirst());
void ServiceWorkerEventQueue::ProcessEvents() {
DCHECK(!processing_events_);
processing_events_ = true;
while (!queue_.IsEmpty()) {
StartEvent(queue_.TakeFirst());
}
processing_tasks_ = false;
processing_events_ = false;
// We have to check HasInflightEvent() and may trigger
// OnNoInflightEvent() here because StartTask() can call EndEvent()
// OnNoInflightEvent() here because StartEvent() can call EndEvent()
// synchronously, and EndEvent() never triggers OnNoInflightEvent()
// while ProcessTasks() is running.
// while ProcessEvents() is running.
if (!HasInflightEvent())
OnNoInflightEvent();
}
void ServiceWorkerEventQueue::StartTask(std::unique_ptr<Task> task) {
int event_id = StartEvent(std::move(task->abort_callback),
task->custom_timeout.value_or(kEventTimeout));
std::move(task->start_callback).Run(event_id);
}
int ServiceWorkerEventQueue::StartEvent(AbortCallback abort_callback,
base::TimeDelta timeout) {
void ServiceWorkerEventQueue::StartEvent(std::unique_ptr<Event> event) {
idle_time_ = base::TimeTicks();
const int event_id = NextEventId();
auto add_result = id_event_map_.insert(
DCHECK(!HasEvent(event_id));
id_event_map_.insert(
event_id, std::make_unique<EventInfo>(
tick_clock_->NowTicks() + timeout,
WTF::Bind(std::move(abort_callback), event_id)));
DCHECK(add_result.is_new_entry);
return event_id;
tick_clock_->NowTicks() +
event->custom_timeout.value_or(kEventTimeout),
WTF::Bind(std::move(event->abort_callback), event_id)));
std::move(event->start_callback).Run(event_id);
}
void ServiceWorkerEventQueue::EndEvent(int event_id) {
DCHECK(HasEvent(event_id));
id_event_map_.erase(event_id);
// Check |processing_tasks_| here because EndEvent() can be called
// synchronously in StartTask(). We don't want to trigger
// OnNoInflightEvent() while ProcessTasks() is running.
if (!processing_tasks_ && !HasInflightEvent())
// Check |processing_events_| here because EndEvent() can be called
// synchronously in StartEvent(). We don't want to trigger
// OnNoInflightEvent() while ProcessEvents() is running.
if (!processing_events_ && !HasInflightEvent())
OnNoInflightEvent();
}
......@@ -207,8 +219,8 @@ bool ServiceWorkerEventQueue::HasInflightEvent() const {
return !id_event_map_.IsEmpty() || num_of_stay_awake_tokens_ > 0;
}
ServiceWorkerEventQueue::Task::Task(
ServiceWorkerEventQueue::Task::Type type,
ServiceWorkerEventQueue::Event::Event(
ServiceWorkerEventQueue::Event::Type type,
StartCallback start_callback,
AbortCallback abort_callback,
base::Optional<base::TimeDelta> custom_timeout)
......@@ -217,7 +229,7 @@ ServiceWorkerEventQueue::Task::Task(
abort_callback(std::move(abort_callback)),
custom_timeout(custom_timeout) {}
ServiceWorkerEventQueue::Task::~Task() = default;
ServiceWorkerEventQueue::Event::~Event() = default;
ServiceWorkerEventQueue::EventInfo::EventInfo(
base::TimeTicks expiration_time,
......
......@@ -24,8 +24,11 @@ class TickClock;
namespace blink {
// ServiceWorkerEventQueue manages two types of timeouts: the long standing
// event timeout and the idle timeout.
// ServiceWorkerEventQueue manages events dispatched on ServiceWorkerGlobalScope
// and their timeouts.
//
// There are two types of timeouts: the long standing event timeout
// and the idle timeout.
//
// 1) Event timeout: when an event starts, StartEvent() records the expiration
// time of the event (kEventTimeout). If EndEvent() has not been called within
......@@ -70,45 +73,20 @@ class MODULES_EXPORT ServiceWorkerEventQueue {
using StartCallback = base::OnceCallback<void(int /* event_id */)>;
// Represents an event dispatch task, which can be queued into |task_queue_|.
struct MODULES_EXPORT Task {
enum class Type {
// A normal task is pushed to the end of the task queue and triggers
// processing of the queue.
Normal,
// A pending task, which does not start until a normal task is
// pushed. A pending task should be used if the idle timeout
// occurred (did_idle_timeout() returns true). In practice, the
// caller pushes pending tasks after the service worker
// requested the browser to terminate it due to idleness. These
// tasks run once PushTask() is called due to a new event from
// the browser, signalling that the browser decided not to
// terminate the worker.
Pending,
};
Task(Type type,
StartCallback start_callback,
AbortCallback abort_callback,
base::Optional<base::TimeDelta> custom_timeout);
~Task();
Type type;
// Callback which is run when the event_queue starts this task. The
// callback receives |event_id|, which is the result of
// StartEvent(). When an event finishes, EndEvent() should be
// called with the given |event_id|.
StartCallback start_callback;
// Callback which is run when the event_queue aborts a started task.
AbortCallback abort_callback;
// The custom timeout value.
base::Optional<base::TimeDelta> custom_timeout;
};
// EndEvent() must be called when an event finishes, with |event_id|
// which StartCallback received.
void EndEvent(int event_id);
// Push the task to the queue, and tasks in the queue can run synchronously.
// See also Task's comment.
void PushTask(std::unique_ptr<Task> task);
// Enqueues a Normal event. See ServiceWorkerEventQueue::Event to know the
// meaning of each parameter.
void EnqueueNormal(StartCallback start_callback,
AbortCallback abort_callback,
base::Optional<base::TimeDelta> custom_timeout);
// Similar to EnqueueNormal(), but enqueues a Pending event.
void EnqueuePending(StartCallback start_callback,
AbortCallback abort_callback,
base::Optional<base::TimeDelta> custom_timeout);
// Returns true if |event_id| was started and hasn't ended.
bool HasEvent(int event_id) const;
......@@ -140,10 +118,45 @@ class MODULES_EXPORT ServiceWorkerEventQueue {
base::TimeDelta::FromSeconds(30);
private:
// StartEvent() should be called at the beginning of an event. It returns an
// event id, which is unique among threads in the same process.
// The event id should be passed to EndEvent() when the event has finished.
int StartEvent(AbortCallback abort_callback, base::TimeDelta timeout);
// Represents an event dispatch, which can be queued into |queue_|.
struct Event {
enum class Type {
// A normal event is enqueued to the end of the event queue and
// triggers processing of the queue.
Normal,
// A pending event which does not start until a normal event is
// pushed. A pending event should be used if the idle timeout
// occurred (did_idle_timeout() returns true). In practice, the
// caller enqueues pending events after the service worker
// requested the browser to terminate it due to idleness. These
// events run when a new event comes from the browser,
// signalling that the browser decided not to terminate the
// worker.
Pending,
};
Event(Type type,
StartCallback start_callback,
AbortCallback abort_callback,
base::Optional<base::TimeDelta> custom_timeout);
~Event();
Type type;
// Callback which is run when the event queue starts this event. The
// callback receives |event_id|. When an event finishes,
// EndEvent() should be called with the given |event_id|.
StartCallback start_callback;
// Callback which is run when a started event is aborted.
AbortCallback abort_callback;
// The custom timeout value.
base::Optional<base::TimeDelta> custom_timeout;
};
// Enqueues the event to |queue_|, and run events in the queue or sometimes
// later synchronously, depending on the type of events.
void EnqueueEvent(std::unique_ptr<Event> event);
// Starts a single event.
void StartEvent(std::unique_ptr<Event> event);
// Updates the internal states and fires timeout callbacks if any.
void UpdateStatus();
......@@ -159,11 +172,8 @@ class MODULES_EXPORT ServiceWorkerEventQueue {
// Returns true if there are running events.
bool HasInflightEvent() const;
// Processes all tasks in |task_queue_|.
void ProcessTasks();
// Start a single task.
void StartTask(std::unique_ptr<Task> task);
// Processes all events in |queue_|.
void ProcessEvents();
struct EventInfo {
EventInfo(base::TimeTicks expiration_time,
......@@ -195,13 +205,13 @@ class MODULES_EXPORT ServiceWorkerEventQueue {
// StartEvent() is called.
bool did_idle_timeout_ = false;
// Tasks that are to be run in the next ProcessTasks() call.
Deque<std::unique_ptr<Task>> task_queue_;
// Event queue to where all events are enqueued.
Deque<std::unique_ptr<Event>> queue_;
// Set to true during running ProcessTasks(). This is used for avoiding to
// invoke |idle_callback_| or to re-enter ProcessTasks() when calling
// ProcessTasks().
bool processing_tasks_ = false;
// Set to true during running ProcessEvents(). This is used for avoiding to
// invoke |idle_callback_| or to re-enter ProcessEvents() when calling
// ProcessEvents().
bool processing_events_ = false;
// The number of the living StayAwakeToken. See also class comments.
int num_of_stay_awake_tokens_ = 0;
......
......@@ -32,31 +32,48 @@ class MockEvent {
bool Started() const { return event_id_.has_value(); }
std::unique_ptr<ServiceWorkerEventQueue::Task> CreateTask() {
return std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
void EnqueueTo(ServiceWorkerEventQueue* event_queue) {
event_queue->EnqueueNormal(
WTF::Bind(&MockEvent::Start, weak_factory_.GetWeakPtr()),
WTF::Bind(&MockEvent::Abort, weak_factory_.GetWeakPtr()),
base::nullopt);
}
std::unique_ptr<ServiceWorkerEventQueue::Task> CreatePendingTask() {
return std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Pending,
void EnqueuePendingTo(ServiceWorkerEventQueue* event_queue) {
event_queue->EnqueuePending(
WTF::Bind(&MockEvent::Start, weak_factory_.GetWeakPtr()),
WTF::Bind(&MockEvent::Abort, weak_factory_.GetWeakPtr()),
base::nullopt);
}
std::unique_ptr<ServiceWorkerEventQueue::Task> CreateTaskWithCustomTimeout(
base::TimeDelta custom_timeout) {
return std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
void EnqueueWithCustomTimeoutTo(ServiceWorkerEventQueue* event_queue,
base::TimeDelta custom_timeout) {
event_queue->EnqueueNormal(
WTF::Bind(&MockEvent::Start, weak_factory_.GetWeakPtr()),
WTF::Bind(&MockEvent::Abort, weak_factory_.GetWeakPtr()),
custom_timeout);
}
void EnqueuePendingDispatchingEventTo(ServiceWorkerEventQueue* event_queue,
String tag,
Vector<String>* out_tags) {
event_queue->EnqueuePending(
WTF::Bind(
[](ServiceWorkerEventQueue* event_queue, MockEvent* event,
String tag, Vector<String>* out_tags, int /* event id */) {
event->EnqueueTo(event_queue);
EXPECT_FALSE(event_queue->did_idle_timeout());
// Event dispatched inside of a pending event should not run
// immediately.
EXPECT_FALSE(event->Started());
EXPECT_FALSE(event->status().has_value());
out_tags->emplace_back(std::move(tag));
},
WTF::Unretained(event_queue), WTF::Unretained(this), std::move(tag),
WTF::Unretained(out_tags)),
base::DoNothing(), base::nullopt);
}
private:
void Start(int event_id) {
EXPECT_FALSE(Started());
......@@ -79,29 +96,6 @@ base::RepeatingClosure CreateReceiverWithCalledFlag(bool* out_is_called) {
WTF::Unretained(out_is_called));
}
std::unique_ptr<ServiceWorkerEventQueue::Task>
CreatePendingTaskDispatchingEvent(ServiceWorkerEventQueue* event_queue,
MockEvent* event,
String tag,
Vector<String>* out_tags) {
return std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Pending,
WTF::Bind(
[](ServiceWorkerEventQueue* event_queue, MockEvent* event, String tag,
Vector<String>* out_tags, int /* event id */) {
event_queue->PushTask(event->CreateTask());
EXPECT_FALSE(event_queue->did_idle_timeout());
// Event dispatched inside of a pending task should not run
// immediately.
EXPECT_FALSE(event->Started());
EXPECT_FALSE(event->status().has_value());
out_tags->emplace_back(std::move(tag));
},
WTF::Unretained(event_queue), WTF::Unretained(event), std::move(tag),
WTF::Unretained(out_tags)),
base::DoNothing(), base::nullopt);
}
} // namespace
using StayAwakeToken = ServiceWorkerEventQueue::StayAwakeToken;
......@@ -133,49 +127,49 @@ TEST_F(ServiceWorkerEventQueueTest, IdleTimer) {
base::TimeDelta::FromSeconds(1);
bool is_idle = false;
ServiceWorkerEventQueue timer(CreateReceiverWithCalledFlag(&is_idle),
task_runner()->GetMockTickClock());
ServiceWorkerEventQueue event_queue(CreateReceiverWithCalledFlag(&is_idle),
task_runner()->GetMockTickClock());
task_runner()->FastForwardBy(kIdleInterval);
// Nothing should happen since the event queue has not started yet.
EXPECT_FALSE(is_idle);
timer.Start();
event_queue.Start();
task_runner()->FastForwardBy(kIdleInterval);
// |idle_callback| should be fired since there is no event.
EXPECT_TRUE(is_idle);
is_idle = false;
MockEvent event1;
timer.PushTask(event1.CreateTask());
event1.EnqueueTo(&event_queue);
task_runner()->FastForwardBy(kIdleInterval);
// Nothing happens since there is an inflight event.
EXPECT_FALSE(is_idle);
MockEvent event2;
timer.PushTask(event2.CreateTask());
event2.EnqueueTo(&event_queue);
task_runner()->FastForwardBy(kIdleInterval);
// Nothing happens since there are two inflight events.
EXPECT_FALSE(is_idle);
timer.EndEvent(event2.event_id());
event_queue.EndEvent(event2.event_id());
task_runner()->FastForwardBy(kIdleInterval);
// Nothing happens since there is an inflight event.
EXPECT_FALSE(is_idle);
timer.EndEvent(event1.event_id());
event_queue.EndEvent(event1.event_id());
task_runner()->FastForwardBy(kIdleInterval);
// |idle_callback| should be fired.
EXPECT_TRUE(is_idle);
is_idle = false;
MockEvent event3;
timer.PushTask(event3.CreateTask());
event3.EnqueueTo(&event_queue);
task_runner()->FastForwardBy(kIdleInterval);
// Nothing happens since there is an inflight event.
EXPECT_FALSE(is_idle);
std::unique_ptr<StayAwakeToken> token = timer.CreateStayAwakeToken();
timer.EndEvent(event3.event_id());
std::unique_ptr<StayAwakeToken> token = event_queue.CreateStayAwakeToken();
event_queue.EndEvent(event3.event_id());
task_runner()->FastForwardBy(kIdleInterval);
// Nothing happens since there is a living StayAwakeToken.
EXPECT_FALSE(is_idle);
......@@ -195,11 +189,11 @@ TEST_F(ServiceWorkerEventQueueTest, InflightEventBeforeStart) {
base::TimeDelta::FromSeconds(1);
bool is_idle = false;
ServiceWorkerEventQueue timer(CreateReceiverWithCalledFlag(&is_idle),
task_runner()->GetMockTickClock());
ServiceWorkerEventQueue event_queue(CreateReceiverWithCalledFlag(&is_idle),
task_runner()->GetMockTickClock());
MockEvent event;
timer.PushTask(event.CreateTask());
timer.Start();
event.EnqueueTo(&event_queue);
event_queue.Start();
task_runner()->FastForwardBy(kIdleInterval);
// Nothing happens since there is an inflight event.
EXPECT_FALSE(is_idle);
......@@ -217,20 +211,20 @@ TEST_F(ServiceWorkerEventQueueTest, InflightEventBeforeStart) {
// In the first UpdateStatus() the idle callback should be triggered.
TEST_F(ServiceWorkerEventQueueTest, EventFinishedBeforeStart) {
bool is_idle = false;
ServiceWorkerEventQueue timer(CreateReceiverWithCalledFlag(&is_idle),
task_runner()->GetMockTickClock());
ServiceWorkerEventQueue event_queue(CreateReceiverWithCalledFlag(&is_idle),
task_runner()->GetMockTickClock());
// Start and finish an event before starting the timer.
MockEvent event;
timer.PushTask(event.CreateTask());
event.EnqueueTo(&event_queue);
task_runner()->FastForwardBy(base::TimeDelta::FromSeconds(1));
timer.EndEvent(event.event_id());
event_queue.EndEvent(event.event_id());
// Move the time ticks to almost before |idle_time_| so that |idle_callback|
// will get called at the first update check.
task_runner()->FastForwardBy(ServiceWorkerEventQueue::kIdleDelay -
base::TimeDelta::FromSeconds(1));
timer.Start();
event_queue.Start();
// Make sure the timer calls UpdateStatus().
task_runner()->FastForwardBy(ServiceWorkerEventQueue::kUpdateInterval +
......@@ -246,8 +240,8 @@ TEST_F(ServiceWorkerEventQueueTest, EventTimer) {
event_queue.Start();
MockEvent event1, event2;
event_queue.PushTask(event1.CreateTask());
event_queue.PushTask(event2.CreateTask());
event1.EnqueueTo(&event_queue);
event2.EnqueueTo(&event_queue);
task_runner()->FastForwardBy(ServiceWorkerEventQueue::kUpdateInterval +
base::TimeDelta::FromSeconds(1));
......@@ -268,12 +262,12 @@ TEST_F(ServiceWorkerEventQueueTest, CustomTimeouts) {
task_runner()->GetMockTickClock());
event_queue.Start();
MockEvent event1, event2;
event_queue.PushTask(event1.CreateTaskWithCustomTimeout(
ServiceWorkerEventQueue::kUpdateInterval -
base::TimeDelta::FromSeconds(1)));
event_queue.PushTask(event2.CreateTaskWithCustomTimeout(
ServiceWorkerEventQueue::kUpdateInterval * 2 -
base::TimeDelta::FromSeconds(1)));
event1.EnqueueWithCustomTimeoutTo(&event_queue,
ServiceWorkerEventQueue::kUpdateInterval -
base::TimeDelta::FromSeconds(1));
event2.EnqueueWithCustomTimeoutTo(
&event_queue, ServiceWorkerEventQueue::kUpdateInterval * 2 -
base::TimeDelta::FromSeconds(1));
task_runner()->FastForwardBy(ServiceWorkerEventQueue::kUpdateInterval +
base::TimeDelta::FromSeconds(1));
......@@ -297,7 +291,7 @@ TEST_F(ServiceWorkerEventQueueTest, BecomeIdleAfterAbort) {
event_queue.Start();
MockEvent event;
event_queue.PushTask(event.CreateTask());
event.EnqueueTo(&event_queue);
task_runner()->FastForwardBy(ServiceWorkerEventQueue::kEventTimeout +
ServiceWorkerEventQueue::kUpdateInterval +
base::TimeDelta::FromSeconds(1));
......@@ -315,8 +309,9 @@ TEST_F(ServiceWorkerEventQueueTest, AbortAllOnDestruction) {
task_runner()->GetMockTickClock());
event_queue.Start();
event_queue.PushTask(event1.CreateTask());
event_queue.PushTask(event2.CreateTask());
event1.EnqueueTo(&event_queue);
event2.EnqueueTo(&event_queue);
task_runner()->FastForwardBy(ServiceWorkerEventQueue::kUpdateInterval +
base::TimeDelta::FromSeconds(1));
......@@ -342,12 +337,12 @@ TEST_F(ServiceWorkerEventQueueTest, PushPendingTask) {
EXPECT_TRUE(event_queue.did_idle_timeout());
MockEvent pending_event;
event_queue.PushTask(pending_event.CreatePendingTask());
pending_event.EnqueuePendingTo(&event_queue);
EXPECT_FALSE(pending_event.Started());
// Start a new event. PushTask() should run the pending tasks.
MockEvent event;
event_queue.PushTask(event.CreateTask());
event.EnqueueTo(&event_queue);
EXPECT_FALSE(event_queue.did_idle_timeout());
EXPECT_TRUE(pending_event.Started());
}
......@@ -363,15 +358,13 @@ TEST_F(ServiceWorkerEventQueueTest, RunPendingTasksWithZeroIdleTimerDelay) {
MockEvent event1, event2;
Vector<String> handled_tasks;
event_queue.PushTask(CreatePendingTaskDispatchingEvent(&event_queue, &event1,
"1", &handled_tasks));
event_queue.PushTask(CreatePendingTaskDispatchingEvent(&event_queue, &event2,
"2", &handled_tasks));
event1.EnqueuePendingDispatchingEventTo(&event_queue, "1", &handled_tasks);
event2.EnqueuePendingDispatchingEventTo(&event_queue, "2", &handled_tasks);
EXPECT_TRUE(handled_tasks.IsEmpty());
// Start a new event. PushTask() should run the pending tasks.
MockEvent event;
event_queue.PushTask(event.CreateTask());
event.EnqueueTo(&event_queue);
EXPECT_FALSE(event_queue.did_idle_timeout());
ASSERT_EQ(2u, handled_tasks.size());
EXPECT_EQ("1", handled_tasks[0]);
......@@ -400,7 +393,7 @@ TEST_F(ServiceWorkerEventQueueTest, SetIdleTimerDelayToZero) {
task_runner()->GetMockTickClock());
event_queue.Start();
MockEvent event;
event_queue.PushTask(event.CreateTask());
event.EnqueueTo(&event_queue);
event_queue.SetIdleTimerDelayToZero();
// Nothing happens since there is an inflight event.
EXPECT_FALSE(is_idle);
......@@ -416,8 +409,8 @@ TEST_F(ServiceWorkerEventQueueTest, SetIdleTimerDelayToZero) {
task_runner()->GetMockTickClock());
event_queue.Start();
MockEvent event1, event2;
event_queue.PushTask(event1.CreateTask());
event_queue.PushTask(event2.CreateTask());
event1.EnqueueTo(&event_queue);
event2.EnqueueTo(&event_queue);
event_queue.SetIdleTimerDelayToZero();
// Nothing happens since there are two inflight events.
EXPECT_FALSE(is_idle);
......
......@@ -1305,11 +1305,9 @@ void ServiceWorkerGlobalScope::OnRequestedTermination(bool will_be_terminated) {
// Push a dummy task to run all of queued tasks. This updates the
// idle timer too.
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
WTF::Bind(&ServiceWorkerEventQueue::EndEvent,
WTF::Unretained(event_queue_.get())),
base::DoNothing(), base::nullopt));
event_queue_->EnqueueNormal(WTF::Bind(&ServiceWorkerEventQueue::EndEvent,
WTF::Unretained(event_queue_.get())),
base::DoNothing(), base::nullopt);
}
bool ServiceWorkerGlobalScope::RequestedTermination() const {
......@@ -1440,13 +1438,21 @@ void ServiceWorkerGlobalScope::DispatchFetchEventForSubresource(
RequestedTermination() ? "true" : "false");
network::mojom::blink::CrossOriginEmbedderPolicy requestor_coep =
controller_receivers_.current_context();
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
RequestedTermination() ? ServiceWorkerEventQueue::Task::Type::Pending
: ServiceWorkerEventQueue::Task::Type::Normal,
WTF::Bind(&ServiceWorkerGlobalScope::StartFetchEvent,
WrapWeakPersistent(this), std::move(params), requestor_coep,
std::move(response_callback), std::move(callback)),
CreateAbortCallback(&fetch_event_callbacks_), base::nullopt));
if (RequestedTermination()) {
event_queue_->EnqueuePending(
WTF::Bind(&ServiceWorkerGlobalScope::StartFetchEvent,
WrapWeakPersistent(this), std::move(params),
std::move(requestor_coep), std::move(response_callback),
std::move(callback)),
CreateAbortCallback(&fetch_event_callbacks_), base::nullopt);
} else {
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartFetchEvent,
WrapWeakPersistent(this), std::move(params),
std::move(requestor_coep), std::move(response_callback),
std::move(callback)),
CreateAbortCallback(&fetch_event_callbacks_), base::nullopt);
}
}
void ServiceWorkerGlobalScope::Clone(
......@@ -1514,13 +1520,12 @@ void ServiceWorkerGlobalScope::ResumeEvaluation() {
void ServiceWorkerGlobalScope::DispatchInstallEvent(
DispatchInstallEventCallback callback) {
DCHECK(IsContextThread());
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartInstallEvent,
WrapWeakPersistent(this), std::move(callback)),
CreateAbortCallback(&install_event_callbacks_,
false /* has_fetch_handler */),
base::nullopt));
base::nullopt);
}
void ServiceWorkerGlobalScope::StartInstallEvent(
......@@ -1546,11 +1551,10 @@ void ServiceWorkerGlobalScope::StartInstallEvent(
void ServiceWorkerGlobalScope::DispatchActivateEvent(
DispatchActivateEventCallback callback) {
DCHECK(IsContextThread());
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartActivateEvent,
WrapWeakPersistent(this), std::move(callback)),
CreateAbortCallback(&activate_event_callbacks_), base::nullopt));
CreateAbortCallback(&activate_event_callbacks_), base::nullopt);
}
void ServiceWorkerGlobalScope::StartActivateEvent(
......@@ -1575,13 +1579,12 @@ void ServiceWorkerGlobalScope::DispatchBackgroundFetchAbortEvent(
mojom::blink::BackgroundFetchRegistrationPtr registration,
DispatchBackgroundFetchAbortEventCallback callback) {
DCHECK(IsContextThread());
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartBackgroundFetchAbortEvent,
WrapWeakPersistent(this), std::move(registration),
std::move(callback)),
CreateAbortCallback(&background_fetch_abort_event_callbacks_),
base::nullopt));
base::nullopt);
}
void ServiceWorkerGlobalScope::StartBackgroundFetchAbortEvent(
......@@ -1619,13 +1622,12 @@ void ServiceWorkerGlobalScope::DispatchBackgroundFetchClickEvent(
mojom::blink::BackgroundFetchRegistrationPtr registration,
DispatchBackgroundFetchClickEventCallback callback) {
DCHECK(IsContextThread());
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartBackgroundFetchClickEvent,
WrapWeakPersistent(this), std::move(registration),
std::move(callback)),
CreateAbortCallback(&background_fetch_click_event_callbacks_),
base::nullopt));
base::nullopt);
}
void ServiceWorkerGlobalScope::StartBackgroundFetchClickEvent(
......@@ -1658,13 +1660,12 @@ void ServiceWorkerGlobalScope::DispatchBackgroundFetchFailEvent(
mojom::blink::BackgroundFetchRegistrationPtr registration,
DispatchBackgroundFetchFailEventCallback callback) {
DCHECK(IsContextThread());
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartBackgroundFetchFailEvent,
WrapWeakPersistent(this), std::move(registration),
std::move(callback)),
CreateAbortCallback(&background_fetch_fail_event_callbacks_),
base::nullopt));
base::nullopt);
}
void ServiceWorkerGlobalScope::StartBackgroundFetchFailEvent(
......@@ -1703,13 +1704,11 @@ void ServiceWorkerGlobalScope::DispatchBackgroundFetchSuccessEvent(
mojom::blink::BackgroundFetchRegistrationPtr registration,
DispatchBackgroundFetchSuccessEventCallback callback) {
DCHECK(IsContextThread());
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartBackgroundFetchSuccessEvent,
WrapWeakPersistent(this), std::move(registration),
std::move(callback)),
CreateAbortCallback(&background_fetched_event_callbacks_),
base::nullopt));
CreateAbortCallback(&background_fetched_event_callbacks_), base::nullopt);
}
void ServiceWorkerGlobalScope::StartBackgroundFetchSuccessEvent(
......@@ -1748,12 +1747,11 @@ void ServiceWorkerGlobalScope::DispatchExtendableMessageEvent(
mojom::blink::ExtendableMessageEventPtr event,
DispatchExtendableMessageEventCallback callback) {
DCHECK(IsContextThread());
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartExtendableMessageEvent,
WrapWeakPersistent(this), std::move(event),
std::move(callback)),
CreateAbortCallback(&message_event_callbacks_), base::nullopt));
CreateAbortCallback(&message_event_callbacks_), base::nullopt);
}
void ServiceWorkerGlobalScope::StartExtendableMessageEvent(
......@@ -1779,13 +1777,12 @@ void ServiceWorkerGlobalScope::DispatchFetchEventForMainResource(
DCHECK(IsContextThread());
// We can use kNone as a |requestor_coep| for the main resource because it
// must be the same origin.
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartFetchEvent,
WrapWeakPersistent(this), std::move(params),
network::mojom::blink::CrossOriginEmbedderPolicy::kNone,
std::move(response_callback), std::move(callback)),
CreateAbortCallback(&fetch_event_callbacks_), base::nullopt));
CreateAbortCallback(&fetch_event_callbacks_), base::nullopt);
}
void ServiceWorkerGlobalScope::DispatchNotificationClickEvent(
......@@ -1795,14 +1792,12 @@ void ServiceWorkerGlobalScope::DispatchNotificationClickEvent(
const String& reply,
DispatchNotificationClickEventCallback callback) {
DCHECK(IsContextThread());
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartNotificationClickEvent,
WrapWeakPersistent(this), notification_id,
std::move(notification_data), action_index, reply,
std::move(callback)),
CreateAbortCallback(&notification_click_event_callbacks_),
base::nullopt));
CreateAbortCallback(&notification_click_event_callbacks_), base::nullopt);
}
void ServiceWorkerGlobalScope::StartNotificationClickEvent(
......@@ -1840,13 +1835,11 @@ void ServiceWorkerGlobalScope::DispatchNotificationCloseEvent(
mojom::blink::NotificationDataPtr notification_data,
DispatchNotificationCloseEventCallback callback) {
DCHECK(IsContextThread());
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartNotificationCloseEvent,
WrapWeakPersistent(this), notification_id,
std::move(notification_data), std::move(callback)),
CreateAbortCallback(&notification_close_event_callbacks_),
base::nullopt));
CreateAbortCallback(&notification_close_event_callbacks_), base::nullopt);
}
void ServiceWorkerGlobalScope::StartNotificationCloseEvent(
......@@ -1878,13 +1871,12 @@ void ServiceWorkerGlobalScope::DispatchPushEvent(
const String& payload,
DispatchPushEventCallback callback) {
DCHECK(IsContextThread());
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartPushEvent,
WrapWeakPersistent(this), std::move(payload),
std::move(callback)),
CreateAbortCallback(&push_event_callbacks_),
base::TimeDelta::FromSeconds(mojom::blink::kPushEventTimeoutSeconds)));
base::TimeDelta::FromSeconds(mojom::blink::kPushEventTimeoutSeconds));
}
void ServiceWorkerGlobalScope::StartPushEvent(
......@@ -1911,13 +1903,12 @@ void ServiceWorkerGlobalScope::DispatchPushSubscriptionChangeEvent(
mojom::blink::PushSubscriptionPtr new_subscription,
DispatchPushSubscriptionChangeEventCallback callback) {
DCHECK(IsContextThread());
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartPushSubscriptionChangeEvent,
WrapWeakPersistent(this), std::move(old_subscription),
std::move(new_subscription), std::move(callback)),
CreateAbortCallback(&push_subscription_change_event_callbacks_),
base::TimeDelta::FromSeconds(mojom::blink::kPushEventTimeoutSeconds)));
base::TimeDelta::FromSeconds(mojom::blink::kPushEventTimeoutSeconds));
}
void ServiceWorkerGlobalScope::StartPushSubscriptionChangeEvent(
......@@ -1948,12 +1939,11 @@ void ServiceWorkerGlobalScope::DispatchSyncEvent(
base::TimeDelta timeout,
DispatchSyncEventCallback callback) {
DCHECK(IsContextThread());
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartSyncEvent,
WrapWeakPersistent(this), std::move(tag), last_chance,
std::move(callback)),
CreateAbortCallback(&sync_event_callbacks_), timeout));
CreateAbortCallback(&sync_event_callbacks_), timeout);
}
void ServiceWorkerGlobalScope::StartSyncEvent(
......@@ -1981,11 +1971,10 @@ void ServiceWorkerGlobalScope::DispatchPeriodicSyncEvent(
base::TimeDelta timeout,
DispatchPeriodicSyncEventCallback callback) {
DCHECK(IsContextThread());
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartPeriodicSyncEvent,
WrapWeakPersistent(this), std::move(tag), std::move(callback)),
CreateAbortCallback(&periodic_sync_event_callbacks_), timeout));
CreateAbortCallback(&periodic_sync_event_callbacks_), timeout);
}
void ServiceWorkerGlobalScope::StartPeriodicSyncEvent(
......@@ -2012,12 +2001,11 @@ void ServiceWorkerGlobalScope::DispatchAbortPaymentEvent(
response_callback,
DispatchAbortPaymentEventCallback callback) {
DCHECK(IsContextThread());
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartAbortPaymentEvent,
WrapWeakPersistent(this), std::move(response_callback),
std::move(callback)),
CreateAbortCallback(&abort_payment_event_callbacks_), base::nullopt));
CreateAbortCallback(&abort_payment_event_callbacks_), base::nullopt);
}
void ServiceWorkerGlobalScope::StartAbortPaymentEvent(
......@@ -2057,12 +2045,11 @@ void ServiceWorkerGlobalScope::DispatchCanMakePaymentEvent(
response_callback,
DispatchCanMakePaymentEventCallback callback) {
DCHECK(IsContextThread());
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartCanMakePaymentEvent,
WrapWeakPersistent(this), std::move(event_data),
std::move(response_callback), std::move(callback)),
CreateAbortCallback(&can_make_payment_event_callbacks_), base::nullopt));
CreateAbortCallback(&can_make_payment_event_callbacks_), base::nullopt);
}
void ServiceWorkerGlobalScope::StartCanMakePaymentEvent(
......@@ -2105,12 +2092,11 @@ void ServiceWorkerGlobalScope::DispatchPaymentRequestEvent(
response_callback,
DispatchPaymentRequestEventCallback callback) {
DCHECK(IsContextThread());
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartPaymentRequestEvent,
WrapWeakPersistent(this), std::move(event_data),
std::move(response_callback), std::move(callback)),
CreateAbortCallback(&payment_request_event_callbacks_), base::nullopt));
CreateAbortCallback(&payment_request_event_callbacks_), base::nullopt);
}
void ServiceWorkerGlobalScope::StartPaymentRequestEvent(
......@@ -2166,12 +2152,11 @@ void ServiceWorkerGlobalScope::StartPaymentRequestEvent(
void ServiceWorkerGlobalScope::DispatchCookieChangeEvent(
network::mojom::blink::CookieChangeInfoPtr change,
DispatchCookieChangeEventCallback callback) {
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartCookieChangeEvent,
WrapWeakPersistent(this), std::move(change),
std::move(callback)),
CreateAbortCallback(&cookie_change_event_callbacks_), base::nullopt));
CreateAbortCallback(&cookie_change_event_callbacks_), base::nullopt);
}
void ServiceWorkerGlobalScope::StartCookieChangeEvent(
......@@ -2207,11 +2192,10 @@ void ServiceWorkerGlobalScope::StartCookieChangeEvent(
void ServiceWorkerGlobalScope::DispatchContentDeleteEvent(
const String& id,
DispatchContentDeleteEventCallback callback) {
event_queue_->PushTask(std::make_unique<ServiceWorkerEventQueue::Task>(
ServiceWorkerEventQueue::Task::Type::Normal,
event_queue_->EnqueueNormal(
WTF::Bind(&ServiceWorkerGlobalScope::StartContentDeleteEvent,
WrapWeakPersistent(this), id, std::move(callback)),
CreateAbortCallback(&content_delete_callbacks_), base::nullopt));
CreateAbortCallback(&content_delete_callbacks_), base::nullopt);
}
void ServiceWorkerGlobalScope::StartContentDeleteEvent(
......
......@@ -458,7 +458,7 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
void NoteRespondedToFetchEvent(const KURL& request_url);
// Dispatches the event synchronously. Enqueued by Dispatch*Event methods to
// the timeout timer, and executed immediately or sometimes later.
// the event queue, and executed immediately or sometimes later.
void StartFetchEvent(
mojom::blink::DispatchFetchEventParamsPtr params,
network::mojom::blink::CrossOriginEmbedderPolicy requestor_coep,
......@@ -641,8 +641,8 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final
// optimizations in these cases.
HashMap<KURL, int> unresponded_fetch_event_counts_;
// Timer triggered when the service worker considers it should be stopped or
// an event should be aborted.
// ServiceWorker event queue where all events are queued before
// they are dispatched.
std::unique_ptr<ServiceWorkerEventQueue> event_queue_;
// InitializeGlobalScope() pauses the top level script evaluation when this
......
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