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 "base/task/sequence_manager/work_queue.h"
6
7 #include <stddef.h>
8 #include <memory>
9
10 #include "base/bind.h"
11 #include "base/task/sequence_manager/real_time_domain.h"
12 #include "base/task/sequence_manager/task_queue_impl.h"
13 #include "base/task/sequence_manager/work_queue_sets.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15
16 namespace base {
17 namespace sequence_manager {
18 namespace internal {
19
20 namespace {
21
NopTask()22 void NopTask() {}
23
24 struct Cancelable {
Cancelablebase::sequence_manager::internal::__anon91c9b2a80111::Cancelable25 Cancelable() : weak_ptr_factory(this) {}
26
NopTaskbase::sequence_manager::internal::__anon91c9b2a80111::Cancelable27 void NopTask() {}
28
29 WeakPtrFactory<Cancelable> weak_ptr_factory;
30 };
31
32 } // namespace
33
34 class WorkQueueTest : public testing::Test {
35 public:
SetUp()36 void SetUp() override {
37 time_domain_.reset(new RealTimeDomain());
38 task_queue_ = std::make_unique<TaskQueueImpl>(nullptr, time_domain_.get(),
39 TaskQueue::Spec("test"));
40
41 work_queue_.reset(new WorkQueue(task_queue_.get(), "test",
42 WorkQueue::QueueType::kImmediate));
43 work_queue_sets_.reset(new WorkQueueSets(1, "test"));
44 work_queue_sets_->AddQueue(work_queue_.get(), 0);
45 }
46
TearDown()47 void TearDown() override { work_queue_sets_->RemoveQueue(work_queue_.get()); }
48
49 protected:
FakeCancelableTaskWithEnqueueOrder(int enqueue_order,WeakPtr<Cancelable> weak_ptr)50 TaskQueueImpl::Task FakeCancelableTaskWithEnqueueOrder(
51 int enqueue_order,
52 WeakPtr<Cancelable> weak_ptr) {
53 TaskQueueImpl::Task fake_task(
54 TaskQueue::PostedTask(BindOnce(&Cancelable::NopTask, weak_ptr),
55 FROM_HERE),
56 TimeTicks(), EnqueueOrder(),
57 EnqueueOrder::FromIntForTesting(enqueue_order));
58 return fake_task;
59 }
60
FakeTaskWithEnqueueOrder(int enqueue_order)61 TaskQueueImpl::Task FakeTaskWithEnqueueOrder(int enqueue_order) {
62 TaskQueueImpl::Task fake_task(
63 TaskQueue::PostedTask(BindOnce(&NopTask), FROM_HERE), TimeTicks(),
64 EnqueueOrder(), EnqueueOrder::FromIntForTesting(enqueue_order));
65 return fake_task;
66 }
67
FakeNonNestableTaskWithEnqueueOrder(int enqueue_order)68 TaskQueueImpl::Task FakeNonNestableTaskWithEnqueueOrder(int enqueue_order) {
69 TaskQueueImpl::Task fake_task(
70 TaskQueue::PostedTask(BindOnce(&NopTask), FROM_HERE), TimeTicks(),
71 EnqueueOrder(), EnqueueOrder::FromIntForTesting(enqueue_order));
72 fake_task.nestable = Nestable::kNonNestable;
73 return fake_task;
74 }
75
76 std::unique_ptr<RealTimeDomain> time_domain_;
77 std::unique_ptr<TaskQueueImpl> task_queue_;
78 std::unique_ptr<WorkQueue> work_queue_;
79 std::unique_ptr<WorkQueueSets> work_queue_sets_;
80 std::unique_ptr<TaskQueueImpl::TaskDeque> incoming_queue_;
81 };
82
TEST_F(WorkQueueTest,Empty)83 TEST_F(WorkQueueTest, Empty) {
84 EXPECT_TRUE(work_queue_->Empty());
85 work_queue_->Push(FakeTaskWithEnqueueOrder(1));
86 EXPECT_FALSE(work_queue_->Empty());
87 }
88
TEST_F(WorkQueueTest,Empty_IgnoresFences)89 TEST_F(WorkQueueTest, Empty_IgnoresFences) {
90 work_queue_->Push(FakeTaskWithEnqueueOrder(1));
91 work_queue_->InsertFence(EnqueueOrder::blocking_fence());
92 EXPECT_FALSE(work_queue_->Empty());
93 }
94
TEST_F(WorkQueueTest,GetFrontTaskEnqueueOrderQueueEmpty)95 TEST_F(WorkQueueTest, GetFrontTaskEnqueueOrderQueueEmpty) {
96 EnqueueOrder enqueue_order;
97 EXPECT_FALSE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
98 }
99
TEST_F(WorkQueueTest,GetFrontTaskEnqueueOrder)100 TEST_F(WorkQueueTest, GetFrontTaskEnqueueOrder) {
101 work_queue_->Push(FakeTaskWithEnqueueOrder(2));
102 work_queue_->Push(FakeTaskWithEnqueueOrder(3));
103 work_queue_->Push(FakeTaskWithEnqueueOrder(4));
104
105 EnqueueOrder enqueue_order;
106 EXPECT_TRUE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
107 EXPECT_EQ(2ull, enqueue_order);
108 }
109
TEST_F(WorkQueueTest,GetFrontTaskQueueEmpty)110 TEST_F(WorkQueueTest, GetFrontTaskQueueEmpty) {
111 EXPECT_EQ(nullptr, work_queue_->GetFrontTask());
112 }
113
TEST_F(WorkQueueTest,GetFrontTask)114 TEST_F(WorkQueueTest, GetFrontTask) {
115 work_queue_->Push(FakeTaskWithEnqueueOrder(2));
116 work_queue_->Push(FakeTaskWithEnqueueOrder(3));
117 work_queue_->Push(FakeTaskWithEnqueueOrder(4));
118
119 ASSERT_NE(nullptr, work_queue_->GetFrontTask());
120 EXPECT_EQ(2ull, work_queue_->GetFrontTask()->enqueue_order());
121 }
122
TEST_F(WorkQueueTest,GetBackTask_Empty)123 TEST_F(WorkQueueTest, GetBackTask_Empty) {
124 EXPECT_EQ(nullptr, work_queue_->GetBackTask());
125 }
126
TEST_F(WorkQueueTest,GetBackTask)127 TEST_F(WorkQueueTest, GetBackTask) {
128 work_queue_->Push(FakeTaskWithEnqueueOrder(2));
129 work_queue_->Push(FakeTaskWithEnqueueOrder(3));
130 work_queue_->Push(FakeTaskWithEnqueueOrder(4));
131
132 ASSERT_NE(nullptr, work_queue_->GetBackTask());
133 EXPECT_EQ(4ull, work_queue_->GetBackTask()->enqueue_order());
134 }
135
TEST_F(WorkQueueTest,Push)136 TEST_F(WorkQueueTest, Push) {
137 WorkQueue* work_queue;
138 EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
139
140 work_queue_->Push(FakeTaskWithEnqueueOrder(2));
141 EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
142 EXPECT_EQ(work_queue_.get(), work_queue);
143 }
144
TEST_F(WorkQueueTest,PushAfterFenceHit)145 TEST_F(WorkQueueTest, PushAfterFenceHit) {
146 work_queue_->InsertFence(EnqueueOrder::blocking_fence());
147 WorkQueue* work_queue;
148 EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
149
150 work_queue_->Push(FakeTaskWithEnqueueOrder(2));
151 EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
152 }
153
TEST_F(WorkQueueTest,PushNonNestableTaskToFront)154 TEST_F(WorkQueueTest, PushNonNestableTaskToFront) {
155 WorkQueue* work_queue;
156 EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
157
158 work_queue_->PushNonNestableTaskToFront(
159 FakeNonNestableTaskWithEnqueueOrder(3));
160 EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
161 EXPECT_EQ(work_queue_.get(), work_queue);
162
163 work_queue_->PushNonNestableTaskToFront(
164 FakeNonNestableTaskWithEnqueueOrder(2));
165
166 EXPECT_EQ(2ull, work_queue_->GetFrontTask()->enqueue_order());
167 EXPECT_EQ(3ull, work_queue_->GetBackTask()->enqueue_order());
168 }
169
TEST_F(WorkQueueTest,PushNonNestableTaskToFrontAfterFenceHit)170 TEST_F(WorkQueueTest, PushNonNestableTaskToFrontAfterFenceHit) {
171 work_queue_->InsertFence(EnqueueOrder::blocking_fence());
172 WorkQueue* work_queue;
173 EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
174
175 work_queue_->PushNonNestableTaskToFront(
176 FakeNonNestableTaskWithEnqueueOrder(2));
177 EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
178 }
179
TEST_F(WorkQueueTest,PushNonNestableTaskToFrontBeforeFenceHit)180 TEST_F(WorkQueueTest, PushNonNestableTaskToFrontBeforeFenceHit) {
181 work_queue_->InsertFence(EnqueueOrder::FromIntForTesting(3));
182 WorkQueue* work_queue;
183 EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
184
185 work_queue_->PushNonNestableTaskToFront(
186 FakeNonNestableTaskWithEnqueueOrder(2));
187 EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
188 }
189
TEST_F(WorkQueueTest,ReloadEmptyImmediateQueue)190 TEST_F(WorkQueueTest, ReloadEmptyImmediateQueue) {
191 task_queue_->PushImmediateIncomingTaskForTest(FakeTaskWithEnqueueOrder(2));
192 task_queue_->PushImmediateIncomingTaskForTest(FakeTaskWithEnqueueOrder(3));
193 task_queue_->PushImmediateIncomingTaskForTest(FakeTaskWithEnqueueOrder(4));
194
195 WorkQueue* work_queue;
196 EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
197 EXPECT_TRUE(work_queue_->Empty());
198 work_queue_->ReloadEmptyImmediateQueue();
199
200 EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
201 EXPECT_FALSE(work_queue_->Empty());
202
203 ASSERT_NE(nullptr, work_queue_->GetFrontTask());
204 EXPECT_EQ(2ull, work_queue_->GetFrontTask()->enqueue_order());
205
206 ASSERT_NE(nullptr, work_queue_->GetBackTask());
207 EXPECT_EQ(4ull, work_queue_->GetBackTask()->enqueue_order());
208 }
209
TEST_F(WorkQueueTest,ReloadEmptyImmediateQueueAfterFenceHit)210 TEST_F(WorkQueueTest, ReloadEmptyImmediateQueueAfterFenceHit) {
211 work_queue_->InsertFence(EnqueueOrder::blocking_fence());
212 task_queue_->PushImmediateIncomingTaskForTest(FakeTaskWithEnqueueOrder(2));
213 task_queue_->PushImmediateIncomingTaskForTest(FakeTaskWithEnqueueOrder(3));
214 task_queue_->PushImmediateIncomingTaskForTest(FakeTaskWithEnqueueOrder(4));
215
216 WorkQueue* work_queue;
217 EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
218 EXPECT_TRUE(work_queue_->Empty());
219 work_queue_->ReloadEmptyImmediateQueue();
220
221 EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
222 EXPECT_FALSE(work_queue_->Empty());
223
224 ASSERT_NE(nullptr, work_queue_->GetFrontTask());
225 EXPECT_EQ(2ull, work_queue_->GetFrontTask()->enqueue_order());
226
227 ASSERT_NE(nullptr, work_queue_->GetBackTask());
228 EXPECT_EQ(4ull, work_queue_->GetBackTask()->enqueue_order());
229 }
230
TEST_F(WorkQueueTest,TakeTaskFromWorkQueue)231 TEST_F(WorkQueueTest, TakeTaskFromWorkQueue) {
232 work_queue_->Push(FakeTaskWithEnqueueOrder(2));
233 work_queue_->Push(FakeTaskWithEnqueueOrder(3));
234 work_queue_->Push(FakeTaskWithEnqueueOrder(4));
235
236 WorkQueue* work_queue;
237 EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
238 EXPECT_FALSE(work_queue_->Empty());
239
240 EXPECT_EQ(2ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
241 EXPECT_EQ(3ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
242 EXPECT_EQ(4ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
243
244 EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
245 EXPECT_TRUE(work_queue_->Empty());
246 }
247
TEST_F(WorkQueueTest,TakeTaskFromWorkQueue_HitFence)248 TEST_F(WorkQueueTest, TakeTaskFromWorkQueue_HitFence) {
249 work_queue_->InsertFence(EnqueueOrder::FromIntForTesting(3));
250 work_queue_->Push(FakeTaskWithEnqueueOrder(2));
251 work_queue_->Push(FakeTaskWithEnqueueOrder(4));
252 EXPECT_FALSE(work_queue_->BlockedByFence());
253
254 WorkQueue* work_queue;
255 EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
256 EXPECT_FALSE(work_queue_->Empty());
257 EXPECT_FALSE(work_queue_->BlockedByFence());
258
259 EXPECT_EQ(2ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
260 EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
261 EXPECT_FALSE(work_queue_->Empty());
262 EXPECT_TRUE(work_queue_->BlockedByFence());
263 }
264
TEST_F(WorkQueueTest,InsertFenceBeforeEnqueueing)265 TEST_F(WorkQueueTest, InsertFenceBeforeEnqueueing) {
266 EXPECT_FALSE(work_queue_->InsertFence(EnqueueOrder::blocking_fence()));
267 EXPECT_TRUE(work_queue_->BlockedByFence());
268
269 work_queue_->Push(FakeTaskWithEnqueueOrder(2));
270 work_queue_->Push(FakeTaskWithEnqueueOrder(3));
271 work_queue_->Push(FakeTaskWithEnqueueOrder(4));
272
273 EnqueueOrder enqueue_order;
274 EXPECT_FALSE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
275 }
276
TEST_F(WorkQueueTest,InsertFenceAfterEnqueueingNonBlocking)277 TEST_F(WorkQueueTest, InsertFenceAfterEnqueueingNonBlocking) {
278 work_queue_->Push(FakeTaskWithEnqueueOrder(2));
279 work_queue_->Push(FakeTaskWithEnqueueOrder(3));
280 work_queue_->Push(FakeTaskWithEnqueueOrder(4));
281
282 EXPECT_FALSE(work_queue_->InsertFence(EnqueueOrder::FromIntForTesting(5)));
283 EXPECT_FALSE(work_queue_->BlockedByFence());
284
285 EnqueueOrder enqueue_order;
286 EXPECT_TRUE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
287 EXPECT_EQ(2ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
288 }
289
TEST_F(WorkQueueTest,InsertFenceAfterEnqueueing)290 TEST_F(WorkQueueTest, InsertFenceAfterEnqueueing) {
291 work_queue_->Push(FakeTaskWithEnqueueOrder(2));
292 work_queue_->Push(FakeTaskWithEnqueueOrder(3));
293 work_queue_->Push(FakeTaskWithEnqueueOrder(4));
294
295 // NB in reality a fence will always be greater than any currently enqueued
296 // tasks.
297 EXPECT_FALSE(work_queue_->InsertFence(EnqueueOrder::blocking_fence()));
298 EXPECT_TRUE(work_queue_->BlockedByFence());
299
300 EnqueueOrder enqueue_order;
301 EXPECT_FALSE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
302 }
303
TEST_F(WorkQueueTest,InsertNewFence)304 TEST_F(WorkQueueTest, InsertNewFence) {
305 work_queue_->Push(FakeTaskWithEnqueueOrder(2));
306 work_queue_->Push(FakeTaskWithEnqueueOrder(4));
307 work_queue_->Push(FakeTaskWithEnqueueOrder(5));
308
309 EXPECT_FALSE(work_queue_->InsertFence(EnqueueOrder::FromIntForTesting(3)));
310 EXPECT_FALSE(work_queue_->BlockedByFence());
311
312 // Note until TakeTaskFromWorkQueue() is called we don't hit the fence.
313 EnqueueOrder enqueue_order;
314 EXPECT_TRUE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
315 EXPECT_EQ(2ull, enqueue_order);
316
317 EXPECT_EQ(2ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
318 EXPECT_FALSE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
319 EXPECT_TRUE(work_queue_->BlockedByFence());
320
321 // Inserting the new fence should temporarily unblock the queue until the new
322 // one is hit.
323 EXPECT_TRUE(work_queue_->InsertFence(EnqueueOrder::FromIntForTesting(6)));
324 EXPECT_FALSE(work_queue_->BlockedByFence());
325
326 EXPECT_TRUE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
327 EXPECT_EQ(4ull, enqueue_order);
328 EXPECT_EQ(4ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
329 EXPECT_TRUE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
330 EXPECT_FALSE(work_queue_->BlockedByFence());
331 }
332
TEST_F(WorkQueueTest,PushWithNonEmptyQueueDoesNotHitFence)333 TEST_F(WorkQueueTest, PushWithNonEmptyQueueDoesNotHitFence) {
334 work_queue_->Push(FakeTaskWithEnqueueOrder(1));
335 EXPECT_FALSE(work_queue_->InsertFence(EnqueueOrder::FromIntForTesting(2)));
336 work_queue_->Push(FakeTaskWithEnqueueOrder(3));
337 EXPECT_FALSE(work_queue_->BlockedByFence());
338 }
339
TEST_F(WorkQueueTest,RemoveFence)340 TEST_F(WorkQueueTest, RemoveFence) {
341 work_queue_->Push(FakeTaskWithEnqueueOrder(2));
342 work_queue_->Push(FakeTaskWithEnqueueOrder(4));
343 work_queue_->Push(FakeTaskWithEnqueueOrder(5));
344 work_queue_->InsertFence(EnqueueOrder::FromIntForTesting(3));
345
346 WorkQueue* work_queue;
347 EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
348 EXPECT_FALSE(work_queue_->Empty());
349
350 EXPECT_EQ(2ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
351 EXPECT_FALSE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
352 EXPECT_FALSE(work_queue_->Empty());
353 EXPECT_TRUE(work_queue_->BlockedByFence());
354
355 EXPECT_TRUE(work_queue_->RemoveFence());
356 EXPECT_EQ(4ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
357 EXPECT_TRUE(work_queue_sets_->GetOldestQueueInSet(0, &work_queue));
358 EXPECT_FALSE(work_queue_->BlockedByFence());
359 }
360
TEST_F(WorkQueueTest,RemoveFenceButNoFence)361 TEST_F(WorkQueueTest, RemoveFenceButNoFence) {
362 EXPECT_FALSE(work_queue_->RemoveFence());
363 }
364
TEST_F(WorkQueueTest,RemoveFenceNothingUnblocked)365 TEST_F(WorkQueueTest, RemoveFenceNothingUnblocked) {
366 EXPECT_FALSE(work_queue_->InsertFence(EnqueueOrder::blocking_fence()));
367 EXPECT_TRUE(work_queue_->BlockedByFence());
368
369 EXPECT_FALSE(work_queue_->RemoveFence());
370 EXPECT_FALSE(work_queue_->BlockedByFence());
371 }
372
TEST_F(WorkQueueTest,BlockedByFence)373 TEST_F(WorkQueueTest, BlockedByFence) {
374 EXPECT_FALSE(work_queue_->BlockedByFence());
375 EXPECT_FALSE(work_queue_->InsertFence(EnqueueOrder::blocking_fence()));
376 EXPECT_TRUE(work_queue_->BlockedByFence());
377 }
378
TEST_F(WorkQueueTest,BlockedByFencePopBecomesEmpty)379 TEST_F(WorkQueueTest, BlockedByFencePopBecomesEmpty) {
380 work_queue_->Push(FakeTaskWithEnqueueOrder(1));
381 EXPECT_FALSE(work_queue_->InsertFence(EnqueueOrder::FromIntForTesting(2)));
382 EXPECT_FALSE(work_queue_->BlockedByFence());
383
384 EXPECT_EQ(1ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
385 EXPECT_TRUE(work_queue_->BlockedByFence());
386 }
387
TEST_F(WorkQueueTest,BlockedByFencePop)388 TEST_F(WorkQueueTest, BlockedByFencePop) {
389 work_queue_->Push(FakeTaskWithEnqueueOrder(1));
390 EXPECT_FALSE(work_queue_->InsertFence(EnqueueOrder::FromIntForTesting(2)));
391 EXPECT_FALSE(work_queue_->BlockedByFence());
392
393 work_queue_->Push(FakeTaskWithEnqueueOrder(3));
394 EXPECT_FALSE(work_queue_->BlockedByFence());
395
396 EXPECT_EQ(1ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
397 EXPECT_TRUE(work_queue_->BlockedByFence());
398 }
399
TEST_F(WorkQueueTest,InitiallyEmptyBlockedByFenceNewFenceUnblocks)400 TEST_F(WorkQueueTest, InitiallyEmptyBlockedByFenceNewFenceUnblocks) {
401 EXPECT_FALSE(work_queue_->InsertFence(EnqueueOrder::blocking_fence()));
402 EXPECT_TRUE(work_queue_->BlockedByFence());
403
404 work_queue_->Push(FakeTaskWithEnqueueOrder(2));
405 EXPECT_TRUE(work_queue_->InsertFence(EnqueueOrder::FromIntForTesting(3)));
406 EXPECT_FALSE(work_queue_->BlockedByFence());
407 }
408
TEST_F(WorkQueueTest,BlockedByFenceNewFenceUnblocks)409 TEST_F(WorkQueueTest, BlockedByFenceNewFenceUnblocks) {
410 work_queue_->Push(FakeTaskWithEnqueueOrder(1));
411 EXPECT_FALSE(work_queue_->InsertFence(EnqueueOrder::FromIntForTesting(2)));
412 EXPECT_FALSE(work_queue_->BlockedByFence());
413
414 work_queue_->Push(FakeTaskWithEnqueueOrder(3));
415 EXPECT_FALSE(work_queue_->BlockedByFence());
416
417 EXPECT_EQ(1ull, work_queue_->TakeTaskFromWorkQueue().enqueue_order());
418 EXPECT_TRUE(work_queue_->BlockedByFence());
419
420 EXPECT_TRUE(work_queue_->InsertFence(EnqueueOrder::FromIntForTesting(4)));
421 EXPECT_FALSE(work_queue_->BlockedByFence());
422 }
423
TEST_F(WorkQueueTest,InsertFenceAfterEnqueuing)424 TEST_F(WorkQueueTest, InsertFenceAfterEnqueuing) {
425 work_queue_->Push(FakeTaskWithEnqueueOrder(2));
426 work_queue_->Push(FakeTaskWithEnqueueOrder(3));
427 work_queue_->Push(FakeTaskWithEnqueueOrder(4));
428 EXPECT_FALSE(work_queue_->BlockedByFence());
429
430 EXPECT_FALSE(work_queue_->InsertFence(EnqueueOrder::blocking_fence()));
431 EXPECT_TRUE(work_queue_->BlockedByFence());
432
433 EnqueueOrder enqueue_order;
434 EXPECT_FALSE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
435 }
436
TEST_F(WorkQueueTest,RemoveAllCanceledTasksFromFront)437 TEST_F(WorkQueueTest, RemoveAllCanceledTasksFromFront) {
438 {
439 Cancelable cancelable;
440 work_queue_->Push(FakeCancelableTaskWithEnqueueOrder(
441 2, cancelable.weak_ptr_factory.GetWeakPtr()));
442 work_queue_->Push(FakeCancelableTaskWithEnqueueOrder(
443 3, cancelable.weak_ptr_factory.GetWeakPtr()));
444 work_queue_->Push(FakeCancelableTaskWithEnqueueOrder(
445 4, cancelable.weak_ptr_factory.GetWeakPtr()));
446 work_queue_->Push(FakeTaskWithEnqueueOrder(5));
447 }
448 EXPECT_TRUE(work_queue_->RemoveAllCanceledTasksFromFront());
449
450 EnqueueOrder enqueue_order;
451 EXPECT_TRUE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
452 EXPECT_EQ(5ull, enqueue_order);
453 }
454
TEST_F(WorkQueueTest,RemoveAllCanceledTasksFromFrontTasksNotCanceled)455 TEST_F(WorkQueueTest, RemoveAllCanceledTasksFromFrontTasksNotCanceled) {
456 {
457 Cancelable cancelable;
458 work_queue_->Push(FakeCancelableTaskWithEnqueueOrder(
459 2, cancelable.weak_ptr_factory.GetWeakPtr()));
460 work_queue_->Push(FakeCancelableTaskWithEnqueueOrder(
461 3, cancelable.weak_ptr_factory.GetWeakPtr()));
462 work_queue_->Push(FakeCancelableTaskWithEnqueueOrder(
463 4, cancelable.weak_ptr_factory.GetWeakPtr()));
464 work_queue_->Push(FakeTaskWithEnqueueOrder(5));
465 EXPECT_FALSE(work_queue_->RemoveAllCanceledTasksFromFront());
466
467 EnqueueOrder enqueue_order;
468 EXPECT_TRUE(work_queue_->GetFrontTaskEnqueueOrder(&enqueue_order));
469 EXPECT_EQ(2ull, enqueue_order);
470 }
471 }
472
473 } // namespace internal
474 } // namespace sequence_manager
475 } // namespace base
476