/src/mozilla-central/xpcom/tests/gtest/TestTaskQueue.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #include "gtest/gtest.h" |
8 | | #include "mozilla/SharedThreadPool.h" |
9 | | #include "mozilla/TaskQueue.h" |
10 | | #include "mozilla/Unused.h" |
11 | | #include "VideoUtils.h" |
12 | | |
13 | | namespace TestTaskQueue { |
14 | | |
15 | | using namespace mozilla; |
16 | | |
17 | | TEST(TaskQueue, EventOrder) |
18 | 0 | { |
19 | 0 | RefPtr<TaskQueue> tq1 = |
20 | 0 | new TaskQueue(GetMediaThreadPool(MediaThreadType::PLAYBACK), true); |
21 | 0 | RefPtr<TaskQueue> tq2 = |
22 | 0 | new TaskQueue(GetMediaThreadPool(MediaThreadType::PLAYBACK), true); |
23 | 0 | RefPtr<TaskQueue> tq3 = |
24 | 0 | new TaskQueue(GetMediaThreadPool(MediaThreadType::PLAYBACK), true); |
25 | 0 |
|
26 | 0 | bool errored = false; |
27 | 0 | int counter = 0; |
28 | 0 | int sync = 0; |
29 | 0 | Monitor monitor("TaskQueue::EventOrder::monitor"); |
30 | 0 |
|
31 | 0 | // We expect task1 happens before task3. |
32 | 0 | for (int i = 0; i < 10000; ++i) { |
33 | 0 | Unused << tq1->Dispatch( |
34 | 0 | NS_NewRunnableFunction( |
35 | 0 | "TestTaskQueue::TaskQueue_EventOrder_Test::TestBody", |
36 | 0 | [&]() { |
37 | 0 | Unused << tq2->Dispatch(NS_NewRunnableFunction( |
38 | 0 | "TestTaskQueue::TaskQueue_EventOrder_Test::TestBody", |
39 | 0 | []() { // task0 |
40 | 0 | })); |
41 | 0 | Unused << tq3->Dispatch(NS_NewRunnableFunction( |
42 | 0 | "TestTaskQueue::TaskQueue_EventOrder_Test::TestBody", |
43 | 0 | [&]() { // task1 |
44 | 0 | EXPECT_EQ(1, ++counter); |
45 | 0 | errored = counter != 1; |
46 | 0 | MonitorAutoLock mon(monitor); |
47 | 0 | ++sync; |
48 | 0 | mon.Notify(); |
49 | 0 | })); |
50 | 0 | Unused << tq2->Dispatch(NS_NewRunnableFunction( |
51 | 0 | "TestTaskQueue::TaskQueue_EventOrder_Test::TestBody", |
52 | 0 | [&]() { // task2 |
53 | 0 | Unused << tq3->Dispatch(NS_NewRunnableFunction( |
54 | 0 | "TestTaskQueue::TaskQueue_EventOrder_Test::TestBody", |
55 | 0 | [&]() { // task3 |
56 | 0 | EXPECT_EQ(0, --counter); |
57 | 0 | errored = counter != 0; |
58 | 0 | MonitorAutoLock mon(monitor); |
59 | 0 | ++sync; |
60 | 0 | mon.Notify(); |
61 | 0 | })); |
62 | 0 | })); |
63 | 0 | }), |
64 | 0 | AbstractThread::TailDispatch); |
65 | 0 |
|
66 | 0 | // Ensure task1 and task3 are done before next loop. |
67 | 0 | MonitorAutoLock mon(monitor); |
68 | 0 | while (sync != 2) { |
69 | 0 | mon.Wait(); |
70 | 0 | } |
71 | 0 | sync = 0; |
72 | 0 |
|
73 | 0 | if (errored) { |
74 | 0 | break; |
75 | 0 | } |
76 | 0 | } |
77 | 0 |
|
78 | 0 | tq1->BeginShutdown(); |
79 | 0 | tq1->AwaitShutdownAndIdle(); |
80 | 0 | tq2->BeginShutdown(); |
81 | 0 | tq2->AwaitShutdownAndIdle(); |
82 | 0 | tq3->BeginShutdown(); |
83 | 0 | tq3->AwaitShutdownAndIdle(); |
84 | 0 | } |
85 | | |
86 | | } // namespace TestTaskQueue |