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::EpsilonDeadline()| may be increased to | 6 // heavily-loaded system). Sorry. |test::EpsilonDeadline()| 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/simple_dispatcher.h" | 10 #include "mojo/edk/system/simple_dispatcher.h" |
11 | 11 |
12 #include <memory> | 12 #include <memory> |
13 #include <vector> | 13 #include <vector> |
14 | 14 |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/memory/ref_counted.h" | 16 #include "mojo/edk/system/ref_ptr.h" |
17 #include "mojo/edk/system/test_utils.h" | 17 #include "mojo/edk/system/test_utils.h" |
| 18 #include "mojo/edk/system/thread_annotations.h" |
18 #include "mojo/edk/system/waiter.h" | 19 #include "mojo/edk/system/waiter.h" |
19 #include "mojo/edk/system/waiter_test_utils.h" | 20 #include "mojo/edk/system/waiter_test_utils.h" |
20 #include "mojo/edk/util/make_unique.h" | 21 #include "mojo/edk/util/make_unique.h" |
21 #include "mojo/public/cpp/system/macros.h" | 22 #include "mojo/public/cpp/system/macros.h" |
22 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
23 | 24 |
24 namespace mojo { | 25 namespace mojo { |
25 namespace system { | 26 namespace system { |
26 namespace { | 27 namespace { |
27 | 28 |
28 class MockSimpleDispatcher final : public SimpleDispatcher { | 29 class MockSimpleDispatcher final : public SimpleDispatcher { |
29 public: | 30 public: |
30 MockSimpleDispatcher() | 31 // Note: Use |MakeRefCounted<MockSimpleDispatcher>()|. |
31 : state_(MOJO_HANDLE_SIGNAL_NONE, | |
32 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE) {} | |
33 explicit MockSimpleDispatcher(const HandleSignalsState& state) | |
34 : state_(state) {} | |
35 | 32 |
36 void SetSatisfiedSignals(MojoHandleSignals new_satisfied_signals) { | 33 void SetSatisfiedSignals(MojoHandleSignals new_satisfied_signals) { |
37 MutexLocker locker(&mutex()); | 34 MutexLocker locker(&mutex()); |
38 | 35 |
39 // Any new signals that are set should be satisfiable. | 36 // Any new signals that are set should be satisfiable. |
40 CHECK_EQ(new_satisfied_signals & ~state_.satisfied_signals, | 37 CHECK_EQ(new_satisfied_signals & ~state_.satisfied_signals, |
41 new_satisfied_signals & ~state_.satisfied_signals & | 38 new_satisfied_signals & ~state_.satisfied_signals & |
42 state_.satisfiable_signals); | 39 state_.satisfiable_signals); |
43 | 40 |
44 if (new_satisfied_signals == state_.satisfied_signals) | 41 if (new_satisfied_signals == state_.satisfied_signals) |
(...skipping 13 matching lines...) Expand all Loading... |
58 if (new_satisfiable_signals == state_.satisfiable_signals) | 55 if (new_satisfiable_signals == state_.satisfiable_signals) |
59 return; | 56 return; |
60 | 57 |
61 state_.satisfiable_signals = new_satisfiable_signals; | 58 state_.satisfiable_signals = new_satisfiable_signals; |
62 HandleSignalsStateChangedNoLock(); | 59 HandleSignalsStateChangedNoLock(); |
63 } | 60 } |
64 | 61 |
65 Type GetType() const override { return Type::UNKNOWN; } | 62 Type GetType() const override { return Type::UNKNOWN; } |
66 | 63 |
67 private: | 64 private: |
| 65 FRIEND_MAKE_REF_COUNTED(MockSimpleDispatcher); |
| 66 |
| 67 MockSimpleDispatcher() |
| 68 : state_(MOJO_HANDLE_SIGNAL_NONE, |
| 69 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE) {} |
| 70 explicit MockSimpleDispatcher(const HandleSignalsState& state) |
| 71 : state_(state) {} |
68 ~MockSimpleDispatcher() override {} | 72 ~MockSimpleDispatcher() override {} |
69 | 73 |
70 scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndCloseImplNoLock() | 74 RefPtr<Dispatcher> CreateEquivalentDispatcherAndCloseImplNoLock() override |
71 override { | 75 MOJO_NO_THREAD_SAFETY_ANALYSIS { |
72 scoped_refptr<MockSimpleDispatcher> rv(new MockSimpleDispatcher(state_)); | 76 return MakeRefCounted<MockSimpleDispatcher>(state_); |
73 return scoped_refptr<Dispatcher>(rv.get()); | |
74 } | 77 } |
75 | 78 |
76 // |Dispatcher| override: | 79 // |Dispatcher| override: |
77 HandleSignalsState GetHandleSignalsStateImplNoLock() const override { | 80 HandleSignalsState GetHandleSignalsStateImplNoLock() const override { |
78 mutex().AssertHeld(); | 81 mutex().AssertHeld(); |
79 return state_; | 82 return state_; |
80 } | 83 } |
81 | 84 |
82 HandleSignalsState state_ MOJO_GUARDED_BY(mutex()); | 85 HandleSignalsState state_ MOJO_GUARDED_BY(mutex()); |
83 | 86 |
84 MOJO_DISALLOW_COPY_AND_ASSIGN(MockSimpleDispatcher); | 87 MOJO_DISALLOW_COPY_AND_ASSIGN(MockSimpleDispatcher); |
85 }; | 88 }; |
86 | 89 |
87 TEST(SimpleDispatcherTest, Basic) { | 90 TEST(SimpleDispatcherTest, Basic) { |
88 test::Stopwatch stopwatch; | 91 test::Stopwatch stopwatch; |
89 | 92 |
90 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher()); | 93 auto d = MakeRefCounted<MockSimpleDispatcher>(); |
91 Waiter w; | 94 Waiter w; |
92 uint32_t context = 0; | 95 uint32_t context = 0; |
93 HandleSignalsState hss; | 96 HandleSignalsState hss; |
94 | 97 |
95 // Try adding a readable waiter when already readable. | 98 // Try adding a readable waiter when already readable. |
96 w.Init(); | 99 w.Init(); |
97 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE); | 100 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE); |
98 hss = HandleSignalsState(); | 101 hss = HandleSignalsState(); |
99 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | 102 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, |
100 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss)); | 103 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss)); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); | 185 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); |
183 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | 186 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, |
184 hss.satisfiable_signals); | 187 hss.satisfiable_signals); |
185 | 188 |
186 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); | 189 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); |
187 } | 190 } |
188 | 191 |
189 TEST(SimpleDispatcherTest, BasicUnsatisfiable) { | 192 TEST(SimpleDispatcherTest, BasicUnsatisfiable) { |
190 test::Stopwatch stopwatch; | 193 test::Stopwatch stopwatch; |
191 | 194 |
192 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher()); | 195 auto d = MakeRefCounted<MockSimpleDispatcher>(); |
193 Waiter w; | 196 Waiter w; |
194 uint32_t context = 0; | 197 uint32_t context = 0; |
195 HandleSignalsState hss; | 198 HandleSignalsState hss; |
196 | 199 |
197 // Try adding a writable waiter when it can never be writable. | 200 // Try adding a writable waiter when it can never be writable. |
198 w.Init(); | 201 w.Init(); |
199 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE); | 202 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE); |
200 d->SetSatisfiedSignals(0); | 203 d->SetSatisfiedSignals(0); |
201 hss = HandleSignalsState(); | 204 hss = HandleSignalsState(); |
202 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | 205 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 d->RemoveAwakable(&w, &hss); | 258 d->RemoveAwakable(&w, &hss); |
256 EXPECT_EQ(0u, hss.satisfied_signals); | 259 EXPECT_EQ(0u, hss.satisfied_signals); |
257 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); | 260 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); |
258 | 261 |
259 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); | 262 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); |
260 } | 263 } |
261 | 264 |
262 TEST(SimpleDispatcherTest, BasicClosed) { | 265 TEST(SimpleDispatcherTest, BasicClosed) { |
263 test::Stopwatch stopwatch; | 266 test::Stopwatch stopwatch; |
264 | 267 |
265 scoped_refptr<MockSimpleDispatcher> d; | 268 RefPtr<MockSimpleDispatcher> d; |
266 Waiter w; | 269 Waiter w; |
267 uint32_t context = 0; | 270 uint32_t context = 0; |
268 HandleSignalsState hss; | 271 HandleSignalsState hss; |
269 | 272 |
270 // Try adding a writable waiter when the dispatcher has been closed. | 273 // Try adding a writable waiter when the dispatcher has been closed. |
271 d = new MockSimpleDispatcher(); | 274 d = MakeRefCounted<MockSimpleDispatcher>(); |
272 w.Init(); | 275 w.Init(); |
273 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); | 276 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); |
274 hss = HandleSignalsState(); | 277 hss = HandleSignalsState(); |
275 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | 278 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, |
276 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 1, &hss)); | 279 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 1, &hss)); |
277 EXPECT_EQ(0u, hss.satisfied_signals); | 280 EXPECT_EQ(0u, hss.satisfied_signals); |
278 EXPECT_EQ(0u, hss.satisfiable_signals); | 281 EXPECT_EQ(0u, hss.satisfiable_signals); |
279 // Shouldn't need to remove the waiter (it was not added). | 282 // Shouldn't need to remove the waiter (it was not added). |
280 | 283 |
281 // Wait (forever) for writable and then the dispatcher is closed. | 284 // Wait (forever) for writable and then the dispatcher is closed. |
282 d = new MockSimpleDispatcher(); | 285 d = MakeRefCounted<MockSimpleDispatcher>(); |
283 w.Init(); | 286 w.Init(); |
284 ASSERT_EQ(MOJO_RESULT_OK, | 287 ASSERT_EQ(MOJO_RESULT_OK, |
285 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 2, nullptr)); | 288 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 2, nullptr)); |
286 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); | 289 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); |
287 stopwatch.Start(); | 290 stopwatch.Start(); |
288 EXPECT_EQ(MOJO_RESULT_CANCELLED, w.Wait(MOJO_DEADLINE_INDEFINITE, &context)); | 291 EXPECT_EQ(MOJO_RESULT_CANCELLED, w.Wait(MOJO_DEADLINE_INDEFINITE, &context)); |
289 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline()); | 292 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline()); |
290 EXPECT_EQ(2u, context); | 293 EXPECT_EQ(2u, context); |
291 // Don't need to remove waiters from closed dispatchers. | 294 // Don't need to remove waiters from closed dispatchers. |
292 | 295 |
293 // Wait for zero time for writable and then the dispatcher is closed. | 296 // Wait for zero time for writable and then the dispatcher is closed. |
294 d = new MockSimpleDispatcher(); | 297 d = MakeRefCounted<MockSimpleDispatcher>(); |
295 w.Init(); | 298 w.Init(); |
296 ASSERT_EQ(MOJO_RESULT_OK, | 299 ASSERT_EQ(MOJO_RESULT_OK, |
297 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 3, nullptr)); | 300 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 3, nullptr)); |
298 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); | 301 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); |
299 stopwatch.Start(); | 302 stopwatch.Start(); |
300 EXPECT_EQ(MOJO_RESULT_CANCELLED, w.Wait(0, &context)); | 303 EXPECT_EQ(MOJO_RESULT_CANCELLED, w.Wait(0, &context)); |
301 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline()); | 304 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline()); |
302 EXPECT_EQ(3u, context); | 305 EXPECT_EQ(3u, context); |
303 // Don't need to remove waiters from closed dispatchers. | 306 // Don't need to remove waiters from closed dispatchers. |
304 | 307 |
305 // Wait for non-zero, finite time for writable and then the dispatcher is | 308 // Wait for non-zero, finite time for writable and then the dispatcher is |
306 // closed. | 309 // closed. |
307 d = new MockSimpleDispatcher(); | 310 d = MakeRefCounted<MockSimpleDispatcher>(); |
308 w.Init(); | 311 w.Init(); |
309 ASSERT_EQ(MOJO_RESULT_OK, | 312 ASSERT_EQ(MOJO_RESULT_OK, |
310 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 4, nullptr)); | 313 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 4, nullptr)); |
311 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); | 314 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); |
312 stopwatch.Start(); | 315 stopwatch.Start(); |
313 EXPECT_EQ(MOJO_RESULT_CANCELLED, | 316 EXPECT_EQ(MOJO_RESULT_CANCELLED, |
314 w.Wait(2 * test::EpsilonDeadline(), &context)); | 317 w.Wait(2 * test::EpsilonDeadline(), &context)); |
315 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline()); | 318 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline()); |
316 EXPECT_EQ(4u, context); | 319 EXPECT_EQ(4u, context); |
317 // Don't need to remove waiters from closed dispatchers. | 320 // Don't need to remove waiters from closed dispatchers. |
318 } | 321 } |
319 | 322 |
320 TEST(SimpleDispatcherTest, BasicThreaded) { | 323 TEST(SimpleDispatcherTest, BasicThreaded) { |
321 test::Stopwatch stopwatch; | 324 test::Stopwatch stopwatch; |
322 bool did_wait; | 325 bool did_wait; |
323 MojoResult result; | 326 MojoResult result; |
324 uint32_t context; | 327 uint32_t context; |
325 HandleSignalsState hss; | 328 HandleSignalsState hss; |
326 | 329 |
327 // Wait for readable (already readable). | 330 // Wait for readable (already readable). |
328 { | 331 { |
329 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher()); | 332 auto d = MakeRefCounted<MockSimpleDispatcher>(); |
330 { | 333 { |
331 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE); | 334 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE); |
332 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE, | 335 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE, |
333 MOJO_DEADLINE_INDEFINITE, 1, &did_wait, &result, | 336 MOJO_DEADLINE_INDEFINITE, 1, &did_wait, &result, |
334 &context, &hss); | 337 &context, &hss); |
335 stopwatch.Start(); | 338 stopwatch.Start(); |
336 thread.Start(); | 339 thread.Start(); |
337 } // Joins the thread. | 340 } // Joins the thread. |
338 // If we closed earlier, then probably we'd get a |MOJO_RESULT_CANCELLED|. | 341 // If we closed earlier, then probably we'd get a |MOJO_RESULT_CANCELLED|. |
339 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); | 342 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); |
340 } | 343 } |
341 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline()); | 344 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline()); |
342 EXPECT_FALSE(did_wait); | 345 EXPECT_FALSE(did_wait); |
343 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, result); | 346 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, result); |
344 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); | 347 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); |
345 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | 348 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, |
346 hss.satisfiable_signals); | 349 hss.satisfiable_signals); |
347 | 350 |
348 // Wait for readable and becomes readable after some time. | 351 // Wait for readable and becomes readable after some time. |
349 { | 352 { |
350 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher()); | 353 auto d = MakeRefCounted<MockSimpleDispatcher>(); |
351 { | 354 { |
352 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE, | 355 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE, |
353 MOJO_DEADLINE_INDEFINITE, 2, &did_wait, &result, | 356 MOJO_DEADLINE_INDEFINITE, 2, &did_wait, &result, |
354 &context, &hss); | 357 &context, &hss); |
355 stopwatch.Start(); | 358 stopwatch.Start(); |
356 thread.Start(); | 359 thread.Start(); |
357 test::Sleep(2 * test::EpsilonDeadline()); | 360 test::Sleep(2 * test::EpsilonDeadline()); |
358 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE); | 361 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE); |
359 } // Joins the thread. | 362 } // Joins the thread. |
360 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); | 363 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); |
361 } | 364 } |
362 MojoDeadline elapsed = stopwatch.Elapsed(); | 365 MojoDeadline elapsed = stopwatch.Elapsed(); |
363 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonDeadline()); | 366 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonDeadline()); |
364 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonDeadline()); | 367 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonDeadline()); |
365 EXPECT_TRUE(did_wait); | 368 EXPECT_TRUE(did_wait); |
366 EXPECT_EQ(MOJO_RESULT_OK, result); | 369 EXPECT_EQ(MOJO_RESULT_OK, result); |
367 EXPECT_EQ(2u, context); | 370 EXPECT_EQ(2u, context); |
368 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); | 371 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); |
369 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | 372 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, |
370 hss.satisfiable_signals); | 373 hss.satisfiable_signals); |
371 | 374 |
372 // Wait for readable and becomes never-readable after some time. | 375 // Wait for readable and becomes never-readable after some time. |
373 { | 376 { |
374 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher()); | 377 auto d = MakeRefCounted<MockSimpleDispatcher>(); |
375 { | 378 { |
376 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE, | 379 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE, |
377 MOJO_DEADLINE_INDEFINITE, 3, &did_wait, &result, | 380 MOJO_DEADLINE_INDEFINITE, 3, &did_wait, &result, |
378 &context, &hss); | 381 &context, &hss); |
379 stopwatch.Start(); | 382 stopwatch.Start(); |
380 thread.Start(); | 383 thread.Start(); |
381 test::Sleep(2 * test::EpsilonDeadline()); | 384 test::Sleep(2 * test::EpsilonDeadline()); |
382 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_NONE); | 385 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_NONE); |
383 } // Joins the thread. | 386 } // Joins the thread. |
384 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); | 387 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); |
385 } | 388 } |
386 elapsed = stopwatch.Elapsed(); | 389 elapsed = stopwatch.Elapsed(); |
387 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonDeadline()); | 390 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonDeadline()); |
388 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonDeadline()); | 391 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonDeadline()); |
389 EXPECT_TRUE(did_wait); | 392 EXPECT_TRUE(did_wait); |
390 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | 393 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
391 EXPECT_EQ(3u, context); | 394 EXPECT_EQ(3u, context); |
392 EXPECT_EQ(0u, hss.satisfied_signals); | 395 EXPECT_EQ(0u, hss.satisfied_signals); |
393 EXPECT_EQ(0u, hss.satisfiable_signals); | 396 EXPECT_EQ(0u, hss.satisfiable_signals); |
394 | 397 |
395 // Wait for readable and dispatcher gets closed. | 398 // Wait for readable and dispatcher gets closed. |
396 { | 399 { |
397 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher()); | 400 auto d = MakeRefCounted<MockSimpleDispatcher>(); |
398 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE, | 401 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE, |
399 MOJO_DEADLINE_INDEFINITE, 4, &did_wait, &result, | 402 MOJO_DEADLINE_INDEFINITE, 4, &did_wait, &result, |
400 &context, &hss); | 403 &context, &hss); |
401 stopwatch.Start(); | 404 stopwatch.Start(); |
402 thread.Start(); | 405 thread.Start(); |
403 test::Sleep(2 * test::EpsilonDeadline()); | 406 test::Sleep(2 * test::EpsilonDeadline()); |
404 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); | 407 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); |
405 } // Joins the thread. | 408 } // Joins the thread. |
406 elapsed = stopwatch.Elapsed(); | 409 elapsed = stopwatch.Elapsed(); |
407 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonDeadline()); | 410 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonDeadline()); |
408 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonDeadline()); | 411 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonDeadline()); |
409 EXPECT_TRUE(did_wait); | 412 EXPECT_TRUE(did_wait); |
410 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | 413 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); |
411 EXPECT_EQ(4u, context); | 414 EXPECT_EQ(4u, context); |
412 EXPECT_EQ(0u, hss.satisfied_signals); | 415 EXPECT_EQ(0u, hss.satisfied_signals); |
413 EXPECT_EQ(0u, hss.satisfiable_signals); | 416 EXPECT_EQ(0u, hss.satisfiable_signals); |
414 | 417 |
415 // Wait for readable and times out. | 418 // Wait for readable and times out. |
416 { | 419 { |
417 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher()); | 420 auto d = MakeRefCounted<MockSimpleDispatcher>(); |
418 { | 421 { |
419 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE, | 422 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE, |
420 2 * test::EpsilonDeadline(), 5, &did_wait, | 423 2 * test::EpsilonDeadline(), 5, &did_wait, |
421 &result, &context, &hss); | 424 &result, &context, &hss); |
422 stopwatch.Start(); | 425 stopwatch.Start(); |
423 thread.Start(); | 426 thread.Start(); |
424 test::Sleep(1 * test::EpsilonDeadline()); | 427 test::Sleep(1 * test::EpsilonDeadline()); |
425 // Not what we're waiting for. | 428 // Not what we're waiting for. |
426 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_WRITABLE); | 429 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_WRITABLE); |
427 } // Joins the thread (after its wait times out). | 430 } // Joins the thread (after its wait times out). |
(...skipping 13 matching lines...) Expand all Loading... |
441 TEST(SimpleDispatcherTest, MultipleWaiters) { | 444 TEST(SimpleDispatcherTest, MultipleWaiters) { |
442 static const uint32_t kNumWaiters = 20; | 445 static const uint32_t kNumWaiters = 20; |
443 | 446 |
444 bool did_wait[kNumWaiters]; | 447 bool did_wait[kNumWaiters]; |
445 MojoResult result[kNumWaiters]; | 448 MojoResult result[kNumWaiters]; |
446 uint32_t context[kNumWaiters]; | 449 uint32_t context[kNumWaiters]; |
447 HandleSignalsState hss[kNumWaiters]; | 450 HandleSignalsState hss[kNumWaiters]; |
448 | 451 |
449 // All wait for readable and becomes readable after some time. | 452 // All wait for readable and becomes readable after some time. |
450 { | 453 { |
451 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher()); | 454 auto d = MakeRefCounted<MockSimpleDispatcher>(); |
452 std::vector<std::unique_ptr<test::WaiterThread>> threads; | 455 std::vector<std::unique_ptr<test::WaiterThread>> threads; |
453 for (uint32_t i = 0; i < kNumWaiters; i++) { | 456 for (uint32_t i = 0; i < kNumWaiters; i++) { |
454 threads.push_back(util::MakeUnique<test::WaiterThread>( | 457 threads.push_back(util::MakeUnique<test::WaiterThread>( |
455 d, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, i, | 458 d, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, i, |
456 &did_wait[i], &result[i], &context[i], &hss[i])); | 459 &did_wait[i], &result[i], &context[i], &hss[i])); |
457 threads.back()->Start(); | 460 threads.back()->Start(); |
458 } | 461 } |
459 test::Sleep(2 * test::EpsilonDeadline()); | 462 test::Sleep(2 * test::EpsilonDeadline()); |
460 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE); | 463 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE); |
461 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); | 464 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); |
462 } // Joins the threads. | 465 } // Joins the threads. |
463 for (uint32_t i = 0; i < kNumWaiters; i++) { | 466 for (uint32_t i = 0; i < kNumWaiters; i++) { |
464 EXPECT_TRUE(did_wait[i]) << i; | 467 EXPECT_TRUE(did_wait[i]) << i; |
465 EXPECT_EQ(MOJO_RESULT_OK, result[i]) << i; | 468 EXPECT_EQ(MOJO_RESULT_OK, result[i]) << i; |
466 EXPECT_EQ(i, context[i]) << i; | 469 EXPECT_EQ(i, context[i]) << i; |
467 // Since we closed before joining, we can't say much about what each thread | 470 // Since we closed before joining, we can't say much about what each thread |
468 // saw as the state. | 471 // saw as the state. |
469 } | 472 } |
470 | 473 |
471 // Some wait for readable, some for writable, and becomes readable after some | 474 // Some wait for readable, some for writable, and becomes readable after some |
472 // time. | 475 // time. |
473 { | 476 { |
474 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher()); | 477 auto d = MakeRefCounted<MockSimpleDispatcher>(); |
475 std::vector<std::unique_ptr<test::WaiterThread>> threads; | 478 std::vector<std::unique_ptr<test::WaiterThread>> threads; |
476 for (uint32_t i = 0; i < kNumWaiters / 2; i++) { | 479 for (uint32_t i = 0; i < kNumWaiters / 2; i++) { |
477 threads.push_back(util::MakeUnique<test::WaiterThread>( | 480 threads.push_back(util::MakeUnique<test::WaiterThread>( |
478 d, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, i, | 481 d, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, i, |
479 &did_wait[i], &result[i], &context[i], &hss[i])); | 482 &did_wait[i], &result[i], &context[i], &hss[i])); |
480 threads.back()->Start(); | 483 threads.back()->Start(); |
481 } | 484 } |
482 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) { | 485 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) { |
483 threads.push_back(util::MakeUnique<test::WaiterThread>( | 486 threads.push_back(util::MakeUnique<test::WaiterThread>( |
484 d, MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE, i, | 487 d, MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE, i, |
(...skipping 16 matching lines...) Expand all Loading... |
501 EXPECT_TRUE(did_wait[i]) << i; | 504 EXPECT_TRUE(did_wait[i]) << i; |
502 EXPECT_EQ(MOJO_RESULT_CANCELLED, result[i]) << i; | 505 EXPECT_EQ(MOJO_RESULT_CANCELLED, result[i]) << i; |
503 EXPECT_EQ(i, context[i]) << i; | 506 EXPECT_EQ(i, context[i]) << i; |
504 // Since we closed before joining, we can't say much about what each thread | 507 // Since we closed before joining, we can't say much about what each thread |
505 // saw as the state. | 508 // saw as the state. |
506 } | 509 } |
507 | 510 |
508 // Some wait for readable, some for writable, and becomes readable and | 511 // Some wait for readable, some for writable, and becomes readable and |
509 // never-writable after some time. | 512 // never-writable after some time. |
510 { | 513 { |
511 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher()); | 514 auto d = MakeRefCounted<MockSimpleDispatcher>(); |
512 std::vector<std::unique_ptr<test::WaiterThread>> threads; | 515 std::vector<std::unique_ptr<test::WaiterThread>> threads; |
513 for (uint32_t i = 0; i < kNumWaiters / 2; i++) { | 516 for (uint32_t i = 0; i < kNumWaiters / 2; i++) { |
514 threads.push_back(util::MakeUnique<test::WaiterThread>( | 517 threads.push_back(util::MakeUnique<test::WaiterThread>( |
515 d, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, i, | 518 d, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, i, |
516 &did_wait[i], &result[i], &context[i], &hss[i])); | 519 &did_wait[i], &result[i], &context[i], &hss[i])); |
517 threads.back()->Start(); | 520 threads.back()->Start(); |
518 } | 521 } |
519 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) { | 522 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) { |
520 threads.push_back(util::MakeUnique<test::WaiterThread>( | 523 threads.push_back(util::MakeUnique<test::WaiterThread>( |
521 d, MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE, i, | 524 d, MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE, i, |
(...skipping 17 matching lines...) Expand all Loading... |
539 EXPECT_TRUE(did_wait[i]) << i; | 542 EXPECT_TRUE(did_wait[i]) << i; |
540 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result[i]) << i; | 543 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result[i]) << i; |
541 EXPECT_EQ(i, context[i]) << i; | 544 EXPECT_EQ(i, context[i]) << i; |
542 // Since we closed before joining, we can't say much about what each thread | 545 // Since we closed before joining, we can't say much about what each thread |
543 // saw as the state. | 546 // saw as the state. |
544 } | 547 } |
545 | 548 |
546 // Some wait for readable, some for writable, and becomes readable after some | 549 // Some wait for readable, some for writable, and becomes readable after some |
547 // time. | 550 // time. |
548 { | 551 { |
549 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher()); | 552 auto d = MakeRefCounted<MockSimpleDispatcher>(); |
550 std::vector<std::unique_ptr<test::WaiterThread>> threads; | 553 std::vector<std::unique_ptr<test::WaiterThread>> threads; |
551 for (uint32_t i = 0; i < kNumWaiters / 2; i++) { | 554 for (uint32_t i = 0; i < kNumWaiters / 2; i++) { |
552 threads.push_back(util::MakeUnique<test::WaiterThread>( | 555 threads.push_back(util::MakeUnique<test::WaiterThread>( |
553 d, MOJO_HANDLE_SIGNAL_READABLE, 3 * test::EpsilonDeadline(), i, | 556 d, MOJO_HANDLE_SIGNAL_READABLE, 3 * test::EpsilonDeadline(), i, |
554 &did_wait[i], &result[i], &context[i], &hss[i])); | 557 &did_wait[i], &result[i], &context[i], &hss[i])); |
555 threads.back()->Start(); | 558 threads.back()->Start(); |
556 } | 559 } |
557 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) { | 560 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) { |
558 threads.push_back(util::MakeUnique<test::WaiterThread>( | 561 threads.push_back(util::MakeUnique<test::WaiterThread>( |
559 d, MOJO_HANDLE_SIGNAL_WRITABLE, 1 * test::EpsilonDeadline(), i, | 562 d, MOJO_HANDLE_SIGNAL_WRITABLE, 1 * test::EpsilonDeadline(), i, |
(...skipping 18 matching lines...) Expand all Loading... |
578 // Since we closed before joining, we can't say much about what each thread | 581 // Since we closed before joining, we can't say much about what each thread |
579 // saw as the state. | 582 // saw as the state. |
580 } | 583 } |
581 } | 584 } |
582 | 585 |
583 // TODO(vtl): Stress test? | 586 // TODO(vtl): Stress test? |
584 | 587 |
585 } // namespace | 588 } // namespace |
586 } // namespace system | 589 } // namespace system |
587 } // namespace mojo | 590 } // namespace mojo |
OLD | NEW |