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
3 // found in the LICENSE file.
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
7 // increase tolerance and reduce observed flakiness (though doing so reduces the
8 // meaningfulness of the test).
10 #include "mojo/system/simple_dispatcher.h"
12 #include "base/logging.h"
13 #include "base/macros.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_vector.h"
16 #include "base/synchronization/lock.h"
17 #include "base/threading/platform_thread.h" // For |Sleep()|.
18 #include "base/time/time.h"
19 #include "mojo/system/test_utils.h"
20 #include "mojo/system/waiter.h"
21 #include "mojo/system/waiter_test_utils.h"
22 #include "testing/gtest/include/gtest/gtest.h"
28 class MockSimpleDispatcher : public SimpleDispatcher {
30 MockSimpleDispatcher()
31 : state_(MOJO_HANDLE_SIGNAL_NONE,
32 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE) {}
34 void SetSatisfiedSignals(MojoHandleSignals new_satisfied_signals) {
35 base::AutoLock locker(lock());
37 // Any new signals that are set should be satisfiable.
38 CHECK_EQ(new_satisfied_signals & ~state_.satisfied_signals,
39 new_satisfied_signals & ~state_.satisfied_signals &
40 state_.satisfiable_signals);
42 if (new_satisfied_signals == state_.satisfied_signals)
45 state_.satisfied_signals = new_satisfied_signals;
46 HandleSignalsStateChangedNoLock();
49 void SetSatisfiableSignals(MojoHandleSignals new_satisfiable_signals) {
50 base::AutoLock locker(lock());
52 // Satisfied implies satisfiable.
53 CHECK_EQ(new_satisfiable_signals & state_.satisfied_signals,
54 state_.satisfied_signals);
56 if (new_satisfiable_signals == state_.satisfiable_signals)
59 state_.satisfiable_signals = new_satisfiable_signals;
60 HandleSignalsStateChangedNoLock();
63 virtual Type GetType() const OVERRIDE { return kTypeUnknown; }
66 friend class base::RefCountedThreadSafe<MockSimpleDispatcher>;
67 virtual ~MockSimpleDispatcher() {}
69 virtual scoped_refptr<Dispatcher>
70 CreateEquivalentDispatcherAndCloseImplNoLock() OVERRIDE {
71 scoped_refptr<MockSimpleDispatcher> rv(new MockSimpleDispatcher());
73 return scoped_refptr<Dispatcher>(rv.get());
76 // |Dispatcher| override:
77 virtual HandleSignalsState GetHandleSignalsStateImplNoLock() const OVERRIDE {
78 lock().AssertAcquired();
82 // Protected by |lock()|:
83 HandleSignalsState state_;
85 DISALLOW_COPY_AND_ASSIGN(MockSimpleDispatcher);
89 // http://crbug.com/396404
90 #define MAYBE_Basic DISABLED_Basic
92 #define MAYBE_Basic Basic
94 TEST(SimpleDispatcherTest, MAYBE_Basic) {
95 test::Stopwatch stopwatch;
97 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
100 HandleSignalsState hss;
102 // Try adding a readable waiter when already readable.
104 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
105 hss = HandleSignalsState();
106 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
107 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss));
108 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
109 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
110 hss.satisfiable_signals);
111 // Shouldn't need to remove the waiter (it was not added).
113 // Wait (forever) for writable when already writable.
115 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
116 ASSERT_EQ(MOJO_RESULT_OK,
117 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 1, nullptr));
118 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_WRITABLE);
120 EXPECT_EQ(MOJO_RESULT_OK, w.Wait(MOJO_DEADLINE_INDEFINITE, &context));
121 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
122 EXPECT_EQ(1u, context);
123 hss = HandleSignalsState();
124 d->RemoveWaiter(&w, &hss);
125 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
126 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
127 hss.satisfiable_signals);
129 // Wait for zero time for writable when already writable.
131 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
132 ASSERT_EQ(MOJO_RESULT_OK,
133 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 2, nullptr));
134 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_WRITABLE);
136 EXPECT_EQ(MOJO_RESULT_OK, w.Wait(0, &context));
137 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
138 EXPECT_EQ(2u, context);
139 hss = HandleSignalsState();
140 d->RemoveWaiter(&w, &hss);
141 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
142 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
143 hss.satisfiable_signals);
145 // Wait for non-zero, finite time for writable when already writable.
147 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
148 ASSERT_EQ(MOJO_RESULT_OK,
149 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 3, nullptr));
150 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_WRITABLE);
152 EXPECT_EQ(MOJO_RESULT_OK,
153 w.Wait(2 * test::EpsilonTimeout().InMicroseconds(), &context));
154 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
155 EXPECT_EQ(3u, context);
156 hss = HandleSignalsState();
157 d->RemoveWaiter(&w, &hss);
158 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
159 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
160 hss.satisfiable_signals);
162 // Wait for zero time for writable when not writable (will time out).
164 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
165 ASSERT_EQ(MOJO_RESULT_OK,
166 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 4, nullptr));
168 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0, nullptr));
169 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
170 hss = HandleSignalsState();
171 d->RemoveWaiter(&w, &hss);
172 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
173 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
174 hss.satisfiable_signals);
176 // Wait for non-zero, finite time for writable when not writable (will time
179 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
180 ASSERT_EQ(MOJO_RESULT_OK,
181 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 5, nullptr));
183 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
184 w.Wait(2 * test::EpsilonTimeout().InMicroseconds(), nullptr));
185 base::TimeDelta elapsed = stopwatch.Elapsed();
186 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonTimeout());
187 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonTimeout());
188 hss = HandleSignalsState();
189 d->RemoveWaiter(&w, &hss);
190 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
191 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
192 hss.satisfiable_signals);
194 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
197 TEST(SimpleDispatcherTest, BasicUnsatisfiable) {
198 test::Stopwatch stopwatch;
200 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
202 uint32_t context = 0;
203 HandleSignalsState hss;
205 // Try adding a writable waiter when it can never be writable.
207 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE);
208 d->SetSatisfiedSignals(0);
209 hss = HandleSignalsState();
210 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
211 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 1, &hss));
212 EXPECT_EQ(0u, hss.satisfied_signals);
213 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
214 // Shouldn't need to remove the waiter (it was not added).
216 // Wait (forever) for writable and then it becomes never writable.
218 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE |
219 MOJO_HANDLE_SIGNAL_WRITABLE);
220 ASSERT_EQ(MOJO_RESULT_OK,
221 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 2, nullptr));
222 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE);
224 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
225 w.Wait(MOJO_DEADLINE_INDEFINITE, &context));
226 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
227 EXPECT_EQ(2u, context);
228 hss = HandleSignalsState();
229 d->RemoveWaiter(&w, &hss);
230 EXPECT_EQ(0u, hss.satisfied_signals);
231 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
233 // Wait for zero time for writable and then it becomes never writable.
235 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE |
236 MOJO_HANDLE_SIGNAL_WRITABLE);
237 ASSERT_EQ(MOJO_RESULT_OK,
238 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 3, nullptr));
239 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE);
241 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, w.Wait(0, &context));
242 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
243 EXPECT_EQ(3u, context);
244 hss = HandleSignalsState();
245 d->RemoveWaiter(&w, &hss);
246 EXPECT_EQ(0u, hss.satisfied_signals);
247 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
249 // Wait for non-zero, finite time for writable and then it becomes never
252 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE |
253 MOJO_HANDLE_SIGNAL_WRITABLE);
254 ASSERT_EQ(MOJO_RESULT_OK,
255 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 4, nullptr));
256 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE);
258 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
259 w.Wait(2 * test::EpsilonTimeout().InMicroseconds(), &context));
260 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
261 EXPECT_EQ(4u, context);
262 hss = HandleSignalsState();
263 d->RemoveWaiter(&w, &hss);
264 EXPECT_EQ(0u, hss.satisfied_signals);
265 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
267 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
270 TEST(SimpleDispatcherTest, BasicClosed) {
271 test::Stopwatch stopwatch;
273 scoped_refptr<MockSimpleDispatcher> d;
275 uint32_t context = 0;
276 HandleSignalsState hss;
278 // Try adding a writable waiter when the dispatcher has been closed.
279 d = new MockSimpleDispatcher();
281 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
282 hss = HandleSignalsState();
283 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
284 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 1, &hss));
285 EXPECT_EQ(0u, hss.satisfied_signals);
286 EXPECT_EQ(0u, hss.satisfiable_signals);
287 // Shouldn't need to remove the waiter (it was not added).
289 // Wait (forever) for writable and then the dispatcher is closed.
290 d = new MockSimpleDispatcher();
292 ASSERT_EQ(MOJO_RESULT_OK,
293 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 2, nullptr));
294 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
296 EXPECT_EQ(MOJO_RESULT_CANCELLED, w.Wait(MOJO_DEADLINE_INDEFINITE, &context));
297 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
298 EXPECT_EQ(2u, context);
299 // Don't need to remove waiters from closed dispatchers.
301 // Wait for zero time for writable and then the dispatcher is closed.
302 d = new MockSimpleDispatcher();
304 ASSERT_EQ(MOJO_RESULT_OK,
305 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 3, nullptr));
306 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
308 EXPECT_EQ(MOJO_RESULT_CANCELLED, w.Wait(0, &context));
309 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
310 EXPECT_EQ(3u, context);
311 // Don't need to remove waiters from closed dispatchers.
313 // Wait for non-zero, finite time for writable and then the dispatcher is
315 d = new MockSimpleDispatcher();
317 ASSERT_EQ(MOJO_RESULT_OK,
318 d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 4, nullptr));
319 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
321 EXPECT_EQ(MOJO_RESULT_CANCELLED,
322 w.Wait(2 * test::EpsilonTimeout().InMicroseconds(), &context));
323 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
324 EXPECT_EQ(4u, context);
325 // Don't need to remove waiters from closed dispatchers.
329 // http://crbug.com/396393
330 #define MAYBE_BasicThreaded DISABLED_BasicThreaded
332 #define MAYBE_BasicThreaded BasicThreaded
334 TEST(SimpleDispatcherTest, MAYBE_BasicThreaded) {
335 test::Stopwatch stopwatch;
339 HandleSignalsState hss;
341 // Wait for readable (already readable).
343 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
345 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
346 test::WaiterThread thread(d,
347 MOJO_HANDLE_SIGNAL_READABLE,
348 MOJO_DEADLINE_INDEFINITE,
356 } // Joins the thread.
357 // If we closed earlier, then probably we'd get a |MOJO_RESULT_CANCELLED|.
358 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
360 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
361 EXPECT_FALSE(did_wait);
362 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, result);
363 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
364 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
365 hss.satisfiable_signals);
367 // Wait for readable and becomes readable after some time.
369 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
371 test::WaiterThread thread(d,
372 MOJO_HANDLE_SIGNAL_READABLE,
373 MOJO_DEADLINE_INDEFINITE,
381 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
382 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
383 } // Joins the thread.
384 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
386 base::TimeDelta elapsed = stopwatch.Elapsed();
387 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonTimeout());
388 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonTimeout());
389 EXPECT_TRUE(did_wait);
390 EXPECT_EQ(MOJO_RESULT_OK, result);
391 EXPECT_EQ(2u, context);
392 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
393 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
394 hss.satisfiable_signals);
396 // Wait for readable and becomes never-readable after some time.
398 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
400 test::WaiterThread thread(d,
401 MOJO_HANDLE_SIGNAL_READABLE,
402 MOJO_DEADLINE_INDEFINITE,
410 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
411 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_NONE);
412 } // Joins the thread.
413 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
415 elapsed = stopwatch.Elapsed();
416 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonTimeout());
417 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonTimeout());
418 EXPECT_TRUE(did_wait);
419 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
420 EXPECT_EQ(3u, context);
421 EXPECT_EQ(0u, hss.satisfied_signals);
422 EXPECT_EQ(0u, hss.satisfiable_signals);
424 // Wait for readable and dispatcher gets closed.
426 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
427 test::WaiterThread thread(d,
428 MOJO_HANDLE_SIGNAL_READABLE,
429 MOJO_DEADLINE_INDEFINITE,
437 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
438 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
439 } // Joins the thread.
440 elapsed = stopwatch.Elapsed();
441 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonTimeout());
442 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonTimeout());
443 EXPECT_TRUE(did_wait);
444 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
445 EXPECT_EQ(4u, context);
446 EXPECT_EQ(0u, hss.satisfied_signals);
447 EXPECT_EQ(0u, hss.satisfiable_signals);
449 // Wait for readable and times out.
451 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
453 test::WaiterThread thread(d,
454 MOJO_HANDLE_SIGNAL_READABLE,
455 2 * test::EpsilonTimeout().InMicroseconds(),
463 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
464 // Not what we're waiting for.
465 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_WRITABLE);
466 } // Joins the thread (after its wait times out).
467 // If we closed earlier, then probably we'd get a |MOJO_RESULT_CANCELLED|.
468 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
470 elapsed = stopwatch.Elapsed();
471 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonTimeout());
472 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonTimeout());
473 EXPECT_TRUE(did_wait);
474 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result);
475 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
476 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
477 hss.satisfiable_signals);
481 // http://crbug.com/387124
482 #define MAYBE_MultipleWaiters DISABLED_MultipleWaiters
484 #define MAYBE_MultipleWaiters MultipleWaiters
486 TEST(SimpleDispatcherTest, MAYBE_MultipleWaiters) {
487 static const uint32_t kNumWaiters = 20;
489 bool did_wait[kNumWaiters];
490 MojoResult result[kNumWaiters];
491 uint32_t context[kNumWaiters];
492 HandleSignalsState hss[kNumWaiters];
494 // All wait for readable and becomes readable after some time.
496 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
497 ScopedVector<test::WaiterThread> threads;
498 for (uint32_t i = 0; i < kNumWaiters; i++) {
499 threads.push_back(new test::WaiterThread(d,
500 MOJO_HANDLE_SIGNAL_READABLE,
501 MOJO_DEADLINE_INDEFINITE,
507 threads.back()->Start();
509 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
510 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
511 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
512 } // Joins the threads.
513 for (uint32_t i = 0; i < kNumWaiters; i++) {
514 EXPECT_TRUE(did_wait[i]) << i;
515 EXPECT_EQ(MOJO_RESULT_OK, result[i]) << i;
516 EXPECT_EQ(i, context[i]) << i;
517 // Since we closed before joining, we can't say much about what each thread
521 // Some wait for readable, some for writable, and becomes readable after some
524 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
525 ScopedVector<test::WaiterThread> threads;
526 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
527 threads.push_back(new test::WaiterThread(d,
528 MOJO_HANDLE_SIGNAL_READABLE,
529 MOJO_DEADLINE_INDEFINITE,
535 threads.back()->Start();
537 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
538 threads.push_back(new test::WaiterThread(d,
539 MOJO_HANDLE_SIGNAL_WRITABLE,
540 MOJO_DEADLINE_INDEFINITE,
546 threads.back()->Start();
548 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
549 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
550 // This will wake up the ones waiting to write.
551 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
552 } // Joins the threads.
553 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
554 EXPECT_TRUE(did_wait[i]) << i;
555 EXPECT_EQ(MOJO_RESULT_OK, result[i]) << i;
556 EXPECT_EQ(i, context[i]) << i;
557 // Since we closed before joining, we can't say much about what each thread
560 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
561 EXPECT_TRUE(did_wait[i]) << i;
562 EXPECT_EQ(MOJO_RESULT_CANCELLED, result[i]) << i;
563 EXPECT_EQ(i, context[i]) << i;
564 // Since we closed before joining, we can't say much about what each thread
568 // Some wait for readable, some for writable, and becomes readable and
569 // never-writable after some time.
571 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
572 ScopedVector<test::WaiterThread> threads;
573 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
574 threads.push_back(new test::WaiterThread(d,
575 MOJO_HANDLE_SIGNAL_READABLE,
576 MOJO_DEADLINE_INDEFINITE,
582 threads.back()->Start();
584 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
585 threads.push_back(new test::WaiterThread(d,
586 MOJO_HANDLE_SIGNAL_WRITABLE,
587 MOJO_DEADLINE_INDEFINITE,
593 threads.back()->Start();
595 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
596 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE);
597 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
598 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
599 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
600 } // Joins the threads.
601 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
602 EXPECT_TRUE(did_wait[i]) << i;
603 EXPECT_EQ(MOJO_RESULT_OK, result[i]) << i;
604 EXPECT_EQ(i, context[i]) << i;
605 // Since we closed before joining, we can't say much about what each thread
608 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
609 EXPECT_TRUE(did_wait[i]) << i;
610 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result[i]) << i;
611 EXPECT_EQ(i, context[i]) << i;
612 // Since we closed before joining, we can't say much about what each thread
616 // Some wait for readable, some for writable, and becomes readable after some
619 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
620 ScopedVector<test::WaiterThread> threads;
621 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
623 new test::WaiterThread(d,
624 MOJO_HANDLE_SIGNAL_READABLE,
625 3 * test::EpsilonTimeout().InMicroseconds(),
631 threads.back()->Start();
633 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
635 new test::WaiterThread(d,
636 MOJO_HANDLE_SIGNAL_WRITABLE,
637 1 * test::EpsilonTimeout().InMicroseconds(),
643 threads.back()->Start();
645 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
646 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
647 // All those waiting for writable should have timed out.
648 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
649 } // Joins the threads.
650 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
651 EXPECT_TRUE(did_wait[i]) << i;
652 EXPECT_EQ(MOJO_RESULT_OK, result[i]) << i;
653 EXPECT_EQ(i, context[i]) << i;
654 // Since we closed before joining, we can't say much about what each thread
657 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
658 EXPECT_TRUE(did_wait[i]) << i;
659 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result[i]) << i;
660 // Since we closed before joining, we can't say much about what each thread
665 // TODO(vtl): Stress test?
668 } // namespace system