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

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: Addressed comments 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
« no previous file with comments | « src/isolate.cc ('k') | test/unittests/unittests.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 TestTask : public Task, public Cancelable {
17 public:
18 enum Mode { kDoNothing, kWaitTillCanceledAgain, kCheckNotRun };
19
20 TestTask(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 base::Release_Store(result_, id());
34
35 switch (mode_) {
36 case kWaitTillCanceledAgain:
37 // Simple busy wait until the main thread tried to cancel.
38 while (CancelAttempts() == 0) {
39 }
40 break;
41 case kCheckNotRun:
42 // Check that we never execute {RunInternal}.
43 EXPECT_TRUE(false);
44 break;
45 default:
46 break;
47 }
48 }
49
50 base::AtomicWord* result_;
51 Mode mode_;
52 };
53
54
55 class SequentialRunner {
56 public:
57 explicit SequentialRunner(TestTask* task) : task_(task) {}
58
59 void Run() {
60 task_->Run();
61 delete task_;
62 }
63
64 private:
65 TestTask* task_;
66 };
67
68
69 class ThreadedRunner final : public base::Thread {
70 public:
71 explicit ThreadedRunner(TestTask* task)
72 : Thread(Options("runner thread")), task_(task) {}
73
74 virtual void Run() {
75 task_->Run();
76 delete task_;
77 }
78
79 private:
80 TestTask* task_;
81 };
82
83
84 typedef base::AtomicWord ResultType;
85
86
87 intptr_t GetValue(ResultType* result) { return base::Acquire_Load(result); }
88
89 } // namespace
90
91
92 TEST(CancelableTask, EmptyCancelableTaskManager) {
93 CancelableTaskManager manager;
94 manager.CancelAndWait();
95 }
96
97
98 TEST(CancelableTask, SequentialCancelAndWait) {
99 CancelableTaskManager manager;
100 ResultType result1 = 0;
101 SequentialRunner runner1(
102 new TestTask(&manager, &result1, TestTask::kCheckNotRun));
103 EXPECT_EQ(GetValue(&result1), 0);
104 manager.CancelAndWait();
105 EXPECT_EQ(GetValue(&result1), 0);
106 runner1.Run(); // Run to avoid leaking the Task.
107 EXPECT_EQ(GetValue(&result1), 0);
108 }
109
110
111 TEST(CancelableTask, SequentialMultipleTasks) {
112 CancelableTaskManager manager;
113 ResultType result1 = 0;
114 ResultType result2 = 0;
115 TestTask* task1 = new TestTask(&manager, &result1);
116 TestTask* task2 = new TestTask(&manager, &result2);
117 SequentialRunner runner1(task1);
118 SequentialRunner runner2(task2);
119 EXPECT_EQ(task1->id(), 1);
120 EXPECT_EQ(task2->id(), 2);
121
122 EXPECT_EQ(GetValue(&result1), 0);
123 runner1.Run(); // Don't touch task1 after running it.
124 EXPECT_EQ(GetValue(&result1), 1);
125
126 EXPECT_EQ(GetValue(&result2), 0);
127 runner2.Run(); // Don't touch task2 after running it.
128 EXPECT_EQ(GetValue(&result2), 2);
129
130 manager.CancelAndWait();
131 EXPECT_FALSE(manager.TryAbort(1));
132 EXPECT_FALSE(manager.TryAbort(2));
133 }
134
135
136 TEST(CancelableTask, ThreadedMultipleTasksStarted) {
137 CancelableTaskManager manager;
138 ResultType result1 = 0;
139 ResultType result2 = 0;
140 TestTask* task1 =
141 new TestTask(&manager, &result1, TestTask::kWaitTillCanceledAgain);
142 TestTask* task2 =
143 new TestTask(&manager, &result2, TestTask::kWaitTillCanceledAgain);
144 ThreadedRunner runner1(task1);
145 ThreadedRunner runner2(task2);
146 runner1.Start();
147 runner2.Start();
148 // Busy wait on result to make sure both tasks are done.
149 while ((GetValue(&result1) == 0) || (GetValue(&result2) == 0)) {
150 }
151 manager.CancelAndWait();
152 runner1.Join();
153 runner2.Join();
154 EXPECT_EQ(GetValue(&result1), 1);
155 EXPECT_EQ(GetValue(&result2), 2);
156 }
157
158
159 TEST(CancelableTask, ThreadedMultipleTasksNotRun) {
160 CancelableTaskManager manager;
161 ResultType result1 = 0;
162 ResultType result2 = 0;
163 TestTask* task1 = new TestTask(&manager, &result1, TestTask::kCheckNotRun);
164 TestTask* task2 = new TestTask(&manager, &result2, TestTask::kCheckNotRun);
165 ThreadedRunner runner1(task1);
166 ThreadedRunner runner2(task2);
167 manager.CancelAndWait();
168 // Tasks are canceled, hence the runner will bail out and not update result.
169 runner1.Start();
170 runner2.Start();
171 runner1.Join();
172 runner2.Join();
173 EXPECT_EQ(GetValue(&result1), 0);
174 EXPECT_EQ(GetValue(&result2), 0);
175 }
176
177
178 TEST(CancelableTask, RemoveBeforeCancelAndWait) {
179 CancelableTaskManager manager;
180 ResultType result1 = 0;
181 TestTask* task1 = new TestTask(&manager, &result1, TestTask::kCheckNotRun);
182 ThreadedRunner runner1(task1);
183 uint32_t id = task1->id();
184 EXPECT_EQ(id, 1);
185 EXPECT_TRUE(manager.TryAbort(id));
186 runner1.Start();
187 runner1.Join();
188 manager.CancelAndWait();
189 EXPECT_EQ(GetValue(&result1), 0);
190 }
191
192
193 TEST(CancelableTask, RemoveAfterCancelAndWait) {
194 CancelableTaskManager manager;
195 ResultType result1 = 0;
196 TestTask* task1 = new TestTask(&manager, &result1);
197 ThreadedRunner runner1(task1);
198 uint32_t id = task1->id();
199 EXPECT_EQ(id, 1);
200 runner1.Start();
201 runner1.Join();
202 manager.CancelAndWait();
203 EXPECT_FALSE(manager.TryAbort(id));
204 EXPECT_EQ(GetValue(&result1), 1);
205 }
206
207
208 TEST(CancelableTask, RemoveUnmanagedId) {
209 CancelableTaskManager manager;
210 EXPECT_FALSE(manager.TryAbort(1));
211 EXPECT_FALSE(manager.TryAbort(2));
212 manager.CancelAndWait();
213 EXPECT_FALSE(manager.TryAbort(1));
214 EXPECT_FALSE(manager.TryAbort(3));
215 }
216
217 } // namespace internal
218 } // namespace v8
OLDNEW
« no previous file with comments | « src/isolate.cc ('k') | test/unittests/unittests.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698