| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/scheduler/base/time_domain.h" | 5 #include "platform/scheduler/base/time_domain.h" |
| 6 | 6 |
| 7 #include "base/macros.h" | 7 #include "base/macros.h" |
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/test/simple_test_tick_clock.h" | 9 #include "base/test/simple_test_tick_clock.h" |
| 10 #include "cc/test/ordered_simple_task_runner.h" | 10 #include "cc/test/ordered_simple_task_runner.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 namespace scheduler { | 23 namespace scheduler { |
| 24 | 24 |
| 25 class MockTimeDomain : public TimeDomain { | 25 class MockTimeDomain : public TimeDomain { |
| 26 public: | 26 public: |
| 27 explicit MockTimeDomain(TimeDomain::Observer* observer) | 27 explicit MockTimeDomain(TimeDomain::Observer* observer) |
| 28 : TimeDomain(observer), | 28 : TimeDomain(observer), |
| 29 now_(base::TimeTicks() + base::TimeDelta::FromSeconds(1)) {} | 29 now_(base::TimeTicks() + base::TimeDelta::FromSeconds(1)) {} |
| 30 | 30 |
| 31 ~MockTimeDomain() override {} | 31 ~MockTimeDomain() override {} |
| 32 | 32 |
| 33 using TimeDomain::CancelDelayedWork; | |
| 34 using TimeDomain::ClearExpiredWakeups; | |
| 35 using TimeDomain::NextScheduledRunTime; | 33 using TimeDomain::NextScheduledRunTime; |
| 36 using TimeDomain::NextScheduledTaskQueue; | 34 using TimeDomain::NextScheduledTaskQueue; |
| 37 using TimeDomain::ScheduleDelayedWork; | 35 using TimeDomain::ScheduleDelayedWork; |
| 38 using TimeDomain::UnregisterQueue; | 36 using TimeDomain::UnregisterQueue; |
| 39 using TimeDomain::UpdateWorkQueues; | 37 using TimeDomain::UpdateWorkQueues; |
| 40 using TimeDomain::RegisterAsUpdatableTaskQueue; | 38 using TimeDomain::RegisterAsUpdatableTaskQueue; |
| 41 | 39 |
| 42 // TimeSource implementation: | 40 // TimeSource implementation: |
| 43 LazyNow CreateLazyNow() const override { return LazyNow(now_); } | 41 LazyNow CreateLazyNow() const override { return LazyNow(now_); } |
| 44 base::TimeTicks Now() const override { return now_; } | 42 base::TimeTicks Now() const override { return now_; } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 | 90 |
| 93 base::TimeTicks next_scheduled_runtime; | 91 base::TimeTicks next_scheduled_runtime; |
| 94 EXPECT_TRUE(time_domain_->NextScheduledRunTime(&next_scheduled_runtime)); | 92 EXPECT_TRUE(time_domain_->NextScheduledRunTime(&next_scheduled_runtime)); |
| 95 EXPECT_EQ(delayed_runtime, next_scheduled_runtime); | 93 EXPECT_EQ(delayed_runtime, next_scheduled_runtime); |
| 96 | 94 |
| 97 TaskQueue* next_task_queue; | 95 TaskQueue* next_task_queue; |
| 98 EXPECT_TRUE(time_domain_->NextScheduledTaskQueue(&next_task_queue)); | 96 EXPECT_TRUE(time_domain_->NextScheduledTaskQueue(&next_task_queue)); |
| 99 EXPECT_EQ(task_queue_.get(), next_task_queue); | 97 EXPECT_EQ(task_queue_.get(), next_task_queue); |
| 100 } | 98 } |
| 101 | 99 |
| 100 TEST_F(TimeDomainTest, ScheduleDelayedWorkSupersedesPreviousWakeup) { |
| 101 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10); |
| 102 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(100); |
| 103 base::TimeTicks delayed_runtime1 = time_domain_->Now() + delay1; |
| 104 base::TimeTicks delayed_runtime2 = time_domain_->Now() + delay2; |
| 105 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay1)); |
| 106 base::TimeTicks now = time_domain_->Now(); |
| 107 time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime1, now); |
| 108 |
| 109 base::TimeTicks next_scheduled_runtime; |
| 110 EXPECT_TRUE(time_domain_->NextScheduledRunTime(&next_scheduled_runtime)); |
| 111 EXPECT_EQ(delayed_runtime1, next_scheduled_runtime); |
| 112 |
| 113 Mock::VerifyAndClearExpectations(time_domain_.get()); |
| 114 |
| 115 // Now scheduler a later wakeup, which should replace the previously requested |
| 116 // one. |
| 117 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay2)); |
| 118 time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime2, now); |
| 119 |
| 120 EXPECT_TRUE(time_domain_->NextScheduledRunTime(&next_scheduled_runtime)); |
| 121 EXPECT_EQ(delayed_runtime2, next_scheduled_runtime); |
| 122 } |
| 123 |
| 102 TEST_F(TimeDomainTest, RequestWakeup_OnlyCalledForEarlierTasks) { | 124 TEST_F(TimeDomainTest, RequestWakeup_OnlyCalledForEarlierTasks) { |
| 125 scoped_refptr<internal::TaskQueueImpl> task_queue2 = |
| 126 make_scoped_refptr(new internal::TaskQueueImpl( |
| 127 nullptr, time_domain_.get(), TaskQueue::Spec("test_queue2"), |
| 128 "test.category", "test.category")); |
| 129 |
| 130 scoped_refptr<internal::TaskQueueImpl> task_queue3 = |
| 131 make_scoped_refptr(new internal::TaskQueueImpl( |
| 132 nullptr, time_domain_.get(), TaskQueue::Spec("test_queue3"), |
| 133 "test.category", "test.category")); |
| 134 |
| 135 scoped_refptr<internal::TaskQueueImpl> task_queue4 = |
| 136 make_scoped_refptr(new internal::TaskQueueImpl( |
| 137 nullptr, time_domain_.get(), TaskQueue::Spec("test_queue4"), |
| 138 "test.category", "test.category")); |
| 139 |
| 103 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10); | 140 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10); |
| 104 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(20); | 141 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(20); |
| 105 base::TimeDelta delay3 = base::TimeDelta::FromMilliseconds(30); | 142 base::TimeDelta delay3 = base::TimeDelta::FromMilliseconds(30); |
| 106 base::TimeDelta delay4 = base::TimeDelta::FromMilliseconds(1); | 143 base::TimeDelta delay4 = base::TimeDelta::FromMilliseconds(1); |
| 107 | 144 |
| 108 // RequestWakeup should always be called if there are no other wakeups. | 145 // RequestWakeup should always be called if there are no other wakeups. |
| 109 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay1)); | 146 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay1)); |
| 110 base::TimeTicks now = time_domain_->Now(); | 147 base::TimeTicks now = time_domain_->Now(); |
| 111 time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay1, now); | 148 time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay1, now); |
| 112 | 149 |
| 113 Mock::VerifyAndClearExpectations(time_domain_.get()); | 150 Mock::VerifyAndClearExpectations(time_domain_.get()); |
| 114 | 151 |
| 115 // RequestWakeup should not be called when scheduling later tasks. | 152 // RequestWakeup should not be called when scheduling later tasks. |
| 116 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)).Times(0); | 153 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)).Times(0); |
| 117 time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay2, now); | 154 time_domain_->ScheduleDelayedWork(task_queue2.get(), now + delay2, now); |
| 118 time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay3, now); | 155 time_domain_->ScheduleDelayedWork(task_queue3.get(), now + delay3, now); |
| 119 | 156 |
| 120 // RequestWakeup should be called when scheduling earlier tasks. | 157 // RequestWakeup should be called when scheduling earlier tasks. |
| 121 Mock::VerifyAndClearExpectations(time_domain_.get()); | 158 Mock::VerifyAndClearExpectations(time_domain_.get()); |
| 122 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay4)); | 159 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay4)); |
| 123 time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay4, now); | 160 time_domain_->ScheduleDelayedWork(task_queue4.get(), now + delay4, now); |
| 124 } | 161 } |
| 125 | 162 |
| 126 TEST_F(TimeDomainTest, UnregisterQueue) { | 163 TEST_F(TimeDomainTest, UnregisterQueue) { |
| 127 scoped_refptr<internal::TaskQueueImpl> task_queue2_ = | 164 scoped_refptr<internal::TaskQueueImpl> task_queue2_ = |
| 128 make_scoped_refptr(new internal::TaskQueueImpl( | 165 make_scoped_refptr(new internal::TaskQueueImpl( |
| 129 nullptr, time_domain_.get(), TaskQueue::Spec("test_queue2"), | 166 nullptr, time_domain_.get(), TaskQueue::Spec("test_queue2"), |
| 130 "test.category", "test.category")); | 167 "test.category", "test.category")); |
| 131 | 168 |
| 132 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)).Times(1); | 169 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)).Times(1); |
| 133 base::TimeTicks now = time_domain_->Now(); | 170 base::TimeTicks now = time_domain_->Now(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 164 time_domain_->UpdateWorkQueues(lazy_now); | 201 time_domain_->UpdateWorkQueues(lazy_now); |
| 165 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | 202 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); |
| 166 EXPECT_EQ(delayed_runtime, next_run_time); | 203 EXPECT_EQ(delayed_runtime, next_run_time); |
| 167 | 204 |
| 168 time_domain_->SetNow(delayed_runtime); | 205 time_domain_->SetNow(delayed_runtime); |
| 169 lazy_now = time_domain_->CreateLazyNow(); | 206 lazy_now = time_domain_->CreateLazyNow(); |
| 170 time_domain_->UpdateWorkQueues(lazy_now); | 207 time_domain_->UpdateWorkQueues(lazy_now); |
| 171 ASSERT_FALSE(time_domain_->NextScheduledRunTime(&next_run_time)); | 208 ASSERT_FALSE(time_domain_->NextScheduledRunTime(&next_run_time)); |
| 172 } | 209 } |
| 173 | 210 |
| 174 TEST_F(TimeDomainTest, ClearExpiredWakeups) { | |
| 175 base::TimeTicks now = time_domain_->Now(); | |
| 176 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10); | |
| 177 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(20); | |
| 178 base::TimeTicks run_time1 = now + delay1; | |
| 179 base::TimeTicks run_time2 = now + delay2; | |
| 180 | |
| 181 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)).Times(AnyNumber()); | |
| 182 time_domain_->ScheduleDelayedWork(task_queue_.get(), run_time1, now); | |
| 183 time_domain_->ScheduleDelayedWork(task_queue_.get(), run_time2, now); | |
| 184 | |
| 185 base::TimeTicks next_run_time; | |
| 186 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
| 187 EXPECT_EQ(run_time1, next_run_time); | |
| 188 | |
| 189 time_domain_->SetNow(run_time1); | |
| 190 time_domain_->ClearExpiredWakeups(); | |
| 191 | |
| 192 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
| 193 EXPECT_EQ(run_time2, next_run_time); | |
| 194 | |
| 195 time_domain_->SetNow(run_time2); | |
| 196 time_domain_->ClearExpiredWakeups(); | |
| 197 ASSERT_FALSE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
| 198 } | |
| 199 | |
| 200 TEST_F(TimeDomainTest, CancelDelayedWork) { | |
| 201 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(50); | |
| 202 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay)); | |
| 203 base::TimeTicks now = time_domain_->Now(); | |
| 204 base::TimeTicks delayed_runtime = now + delay; | |
| 205 time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime, now); | |
| 206 | |
| 207 base::TimeTicks next_run_time; | |
| 208 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
| 209 EXPECT_EQ(delayed_runtime, next_run_time); | |
| 210 | |
| 211 time_domain_->CancelDelayedWork(task_queue_.get(), delayed_runtime); | |
| 212 EXPECT_FALSE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
| 213 } | |
| 214 | |
| 215 TEST_F(TimeDomainTest, CancelDelayedWorkTaskQueueDoesntMatch) { | |
| 216 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(50); | |
| 217 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay)); | |
| 218 base::TimeTicks now = time_domain_->Now(); | |
| 219 base::TimeTicks delayed_runtime = now + delay; | |
| 220 time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime, now); | |
| 221 | |
| 222 base::TimeTicks next_run_time; | |
| 223 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
| 224 EXPECT_EQ(delayed_runtime, next_run_time); | |
| 225 | |
| 226 time_domain_->CancelDelayedWork(nullptr, delayed_runtime); | |
| 227 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
| 228 EXPECT_EQ(delayed_runtime, next_run_time); | |
| 229 } | |
| 230 | |
| 231 TEST_F(TimeDomainTest, CancelDelayedWorkTwoWakeUpsCancelFirst) { | |
| 232 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(50); | |
| 233 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(150); | |
| 234 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay1)); | |
| 235 base::TimeTicks now = time_domain_->Now(); | |
| 236 base::TimeTicks delayed_runtime1 = now + delay1; | |
| 237 base::TimeTicks delayed_runtime2 = now + delay2; | |
| 238 time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime1, now); | |
| 239 time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime2, now); | |
| 240 | |
| 241 base::TimeTicks next_run_time; | |
| 242 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
| 243 EXPECT_EQ(delayed_runtime1, next_run_time); | |
| 244 Mock::VerifyAndClearExpectations(time_domain_.get()); | |
| 245 | |
| 246 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay2)); | |
| 247 time_domain_->CancelDelayedWork(task_queue_.get(), delayed_runtime1); | |
| 248 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
| 249 EXPECT_EQ(delayed_runtime2, next_run_time); | |
| 250 } | |
| 251 | |
| 252 TEST_F(TimeDomainTest, CancelDelayedWorkTwoWakeUpsCancelSecond) { | |
| 253 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(50); | |
| 254 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(150); | |
| 255 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay1)); | |
| 256 base::TimeTicks now = time_domain_->Now(); | |
| 257 base::TimeTicks delayed_runtime1 = now + delay1; | |
| 258 base::TimeTicks delayed_runtime2 = now + delay2; | |
| 259 time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime1, now); | |
| 260 time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime2, now); | |
| 261 | |
| 262 base::TimeTicks next_run_time; | |
| 263 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
| 264 EXPECT_EQ(delayed_runtime1, next_run_time); | |
| 265 Mock::VerifyAndClearExpectations(time_domain_.get()); | |
| 266 | |
| 267 time_domain_->CancelDelayedWork(task_queue_.get(), delayed_runtime2); | |
| 268 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
| 269 EXPECT_EQ(delayed_runtime1, next_run_time); | |
| 270 | |
| 271 time_domain_->SetNow(delayed_runtime1); | |
| 272 LazyNow lazy_now = time_domain_->CreateLazyNow(); | |
| 273 time_domain_->UpdateWorkQueues(lazy_now); | |
| 274 ASSERT_FALSE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
| 275 } | |
| 276 | |
| 277 namespace { | 211 namespace { |
| 278 class MockObserver : public TimeDomain::Observer { | 212 class MockObserver : public TimeDomain::Observer { |
| 279 public: | 213 public: |
| 280 ~MockObserver() override {} | 214 ~MockObserver() override {} |
| 281 | 215 |
| 282 MOCK_METHOD0(OnTimeDomainHasImmediateWork, void()); | 216 MOCK_METHOD0(OnTimeDomainHasImmediateWork, void()); |
| 283 MOCK_METHOD0(OnTimeDomainHasDelayedWork, void()); | 217 MOCK_METHOD0(OnTimeDomainHasDelayedWork, void()); |
| 284 }; | 218 }; |
| 285 } // namespace | 219 } // namespace |
| 286 | 220 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 302 TEST_F(TimeDomainWithObserverTest, OnTimeDomainHasDelayedWork) { | 236 TEST_F(TimeDomainWithObserverTest, OnTimeDomainHasDelayedWork) { |
| 303 EXPECT_CALL(*observer_, OnTimeDomainHasDelayedWork()); | 237 EXPECT_CALL(*observer_, OnTimeDomainHasDelayedWork()); |
| 304 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)); | 238 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)); |
| 305 base::TimeTicks now = time_domain_->Now(); | 239 base::TimeTicks now = time_domain_->Now(); |
| 306 time_domain_->ScheduleDelayedWork( | 240 time_domain_->ScheduleDelayedWork( |
| 307 task_queue_.get(), now + base::TimeDelta::FromMilliseconds(10), now); | 241 task_queue_.get(), now + base::TimeDelta::FromMilliseconds(10), now); |
| 308 } | 242 } |
| 309 | 243 |
| 310 } // namespace scheduler | 244 } // namespace scheduler |
| 311 } // namespace blink | 245 } // namespace blink |
| OLD | NEW |