Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / mojo / system / simple_dispatcher_unittest.cc
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.
4
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).
9
10 #include "mojo/system/simple_dispatcher.h"
11
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"
23
24 namespace mojo {
25 namespace system {
26 namespace {
27
28 class MockSimpleDispatcher : public SimpleDispatcher {
29  public:
30   MockSimpleDispatcher()
31       : state_(MOJO_HANDLE_SIGNAL_NONE,
32                MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE) {}
33
34   void SetSatisfiedSignals(MojoHandleSignals new_satisfied_signals) {
35     base::AutoLock locker(lock());
36
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);
41
42     if (new_satisfied_signals == state_.satisfied_signals)
43       return;
44
45     state_.satisfied_signals = new_satisfied_signals;
46     HandleSignalsStateChangedNoLock();
47   }
48
49   void SetSatisfiableSignals(MojoHandleSignals new_satisfiable_signals) {
50     base::AutoLock locker(lock());
51
52     // Satisfied implies satisfiable.
53     CHECK_EQ(new_satisfiable_signals & state_.satisfied_signals,
54              state_.satisfied_signals);
55
56     if (new_satisfiable_signals == state_.satisfiable_signals)
57       return;
58
59     state_.satisfiable_signals = new_satisfiable_signals;
60     HandleSignalsStateChangedNoLock();
61   }
62
63   virtual Type GetType() const OVERRIDE { return kTypeUnknown; }
64
65  private:
66   friend class base::RefCountedThreadSafe<MockSimpleDispatcher>;
67   virtual ~MockSimpleDispatcher() {}
68
69   virtual scoped_refptr<Dispatcher>
70   CreateEquivalentDispatcherAndCloseImplNoLock() OVERRIDE {
71     scoped_refptr<MockSimpleDispatcher> rv(new MockSimpleDispatcher());
72     rv->state_ = state_;
73     return scoped_refptr<Dispatcher>(rv.get());
74   }
75
76   // |Dispatcher| override:
77   virtual HandleSignalsState GetHandleSignalsStateImplNoLock() const OVERRIDE {
78     lock().AssertAcquired();
79     return state_;
80   }
81
82   // Protected by |lock()|:
83   HandleSignalsState state_;
84
85   DISALLOW_COPY_AND_ASSIGN(MockSimpleDispatcher);
86 };
87
88 #if defined(OS_WIN)
89 // http://crbug.com/396404
90 #define MAYBE_Basic DISABLED_Basic
91 #else
92 #define MAYBE_Basic Basic
93 #endif
94 TEST(SimpleDispatcherTest, MAYBE_Basic) {
95   test::Stopwatch stopwatch;
96
97   scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
98   Waiter w;
99   uint32_t context = 0;
100   HandleSignalsState hss;
101
102   // Try adding a readable waiter when already readable.
103   w.Init();
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).
112
113   // Wait (forever) for writable when already writable.
114   w.Init();
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);
119   stopwatch.Start();
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);
128
129   // Wait for zero time for writable when already writable.
130   w.Init();
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);
135   stopwatch.Start();
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);
144
145   // Wait for non-zero, finite time for writable when already writable.
146   w.Init();
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);
151   stopwatch.Start();
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);
161
162   // Wait for zero time for writable when not writable (will time out).
163   w.Init();
164   d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
165   ASSERT_EQ(MOJO_RESULT_OK,
166             d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 4, nullptr));
167   stopwatch.Start();
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);
175
176   // Wait for non-zero, finite time for writable when not writable (will time
177   // out).
178   w.Init();
179   d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
180   ASSERT_EQ(MOJO_RESULT_OK,
181             d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 5, nullptr));
182   stopwatch.Start();
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);
193
194   EXPECT_EQ(MOJO_RESULT_OK, d->Close());
195 }
196
197 TEST(SimpleDispatcherTest, BasicUnsatisfiable) {
198   test::Stopwatch stopwatch;
199
200   scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
201   Waiter w;
202   uint32_t context = 0;
203   HandleSignalsState hss;
204
205   // Try adding a writable waiter when it can never be writable.
206   w.Init();
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).
215
216   // Wait (forever) for writable and then it becomes never writable.
217   w.Init();
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);
223   stopwatch.Start();
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);
232
233   // Wait for zero time for writable and then it becomes never writable.
234   w.Init();
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);
240   stopwatch.Start();
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);
248
249   // Wait for non-zero, finite time for writable and then it becomes never
250   // writable.
251   w.Init();
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);
257   stopwatch.Start();
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);
266
267   EXPECT_EQ(MOJO_RESULT_OK, d->Close());
268 }
269
270 TEST(SimpleDispatcherTest, BasicClosed) {
271   test::Stopwatch stopwatch;
272
273   scoped_refptr<MockSimpleDispatcher> d;
274   Waiter w;
275   uint32_t context = 0;
276   HandleSignalsState hss;
277
278   // Try adding a writable waiter when the dispatcher has been closed.
279   d = new MockSimpleDispatcher();
280   w.Init();
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).
288
289   // Wait (forever) for writable and then the dispatcher is closed.
290   d = new MockSimpleDispatcher();
291   w.Init();
292   ASSERT_EQ(MOJO_RESULT_OK,
293             d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 2, nullptr));
294   EXPECT_EQ(MOJO_RESULT_OK, d->Close());
295   stopwatch.Start();
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.
300
301   // Wait for zero time for writable and then the dispatcher is closed.
302   d = new MockSimpleDispatcher();
303   w.Init();
304   ASSERT_EQ(MOJO_RESULT_OK,
305             d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 3, nullptr));
306   EXPECT_EQ(MOJO_RESULT_OK, d->Close());
307   stopwatch.Start();
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.
312
313   // Wait for non-zero, finite time for writable and then the dispatcher is
314   // closed.
315   d = new MockSimpleDispatcher();
316   w.Init();
317   ASSERT_EQ(MOJO_RESULT_OK,
318             d->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 4, nullptr));
319   EXPECT_EQ(MOJO_RESULT_OK, d->Close());
320   stopwatch.Start();
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.
326 }
327
328 #if defined(OS_WIN)
329 // http://crbug.com/396393
330 #define MAYBE_BasicThreaded DISABLED_BasicThreaded
331 #else
332 #define MAYBE_BasicThreaded BasicThreaded
333 #endif
334 TEST(SimpleDispatcherTest, MAYBE_BasicThreaded) {
335   test::Stopwatch stopwatch;
336   bool did_wait;
337   MojoResult result;
338   uint32_t context;
339   HandleSignalsState hss;
340
341   // Wait for readable (already readable).
342   {
343     scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
344     {
345       d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
346       test::WaiterThread thread(d,
347                                 MOJO_HANDLE_SIGNAL_READABLE,
348                                 MOJO_DEADLINE_INDEFINITE,
349                                 1,
350                                 &did_wait,
351                                 &result,
352                                 &context,
353                                 &hss);
354       stopwatch.Start();
355       thread.Start();
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());
359   }
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);
366
367   // Wait for readable and becomes readable after some time.
368   {
369     scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
370     {
371       test::WaiterThread thread(d,
372                                 MOJO_HANDLE_SIGNAL_READABLE,
373                                 MOJO_DEADLINE_INDEFINITE,
374                                 2,
375                                 &did_wait,
376                                 &result,
377                                 &context,
378                                 &hss);
379       stopwatch.Start();
380       thread.Start();
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());
385   }
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);
395
396   // Wait for readable and becomes never-readable after some time.
397   {
398     scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
399     {
400       test::WaiterThread thread(d,
401                                 MOJO_HANDLE_SIGNAL_READABLE,
402                                 MOJO_DEADLINE_INDEFINITE,
403                                 3,
404                                 &did_wait,
405                                 &result,
406                                 &context,
407                                 &hss);
408       stopwatch.Start();
409       thread.Start();
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());
414   }
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);
423
424   // Wait for readable and dispatcher gets closed.
425   {
426     scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
427     test::WaiterThread thread(d,
428                               MOJO_HANDLE_SIGNAL_READABLE,
429                               MOJO_DEADLINE_INDEFINITE,
430                               4,
431                               &did_wait,
432                               &result,
433                               &context,
434                               &hss);
435     stopwatch.Start();
436     thread.Start();
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);
448
449   // Wait for readable and times out.
450   {
451     scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
452     {
453       test::WaiterThread thread(d,
454                                 MOJO_HANDLE_SIGNAL_READABLE,
455                                 2 * test::EpsilonTimeout().InMicroseconds(),
456                                 5,
457                                 &did_wait,
458                                 &result,
459                                 &context,
460                                 &hss);
461       stopwatch.Start();
462       thread.Start();
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());
469   }
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);
478 }
479
480 #if defined(OS_WIN)
481 // http://crbug.com/387124
482 #define MAYBE_MultipleWaiters DISABLED_MultipleWaiters
483 #else
484 #define MAYBE_MultipleWaiters MultipleWaiters
485 #endif
486 TEST(SimpleDispatcherTest, MAYBE_MultipleWaiters) {
487   static const uint32_t kNumWaiters = 20;
488
489   bool did_wait[kNumWaiters];
490   MojoResult result[kNumWaiters];
491   uint32_t context[kNumWaiters];
492   HandleSignalsState hss[kNumWaiters];
493
494   // All wait for readable and becomes readable after some time.
495   {
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,
502                                                i,
503                                                &did_wait[i],
504                                                &result[i],
505                                                &context[i],
506                                                &hss[i]));
507       threads.back()->Start();
508     }
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
518     // saw as the state.
519   }
520
521   // Some wait for readable, some for writable, and becomes readable after some
522   // time.
523   {
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,
530                                                i,
531                                                &did_wait[i],
532                                                &result[i],
533                                                &context[i],
534                                                &hss[i]));
535       threads.back()->Start();
536     }
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,
541                                                i,
542                                                &did_wait[i],
543                                                &result[i],
544                                                &context[i],
545                                                &hss[i]));
546       threads.back()->Start();
547     }
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
558     // saw as the state.
559   }
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
565     // saw as the state.
566   }
567
568   // Some wait for readable, some for writable, and becomes readable and
569   // never-writable after some time.
570   {
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,
577                                                i,
578                                                &did_wait[i],
579                                                &result[i],
580                                                &context[i],
581                                                &hss[i]));
582       threads.back()->Start();
583     }
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,
588                                                i,
589                                                &did_wait[i],
590                                                &result[i],
591                                                &context[i],
592                                                &hss[i]));
593       threads.back()->Start();
594     }
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
606     // saw as the state.
607   }
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
613     // saw as the state.
614   }
615
616   // Some wait for readable, some for writable, and becomes readable after some
617   // time.
618   {
619     scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
620     ScopedVector<test::WaiterThread> threads;
621     for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
622       threads.push_back(
623           new test::WaiterThread(d,
624                                  MOJO_HANDLE_SIGNAL_READABLE,
625                                  3 * test::EpsilonTimeout().InMicroseconds(),
626                                  i,
627                                  &did_wait[i],
628                                  &result[i],
629                                  &context[i],
630                                  &hss[i]));
631       threads.back()->Start();
632     }
633     for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
634       threads.push_back(
635           new test::WaiterThread(d,
636                                  MOJO_HANDLE_SIGNAL_WRITABLE,
637                                  1 * test::EpsilonTimeout().InMicroseconds(),
638                                  i,
639                                  &did_wait[i],
640                                  &result[i],
641                                  &context[i],
642                                  &hss[i]));
643       threads.back()->Start();
644     }
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
655     // saw as the state.
656   }
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
661     // saw as the state.
662   }
663 }
664
665 // TODO(vtl): Stress test?
666
667 }  // namespace
668 }  // namespace system
669 }  // namespace mojo