OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 // NOTE(vtl): Some of these tests are inherently flaky (e.g., if run on a | 5 // NOTE(vtl): Some of these tests are inherently flaky (e.g., if run on a |
6 // heavily-loaded system). Sorry. |test::EpsilonTimeout()| may be increased to | 6 // heavily-loaded system). Sorry. |test::EpsilonTimeout()| may be increased to |
7 // increase tolerance and reduce observed flakiness (though doing so reduces the | 7 // increase tolerance and reduce observed flakiness (though doing so reduces the |
8 // meaningfulness of the test). | 8 // meaningfulness of the test). |
9 | 9 |
10 #include "mojo/edk/system/awakable_list.h" | 10 #include "mojo/edk/system/awakable_list.h" |
11 | 11 |
| 12 #include "mojo/edk/platform/thread_utils.h" |
12 #include "mojo/edk/system/handle_signals_state.h" | 13 #include "mojo/edk/system/handle_signals_state.h" |
13 #include "mojo/edk/system/test/sleep.h" | |
14 #include "mojo/edk/system/test/timeouts.h" | 14 #include "mojo/edk/system/test/timeouts.h" |
15 #include "mojo/edk/system/waiter.h" | 15 #include "mojo/edk/system/waiter.h" |
16 #include "mojo/edk/system/waiter_test_utils.h" | 16 #include "mojo/edk/system/waiter_test_utils.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
18 | 18 |
| 19 using mojo::platform::ThreadSleep; |
| 20 |
19 namespace mojo { | 21 namespace mojo { |
20 namespace system { | 22 namespace system { |
21 namespace { | 23 namespace { |
22 | 24 |
23 TEST(AwakableListTest, BasicCancel) { | 25 TEST(AwakableListTest, BasicCancel) { |
24 MojoResult result; | 26 MojoResult result; |
25 uint32_t context; | 27 uint32_t context; |
26 | 28 |
27 // Cancel immediately after thread start. | 29 // Cancel immediately after thread start. |
28 { | 30 { |
(...skipping 18 matching lines...) Expand all Loading... |
47 } // Join |thread|. | 49 } // Join |thread|. |
48 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | 50 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); |
49 EXPECT_EQ(2u, context); | 51 EXPECT_EQ(2u, context); |
50 | 52 |
51 // Cancel some time after thread start. | 53 // Cancel some time after thread start. |
52 { | 54 { |
53 AwakableList awakable_list; | 55 AwakableList awakable_list; |
54 test::SimpleWaiterThread thread(&result, &context); | 56 test::SimpleWaiterThread thread(&result, &context); |
55 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3); | 57 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3); |
56 thread.Start(); | 58 thread.Start(); |
57 test::Sleep(2 * test::EpsilonTimeout()); | 59 ThreadSleep(2 * test::EpsilonTimeout()); |
58 awakable_list.CancelAll(); | 60 awakable_list.CancelAll(); |
59 } // Join |thread|. | 61 } // Join |thread|. |
60 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | 62 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); |
61 EXPECT_EQ(3u, context); | 63 EXPECT_EQ(3u, context); |
62 } | 64 } |
63 | 65 |
64 TEST(AwakableListTest, BasicAwakeSatisfied) { | 66 TEST(AwakableListTest, BasicAwakeSatisfied) { |
65 MojoResult result; | 67 MojoResult result; |
66 uint32_t context; | 68 uint32_t context; |
67 | 69 |
(...skipping 26 matching lines...) Expand all Loading... |
94 } // Join |thread|. | 96 } // Join |thread|. |
95 EXPECT_EQ(MOJO_RESULT_OK, result); | 97 EXPECT_EQ(MOJO_RESULT_OK, result); |
96 EXPECT_EQ(2u, context); | 98 EXPECT_EQ(2u, context); |
97 | 99 |
98 // Awake some time after thread start. | 100 // Awake some time after thread start. |
99 { | 101 { |
100 AwakableList awakable_list; | 102 AwakableList awakable_list; |
101 test::SimpleWaiterThread thread(&result, &context); | 103 test::SimpleWaiterThread thread(&result, &context); |
102 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3); | 104 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3); |
103 thread.Start(); | 105 thread.Start(); |
104 test::Sleep(2 * test::EpsilonTimeout()); | 106 ThreadSleep(2 * test::EpsilonTimeout()); |
105 awakable_list.AwakeForStateChange(HandleSignalsState( | 107 awakable_list.AwakeForStateChange(HandleSignalsState( |
106 MOJO_HANDLE_SIGNAL_READABLE, | 108 MOJO_HANDLE_SIGNAL_READABLE, |
107 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); | 109 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); |
108 awakable_list.Remove(thread.waiter()); | 110 awakable_list.Remove(thread.waiter()); |
109 } // Join |thread|. | 111 } // Join |thread|. |
110 EXPECT_EQ(MOJO_RESULT_OK, result); | 112 EXPECT_EQ(MOJO_RESULT_OK, result); |
111 EXPECT_EQ(3u, context); | 113 EXPECT_EQ(3u, context); |
112 } | 114 } |
113 | 115 |
114 TEST(AwakableListTest, BasicAwakeUnsatisfiable) { | 116 TEST(AwakableListTest, BasicAwakeUnsatisfiable) { |
(...skipping 25 matching lines...) Expand all Loading... |
140 } // Join |thread|. | 142 } // Join |thread|. |
141 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | 143 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
142 EXPECT_EQ(2u, context); | 144 EXPECT_EQ(2u, context); |
143 | 145 |
144 // Awake (for unsatisfiability) some time after thread start. | 146 // Awake (for unsatisfiability) some time after thread start. |
145 { | 147 { |
146 AwakableList awakable_list; | 148 AwakableList awakable_list; |
147 test::SimpleWaiterThread thread(&result, &context); | 149 test::SimpleWaiterThread thread(&result, &context); |
148 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3); | 150 awakable_list.Add(thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3); |
149 thread.Start(); | 151 thread.Start(); |
150 test::Sleep(2 * test::EpsilonTimeout()); | 152 ThreadSleep(2 * test::EpsilonTimeout()); |
151 awakable_list.AwakeForStateChange(HandleSignalsState( | 153 awakable_list.AwakeForStateChange(HandleSignalsState( |
152 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE)); | 154 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE)); |
153 awakable_list.Remove(thread.waiter()); | 155 awakable_list.Remove(thread.waiter()); |
154 // Double-remove okay: | 156 // Double-remove okay: |
155 awakable_list.Remove(thread.waiter()); | 157 awakable_list.Remove(thread.waiter()); |
156 } // Join |thread|. | 158 } // Join |thread|. |
157 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | 159 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
158 EXPECT_EQ(3u, context); | 160 EXPECT_EQ(3u, context); |
159 } | 161 } |
160 | 162 |
161 TEST(AwakableListTest, MultipleAwakables) { | 163 TEST(AwakableListTest, MultipleAwakables) { |
162 MojoResult result1; | 164 MojoResult result1; |
163 MojoResult result2; | 165 MojoResult result2; |
164 MojoResult result3; | 166 MojoResult result3; |
165 MojoResult result4; | 167 MojoResult result4; |
166 uint32_t context1; | 168 uint32_t context1; |
167 uint32_t context2; | 169 uint32_t context2; |
168 uint32_t context3; | 170 uint32_t context3; |
169 uint32_t context4; | 171 uint32_t context4; |
170 | 172 |
171 // Cancel two awakables. | 173 // Cancel two awakables. |
172 { | 174 { |
173 AwakableList awakable_list; | 175 AwakableList awakable_list; |
174 test::SimpleWaiterThread thread1(&result1, &context1); | 176 test::SimpleWaiterThread thread1(&result1, &context1); |
175 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1); | 177 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1); |
176 thread1.Start(); | 178 thread1.Start(); |
177 test::SimpleWaiterThread thread2(&result2, &context2); | 179 test::SimpleWaiterThread thread2(&result2, &context2); |
178 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 2); | 180 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 2); |
179 thread2.Start(); | 181 thread2.Start(); |
180 test::Sleep(2 * test::EpsilonTimeout()); | 182 ThreadSleep(2 * test::EpsilonTimeout()); |
181 awakable_list.CancelAll(); | 183 awakable_list.CancelAll(); |
182 } // Join threads. | 184 } // Join threads. |
183 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); | 185 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); |
184 EXPECT_EQ(1u, context1); | 186 EXPECT_EQ(1u, context1); |
185 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); | 187 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); |
186 EXPECT_EQ(2u, context2); | 188 EXPECT_EQ(2u, context2); |
187 | 189 |
188 // Awake one awakable, cancel other. | 190 // Awake one awakable, cancel other. |
189 { | 191 { |
190 AwakableList awakable_list; | 192 AwakableList awakable_list; |
191 test::SimpleWaiterThread thread1(&result1, &context1); | 193 test::SimpleWaiterThread thread1(&result1, &context1); |
192 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3); | 194 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3); |
193 thread1.Start(); | 195 thread1.Start(); |
194 test::SimpleWaiterThread thread2(&result2, &context2); | 196 test::SimpleWaiterThread thread2(&result2, &context2); |
195 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 4); | 197 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 4); |
196 thread2.Start(); | 198 thread2.Start(); |
197 test::Sleep(2 * test::EpsilonTimeout()); | 199 ThreadSleep(2 * test::EpsilonTimeout()); |
198 awakable_list.AwakeForStateChange(HandleSignalsState( | 200 awakable_list.AwakeForStateChange(HandleSignalsState( |
199 MOJO_HANDLE_SIGNAL_READABLE, | 201 MOJO_HANDLE_SIGNAL_READABLE, |
200 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); | 202 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); |
201 awakable_list.Remove(thread1.waiter()); | 203 awakable_list.Remove(thread1.waiter()); |
202 awakable_list.CancelAll(); | 204 awakable_list.CancelAll(); |
203 } // Join threads. | 205 } // Join threads. |
204 EXPECT_EQ(MOJO_RESULT_OK, result1); | 206 EXPECT_EQ(MOJO_RESULT_OK, result1); |
205 EXPECT_EQ(3u, context1); | 207 EXPECT_EQ(3u, context1); |
206 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); | 208 EXPECT_EQ(MOJO_RESULT_CANCELLED, result2); |
207 EXPECT_EQ(4u, context2); | 209 EXPECT_EQ(4u, context2); |
208 | 210 |
209 // Cancel one awakable, awake other for unsatisfiability. | 211 // Cancel one awakable, awake other for unsatisfiability. |
210 { | 212 { |
211 AwakableList awakable_list; | 213 AwakableList awakable_list; |
212 test::SimpleWaiterThread thread1(&result1, &context1); | 214 test::SimpleWaiterThread thread1(&result1, &context1); |
213 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 5); | 215 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 5); |
214 thread1.Start(); | 216 thread1.Start(); |
215 test::SimpleWaiterThread thread2(&result2, &context2); | 217 test::SimpleWaiterThread thread2(&result2, &context2); |
216 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 6); | 218 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 6); |
217 thread2.Start(); | 219 thread2.Start(); |
218 test::Sleep(2 * test::EpsilonTimeout()); | 220 ThreadSleep(2 * test::EpsilonTimeout()); |
219 awakable_list.AwakeForStateChange(HandleSignalsState( | 221 awakable_list.AwakeForStateChange(HandleSignalsState( |
220 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_READABLE)); | 222 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_READABLE)); |
221 awakable_list.Remove(thread2.waiter()); | 223 awakable_list.Remove(thread2.waiter()); |
222 awakable_list.CancelAll(); | 224 awakable_list.CancelAll(); |
223 } // Join threads. | 225 } // Join threads. |
224 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); | 226 EXPECT_EQ(MOJO_RESULT_CANCELLED, result1); |
225 EXPECT_EQ(5u, context1); | 227 EXPECT_EQ(5u, context1); |
226 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); | 228 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); |
227 EXPECT_EQ(6u, context2); | 229 EXPECT_EQ(6u, context2); |
228 | 230 |
229 // Cancel one awakable, awake other for unsatisfiability. | 231 // Cancel one awakable, awake other for unsatisfiability. |
230 { | 232 { |
231 AwakableList awakable_list; | 233 AwakableList awakable_list; |
232 test::SimpleWaiterThread thread1(&result1, &context1); | 234 test::SimpleWaiterThread thread1(&result1, &context1); |
233 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 7); | 235 awakable_list.Add(thread1.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 7); |
234 thread1.Start(); | 236 thread1.Start(); |
235 | 237 |
236 test::Sleep(1 * test::EpsilonTimeout()); | 238 ThreadSleep(1 * test::EpsilonTimeout()); |
237 | 239 |
238 // Should do nothing. | 240 // Should do nothing. |
239 awakable_list.AwakeForStateChange(HandleSignalsState( | 241 awakable_list.AwakeForStateChange(HandleSignalsState( |
240 MOJO_HANDLE_SIGNAL_NONE, | 242 MOJO_HANDLE_SIGNAL_NONE, |
241 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); | 243 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); |
242 | 244 |
243 test::SimpleWaiterThread thread2(&result2, &context2); | 245 test::SimpleWaiterThread thread2(&result2, &context2); |
244 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 8); | 246 awakable_list.Add(thread2.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 8); |
245 thread2.Start(); | 247 thread2.Start(); |
246 | 248 |
247 test::Sleep(1 * test::EpsilonTimeout()); | 249 ThreadSleep(1 * test::EpsilonTimeout()); |
248 | 250 |
249 // Awake #1. | 251 // Awake #1. |
250 awakable_list.AwakeForStateChange(HandleSignalsState( | 252 awakable_list.AwakeForStateChange(HandleSignalsState( |
251 MOJO_HANDLE_SIGNAL_READABLE, | 253 MOJO_HANDLE_SIGNAL_READABLE, |
252 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); | 254 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE)); |
253 awakable_list.Remove(thread1.waiter()); | 255 awakable_list.Remove(thread1.waiter()); |
254 | 256 |
255 test::Sleep(1 * test::EpsilonTimeout()); | 257 ThreadSleep(1 * test::EpsilonTimeout()); |
256 | 258 |
257 test::SimpleWaiterThread thread3(&result3, &context3); | 259 test::SimpleWaiterThread thread3(&result3, &context3); |
258 awakable_list.Add(thread3.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 9); | 260 awakable_list.Add(thread3.waiter(), MOJO_HANDLE_SIGNAL_WRITABLE, 9); |
259 thread3.Start(); | 261 thread3.Start(); |
260 | 262 |
261 test::SimpleWaiterThread thread4(&result4, &context4); | 263 test::SimpleWaiterThread thread4(&result4, &context4); |
262 awakable_list.Add(thread4.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 10); | 264 awakable_list.Add(thread4.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 10); |
263 thread4.Start(); | 265 thread4.Start(); |
264 | 266 |
265 test::Sleep(1 * test::EpsilonTimeout()); | 267 ThreadSleep(1 * test::EpsilonTimeout()); |
266 | 268 |
267 // Awake #2 and #3 for unsatisfiability. | 269 // Awake #2 and #3 for unsatisfiability. |
268 awakable_list.AwakeForStateChange(HandleSignalsState( | 270 awakable_list.AwakeForStateChange(HandleSignalsState( |
269 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_READABLE)); | 271 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_READABLE)); |
270 awakable_list.Remove(thread2.waiter()); | 272 awakable_list.Remove(thread2.waiter()); |
271 awakable_list.Remove(thread3.waiter()); | 273 awakable_list.Remove(thread3.waiter()); |
272 | 274 |
273 // Cancel #4. | 275 // Cancel #4. |
274 awakable_list.CancelAll(); | 276 awakable_list.CancelAll(); |
275 } // Join threads. | 277 } // Join threads. |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 EXPECT_EQ(keep1.awake_count, 2); | 350 EXPECT_EQ(keep1.awake_count, 2); |
349 EXPECT_EQ(remove2.awake_count, 1); | 351 EXPECT_EQ(remove2.awake_count, 1); |
350 | 352 |
351 remove_first.Remove(&keep0); | 353 remove_first.Remove(&keep0); |
352 remove_first.Remove(&keep1); | 354 remove_first.Remove(&keep1); |
353 } | 355 } |
354 | 356 |
355 } // namespace | 357 } // namespace |
356 } // namespace system | 358 } // namespace system |
357 } // namespace mojo | 359 } // namespace mojo |
OLD | NEW |