OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "content/renderer/scheduler/webthread_impl_for_scheduler.h" |
| 6 |
| 7 #include "content/renderer/scheduler/renderer_scheduler.h" |
| 8 #include "third_party/WebKit/public/platform/WebTraceLocation.h" |
| 9 |
| 10 namespace content { |
| 11 namespace internal { |
| 12 |
| 13 // Observes tasks both from a MessageLoop and a RendererScheduler which is |
| 14 // driven by that MessageLoop and filters out redundant task observer |
| 15 // notifications. |
| 16 class NestedTaskObserver { |
| 17 public: |
| 18 NestedTaskObserver(base::MessageLoop* message_loop, |
| 19 RendererScheduler* scheduler, |
| 20 blink::WebThread::TaskObserver* client_observer) |
| 21 : message_loop_(message_loop), |
| 22 scheduler_(scheduler), |
| 23 client_observer_(client_observer), |
| 24 message_loop_observer_(this), |
| 25 scheduler_observer_(this), |
| 26 inside_task_(false) { |
| 27 message_loop_->AddTaskObserver(&message_loop_observer_); |
| 28 scheduler_->AddTaskObserver(&scheduler_observer_); |
| 29 } |
| 30 |
| 31 ~NestedTaskObserver() { |
| 32 message_loop_->RemoveTaskObserver(&message_loop_observer_); |
| 33 scheduler_->RemoveTaskObserver(&scheduler_observer_); |
| 34 } |
| 35 |
| 36 private: |
| 37 class MessageLoopTaskObserver : public base::MessageLoop::TaskObserver { |
| 38 public: |
| 39 MessageLoopTaskObserver(NestedTaskObserver* parent) : parent_(parent) {} |
| 40 |
| 41 void WillProcessTask(const base::PendingTask& pending_task) override { |
| 42 parent_->WillProcessTask(); |
| 43 } |
| 44 |
| 45 void DidProcessTask(const base::PendingTask& pending_task) override { |
| 46 parent_->DidProcessTask(); |
| 47 } |
| 48 |
| 49 private: |
| 50 NestedTaskObserver* parent_; |
| 51 }; |
| 52 |
| 53 class SchedulerTaskObserver : public base::MessageLoop::TaskObserver { |
| 54 public: |
| 55 SchedulerTaskObserver(NestedTaskObserver* parent) : parent_(parent) {} |
| 56 |
| 57 void WillProcessTask(const base::PendingTask& pending_task) override { |
| 58 parent_->WillProcessTask(); |
| 59 } |
| 60 |
| 61 void DidProcessTask(const base::PendingTask& pending_task) override { |
| 62 parent_->DidProcessTask(); |
| 63 } |
| 64 |
| 65 private: |
| 66 NestedTaskObserver* parent_; |
| 67 }; |
| 68 |
| 69 void WillProcessTask() { |
| 70 // Don't filter out callbacks in nested message loops to ensure the client |
| 71 // sees at least the same callbacks as without the scheduler. |
| 72 if (message_loop_->IsNested()) { |
| 73 client_observer_->willProcessTask(); |
| 74 return; |
| 75 } |
| 76 if (!inside_task_) { |
| 77 inside_task_ = true; |
| 78 client_observer_->willProcessTask(); |
| 79 } |
| 80 } |
| 81 |
| 82 void DidProcessTask() { |
| 83 if (message_loop_->IsNested()) { |
| 84 client_observer_->didProcessTask(); |
| 85 return; |
| 86 } |
| 87 if (inside_task_) { |
| 88 inside_task_ = false; |
| 89 client_observer_->didProcessTask(); |
| 90 } |
| 91 } |
| 92 |
| 93 base::MessageLoop* message_loop_; // Not owned. |
| 94 RendererScheduler* scheduler_; // Not owned. |
| 95 blink::WebThread::TaskObserver* client_observer_; // Not owned. |
| 96 MessageLoopTaskObserver message_loop_observer_; |
| 97 SchedulerTaskObserver scheduler_observer_; |
| 98 |
| 99 bool inside_task_; |
| 100 |
| 101 DISALLOW_COPY_AND_ASSIGN(NestedTaskObserver); |
| 102 }; |
| 103 } // namespace internal |
| 104 |
| 105 WebThreadImplForScheduler::WebThreadImplForScheduler( |
| 106 RendererScheduler* scheduler) |
| 107 : task_runner_(scheduler->DefaultTaskRunner()), |
| 108 scheduler_(scheduler), |
| 109 thread_id_(base::PlatformThread::CurrentId()) { |
| 110 } |
| 111 |
| 112 WebThreadImplForScheduler::~WebThreadImplForScheduler() { |
| 113 } |
| 114 |
| 115 blink::PlatformThreadId WebThreadImplForScheduler::threadId() const { |
| 116 return thread_id_; |
| 117 } |
| 118 |
| 119 base::MessageLoop* WebThreadImplForScheduler::MessageLoop() const { |
| 120 DCHECK(isCurrentThread()); |
| 121 return base::MessageLoop::current(); |
| 122 } |
| 123 |
| 124 base::SingleThreadTaskRunner* WebThreadImplForScheduler::TaskRunner() const { |
| 125 return task_runner_.get(); |
| 126 } |
| 127 |
| 128 void WebThreadImplForScheduler::addTaskObserver(TaskObserver* observer) { |
| 129 CHECK(isCurrentThread()); |
| 130 if (nested_task_observer_map_.contains(observer)) |
| 131 return; |
| 132 nested_task_observer_map_.add( |
| 133 observer, make_scoped_ptr(new internal::NestedTaskObserver( |
| 134 MessageLoop(), scheduler_, observer))); |
| 135 } |
| 136 |
| 137 void WebThreadImplForScheduler::removeTaskObserver(TaskObserver* observer) { |
| 138 nested_task_observer_map_.erase(observer); |
| 139 } |
| 140 |
| 141 } // namespace content |
OLD | NEW |