Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: test/unittests/cancelable-tasks-unittest.cc

Issue 1409993012: Add {CancelableTaskManager} to handle {Cancelable} concurrent tasks. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fixed concurrent version including unittests Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 the V8 project 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 "src/base/atomicops.h"
6 #include "src/base/platform/platform.h"
7 #include "src/cancelable-task.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9
10
11 namespace v8 {
12 namespace internal {
13
14 namespace {
15
16 class MockTask : public Task, public Cancelable {
17 public:
18 enum Mode { kDoNothing, kWaitTillCanceledAgain, kCheckNotRun };
19
20 MockTask(CancelableTaskManager* parent, base::AtomicWord* result,
21 Mode mode = kDoNothing)
22 : Cancelable(parent), result_(result), mode_(mode) {}
23
24 // Task overrides.
25 void Run() final {
26 if (TryRun()) {
27 RunInternal();
28 }
29 }
30
31 private:
32 void RunInternal() {
33 *result_ = id();
34 base::Release_Store(result_, id());
35
36 switch (mode_) {
37 case kWaitTillCanceledAgain:
38 // Simple busy wait until the main thread tried to cancel.
39 while (CancelAttempts() == 0) {
40 }
41 break;
42 case kCheckNotRun:
43 // Check that we never execute {RunInternal}.
44 EXPECT_TRUE(false);
45 break;
46 default:
47 break;
48 }
49 }
50
51 base::AtomicWord* result_;
52 Mode mode_;
53 };
54
55
56 class SequentialRunner {
57 public:
58 explicit SequentialRunner(MockTask* task) : task_(task) {}
59
60 void Run() {
61 task_->Run();
62 delete task_;
63 }
64
65 private:
66 MockTask* task_;
67 };
68
69
70 class ThreadedRunner final : public base::Thread {
71 public:
72 explicit ThreadedRunner(MockTask* task)
73 : Thread(Options("runner thread")), task_(task) {}
74
75 virtual void Run() {
76 task_->Run();
77 delete task_;
78 }
79
80 private:
81 MockTask* task_;
82 };
83
84
85 typedef base::AtomicWord ResultType;
86
87
88 intptr_t GetValue(ResultType* result) { return base::Acquire_Load(result); }
89
90 } // namespace
91
92
93 TEST(CancelableTask, ManagerBasic) {
94 CancelableTaskManager manager;
95 manager.CancelAndWait();
96 }
97
98
99 TEST(CancelableTask, SimpleCancelAndWait) {
100 CancelableTaskManager manager;
101 ResultType result1 = 0;
102 SequentialRunner runner1(
103 new MockTask(&manager, &result1, MockTask::kCheckNotRun));
104 EXPECT_EQ(GetValue(&result1), 0);
105 manager.CancelAndWait();
106 EXPECT_EQ(GetValue(&result1), 0);
107 }
108
109
110 TEST(CancelableTask, SimpleMultipleTasks) {
111 CancelableTaskManager manager;
112 ResultType result1 = 0;
113 ResultType result2 = 0;
114 MockTask* task1 = new MockTask(&manager, &result1);
115 MockTask* task2 = new MockTask(&manager, &result2);
116 SequentialRunner runner1(task1);
117 SequentialRunner runner2(task2);
118 EXPECT_EQ(task1->id(), 1);
119 EXPECT_EQ(task2->id(), 2);
120
121 EXPECT_EQ(GetValue(&result1), 0);
122 runner1.Run(); // Don't touch task1 after running it.
123 EXPECT_EQ(GetValue(&result1), 1);
124
125 EXPECT_EQ(GetValue(&result2), 0);
126 runner2.Run(); // Don't touch task2 after running it.
127 EXPECT_EQ(GetValue(&result2), 2);
128
129 manager.CancelAndWait();
130 EXPECT_EQ(manager.Remove(1), false);
131 EXPECT_EQ(manager.Remove(2), false);
132 }
133
134
135 TEST(CancelableTask, ThreadedMultipleTasksStarted) {
136 CancelableTaskManager manager;
137 ResultType result1 = 0;
138 ResultType result2 = 0;
139 MockTask* task1 =
140 new MockTask(&manager, &result1, MockTask::kWaitTillCanceledAgain);
141 MockTask* task2 =
142 new MockTask(&manager, &result2, MockTask::kWaitTillCanceledAgain);
143 ThreadedRunner runner1(task1);
144 ThreadedRunner runner2(task2);
145 runner1.Start();
146 runner2.Start();
147 // Busy wait on result.
148 while ((GetValue(&result1) == 0) || (GetValue(&result2) == 0)) {
149 }
150 manager.CancelAndWait();
151 runner1.Join();
152 runner2.Join();
153 EXPECT_EQ(GetValue(&result1), 1);
154 EXPECT_EQ(GetValue(&result2), 2);
155 }
156
157
158 TEST(CancelableTask, ThreadedMultipleTasksNotRun) {
159 CancelableTaskManager manager;
160 ResultType result1 = 0;
161 ResultType result2 = 0;
162 MockTask* task1 = new MockTask(&manager, &result1, MockTask::kCheckNotRun);
163 MockTask* task2 = new MockTask(&manager, &result2, MockTask::kCheckNotRun);
164 ThreadedRunner runner1(task1);
165 ThreadedRunner runner2(task2);
166 manager.CancelAndWait();
167 runner1.Start();
168 runner2.Start();
169 runner1.Join();
170 runner2.Join();
171 EXPECT_EQ(GetValue(&result1), 0);
172 EXPECT_EQ(GetValue(&result2), 0);
173 }
174
175
176 TEST(CancelableTask, Cancel) {
177 CancelableTaskManager manager;
178 ResultType result1 = 0;
179 MockTask* task1 = new MockTask(&manager, &result1, MockTask::kCheckNotRun);
180 ThreadedRunner runner1(task1);
181 uint32_t id = task1->id();
182 EXPECT_EQ(id, 1);
183 EXPECT_TRUE(manager.Remove(id));
184 runner1.Start();
185 runner1.Join();
186 manager.CancelAndWait();
187 EXPECT_EQ(GetValue(&result1), 0);
188 }
189
190 } // namespace internal
191 } // namespace v8
OLDNEW
« src/cancelable-task.cc ('K') | « src/isolate.cc ('k') | test/unittests/unittests.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698