| Index: content/renderer/scheduler/webthread_impl_for_scheduler.cc
|
| diff --git a/content/renderer/scheduler/webthread_impl_for_scheduler.cc b/content/renderer/scheduler/webthread_impl_for_scheduler.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7a62f0da69c745e3662bcad2ebbd167c6403b8a7
|
| --- /dev/null
|
| +++ b/content/renderer/scheduler/webthread_impl_for_scheduler.cc
|
| @@ -0,0 +1,141 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "content/renderer/scheduler/webthread_impl_for_scheduler.h"
|
| +
|
| +#include "content/renderer/scheduler/renderer_scheduler.h"
|
| +#include "third_party/WebKit/public/platform/WebTraceLocation.h"
|
| +
|
| +namespace content {
|
| +namespace internal {
|
| +
|
| +// Observes tasks both from a MessageLoop and a RendererScheduler which is
|
| +// driven by that MessageLoop and filters out redundant task observer
|
| +// notifications.
|
| +class NestedTaskObserver {
|
| + public:
|
| + NestedTaskObserver(base::MessageLoop* message_loop,
|
| + RendererScheduler* scheduler,
|
| + blink::WebThread::TaskObserver* client_observer)
|
| + : message_loop_(message_loop),
|
| + scheduler_(scheduler),
|
| + client_observer_(client_observer),
|
| + message_loop_observer_(this),
|
| + scheduler_observer_(this),
|
| + inside_task_(false) {
|
| + message_loop_->AddTaskObserver(&message_loop_observer_);
|
| + scheduler_->AddTaskObserver(&scheduler_observer_);
|
| + }
|
| +
|
| + ~NestedTaskObserver() {
|
| + message_loop_->RemoveTaskObserver(&message_loop_observer_);
|
| + scheduler_->RemoveTaskObserver(&scheduler_observer_);
|
| + }
|
| +
|
| + private:
|
| + class MessageLoopTaskObserver : public base::MessageLoop::TaskObserver {
|
| + public:
|
| + MessageLoopTaskObserver(NestedTaskObserver* parent) : parent_(parent) {}
|
| +
|
| + void WillProcessTask(const base::PendingTask& pending_task) override {
|
| + parent_->WillProcessTask();
|
| + }
|
| +
|
| + void DidProcessTask(const base::PendingTask& pending_task) override {
|
| + parent_->DidProcessTask();
|
| + }
|
| +
|
| + private:
|
| + NestedTaskObserver* parent_;
|
| + };
|
| +
|
| + class SchedulerTaskObserver : public base::MessageLoop::TaskObserver {
|
| + public:
|
| + SchedulerTaskObserver(NestedTaskObserver* parent) : parent_(parent) {}
|
| +
|
| + void WillProcessTask(const base::PendingTask& pending_task) override {
|
| + parent_->WillProcessTask();
|
| + }
|
| +
|
| + void DidProcessTask(const base::PendingTask& pending_task) override {
|
| + parent_->DidProcessTask();
|
| + }
|
| +
|
| + private:
|
| + NestedTaskObserver* parent_;
|
| + };
|
| +
|
| + void WillProcessTask() {
|
| + // Don't filter out callbacks in nested message loops to ensure the client
|
| + // sees at least the same callbacks as without the scheduler.
|
| + if (message_loop_->IsNested()) {
|
| + client_observer_->willProcessTask();
|
| + return;
|
| + }
|
| + if (!inside_task_) {
|
| + inside_task_ = true;
|
| + client_observer_->willProcessTask();
|
| + }
|
| + }
|
| +
|
| + void DidProcessTask() {
|
| + if (message_loop_->IsNested()) {
|
| + client_observer_->didProcessTask();
|
| + return;
|
| + }
|
| + if (inside_task_) {
|
| + inside_task_ = false;
|
| + client_observer_->didProcessTask();
|
| + }
|
| + }
|
| +
|
| + base::MessageLoop* message_loop_; // Not owned.
|
| + RendererScheduler* scheduler_; // Not owned.
|
| + blink::WebThread::TaskObserver* client_observer_; // Not owned.
|
| + MessageLoopTaskObserver message_loop_observer_;
|
| + SchedulerTaskObserver scheduler_observer_;
|
| +
|
| + bool inside_task_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(NestedTaskObserver);
|
| +};
|
| +} // namespace internal
|
| +
|
| +WebThreadImplForScheduler::WebThreadImplForScheduler(
|
| + RendererScheduler* scheduler)
|
| + : task_runner_(scheduler->DefaultTaskRunner()),
|
| + scheduler_(scheduler),
|
| + thread_id_(base::PlatformThread::CurrentId()) {
|
| +}
|
| +
|
| +WebThreadImplForScheduler::~WebThreadImplForScheduler() {
|
| +}
|
| +
|
| +blink::PlatformThreadId WebThreadImplForScheduler::threadId() const {
|
| + return thread_id_;
|
| +}
|
| +
|
| +base::MessageLoop* WebThreadImplForScheduler::MessageLoop() const {
|
| + DCHECK(isCurrentThread());
|
| + return base::MessageLoop::current();
|
| +}
|
| +
|
| +base::SingleThreadTaskRunner* WebThreadImplForScheduler::TaskRunner() const {
|
| + return task_runner_.get();
|
| +}
|
| +
|
| +void WebThreadImplForScheduler::addTaskObserver(TaskObserver* observer) {
|
| + CHECK(isCurrentThread());
|
| + if (nested_task_observer_map_.contains(observer))
|
| + return;
|
| + nested_task_observer_map_.add(
|
| + observer, make_scoped_ptr(new internal::NestedTaskObserver(
|
| + MessageLoop(), scheduler_, observer)));
|
| +}
|
| +
|
| +void WebThreadImplForScheduler::removeTaskObserver(TaskObserver* observer) {
|
| + nested_task_observer_map_.erase(observer);
|
| +}
|
| +
|
| +} // namespace content
|
|
|