| 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 |