Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: mojo/system/simple_dispatcher_unittest.cc

Issue 23621056: Initial in-process implementation of some Mojo primitives. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: build fix Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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. |kEpsilonMicros| may be increased to increase
7 // tolerance and reduce observed flakiness.
8
9 #include "mojo/system/simple_dispatcher.h"
10
11 #include "base/basictypes.h"
12 #include "base/logging.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_vector.h"
15 #include "base/synchronization/lock.h"
16 #include "base/threading/platform_thread.h" // For |Sleep()|.
17 #include "base/time/time.h"
18 #include "mojo/system/test_utils.h"
19 #include "mojo/system/waiter.h"
20 #include "mojo/system/waiter_test_utils.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 namespace mojo {
24 namespace system {
25 namespace {
26
27 const int64_t kMicrosPerMs = 1000;
28 const int64_t kEpsilonMicros = 15 * kMicrosPerMs; // 15 ms.
29
30 class MockSimpleDispatcher : public SimpleDispatcher {
31 public:
32 MockSimpleDispatcher()
33 : satisfied_flags_(MOJO_WAIT_FLAG_NONE),
34 satisfiable_flags_(MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE) {}
35
36 void SetSatisfiedFlags(MojoWaitFlags new_satisfied_flags) {
37 base::AutoLock locker(lock());
38
39 // Any new flags that are set should be satisfiable.
40 CHECK_EQ(new_satisfied_flags & ~satisfied_flags_,
41 new_satisfied_flags & ~satisfied_flags_ & satisfiable_flags_);
42
43 if (new_satisfied_flags == satisfied_flags_)
44 return;
45
46 satisfied_flags_ = new_satisfied_flags;
47 StateChangedNoLock();
48 }
49
50 void SetSatisfiableFlags(MojoWaitFlags new_satisfiable_flags) {
51 base::AutoLock locker(lock());
52
53 if (new_satisfiable_flags == satisfiable_flags_)
54 return;
55
56 satisfiable_flags_ = new_satisfiable_flags;
57 StateChangedNoLock();
58 }
59
60 private:
61 friend class base::RefCountedThreadSafe<MockSimpleDispatcher>;
62 virtual ~MockSimpleDispatcher() {}
63
64 // |SimpleDispatcher| implementation:
65 virtual MojoWaitFlags SatisfiedFlagsNoLock() const OVERRIDE {
66 lock().AssertAcquired();
67 return satisfied_flags_;
68 }
69
70 virtual MojoWaitFlags SatisfiableFlagsNoLock() const OVERRIDE {
71 lock().AssertAcquired();
72 return satisfiable_flags_;
73 }
74
75 // Protected by |lock()|:
76 MojoWaitFlags satisfied_flags_;
77 MojoWaitFlags satisfiable_flags_;
78
79 DISALLOW_COPY_AND_ASSIGN(MockSimpleDispatcher);
80 };
81
82 TEST(SimpleDispatcherTest, Basic) {
83 test::Stopwatch stopwatch;
84 int64_t elapsed_micros;
85
86 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
87 Waiter w;
88
89 // Try adding a readable waiter when already readable.
90 w.Init();
91 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
92 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
93 d->AddWaiter(&w, MOJO_WAIT_FLAG_READABLE, 0));
94 // Shouldn't need to remove the waiter (it was not added).
95
96 // Wait (forever) for writable when already writable.
97 w.Init();
98 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
99 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 1));
100 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_WRITABLE);
101 stopwatch.Start();
102 EXPECT_EQ(1, w.Wait(MOJO_DEADLINE_INDEFINITE));
103 elapsed_micros = stopwatch.Elapsed();
104 EXPECT_LT(elapsed_micros, kEpsilonMicros);
105 d->RemoveWaiter(&w);
106
107 // Wait for zero time for writable when already writable.
108 w.Init();
109 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
110 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 2));
111 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_WRITABLE);
112 stopwatch.Start();
113 EXPECT_EQ(2, w.Wait(0));
114 elapsed_micros = stopwatch.Elapsed();
115 EXPECT_LT(elapsed_micros, kEpsilonMicros);
116 d->RemoveWaiter(&w);
117
118 // Wait for non-zero, finite time for writable when already writable.
119 w.Init();
120 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
121 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 3));
122 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_WRITABLE);
123 stopwatch.Start();
124 EXPECT_EQ(3, w.Wait(2 * kEpsilonMicros));
125 elapsed_micros = stopwatch.Elapsed();
126 EXPECT_LT(elapsed_micros, kEpsilonMicros);
127 d->RemoveWaiter(&w);
128
129 // Wait for zero time for writable when not writable (will time out).
130 w.Init();
131 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
132 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 4));
133 stopwatch.Start();
134 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0));
135 elapsed_micros = stopwatch.Elapsed();
136 EXPECT_LT(elapsed_micros, kEpsilonMicros);
137 d->RemoveWaiter(&w);
138
139 // Wait for non-zero, finite time for writable when not writable (will time
140 // out).
141 w.Init();
142 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
143 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 4));
144 stopwatch.Start();
145 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(2 * kEpsilonMicros));
146 elapsed_micros = stopwatch.Elapsed();
147 EXPECT_GT(elapsed_micros, (2-1) * kEpsilonMicros);
148 EXPECT_LT(elapsed_micros, (2+1) * kEpsilonMicros);
149 d->RemoveWaiter(&w);
150
151 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
152 }
153
154 TEST(SimpleDispatcherTest, BasicUnsatisfiable) {
155 test::Stopwatch stopwatch;
156 int64_t elapsed_micros;
157
158 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
159 Waiter w;
160
161 // Try adding a writable waiter when it can never be writable.
162 w.Init();
163 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE);
164 d->SetSatisfiedFlags(0);
165 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
166 d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 5));
167 // Shouldn't need to remove the waiter (it was not added).
168
169 // Wait (forever) for writable and then it becomes never writable.
170 w.Init();
171 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE);
172 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 6));
173 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE);
174 stopwatch.Start();
175 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, w.Wait(MOJO_DEADLINE_INDEFINITE));
176 elapsed_micros = stopwatch.Elapsed();
177 EXPECT_LT(elapsed_micros, kEpsilonMicros);
178 d->RemoveWaiter(&w);
179
180 // Wait for zero time for writable and then it becomes never writable.
181 w.Init();
182 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE);
183 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 6));
184 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE);
185 stopwatch.Start();
186 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, w.Wait(0));
187 elapsed_micros = stopwatch.Elapsed();
188 EXPECT_LT(elapsed_micros, kEpsilonMicros);
189 d->RemoveWaiter(&w);
190
191 // Wait for non-zero, finite time for writable and then it becomes never
192 // writable.
193 w.Init();
194 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE);
195 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 7));
196 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE);
197 stopwatch.Start();
198 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, w.Wait(2 * kEpsilonMicros));
199 elapsed_micros = stopwatch.Elapsed();
200 EXPECT_LT(elapsed_micros, kEpsilonMicros);
201 d->RemoveWaiter(&w);
202
203 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
204 }
205
206 TEST(SimpleDispatcherTest, BasicClosed) {
207 test::Stopwatch stopwatch;
208 int64_t elapsed_micros;
209
210 scoped_refptr<MockSimpleDispatcher> d;
211 Waiter w;
212
213 // Try adding a writable waiter when the dispatcher has been closed.
214 d = new MockSimpleDispatcher();
215 w.Init();
216 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
217 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
218 d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 8));
219 // Shouldn't need to remove the waiter (it was not added).
220
221 // Wait (forever) for writable and then the dispatcher is closed.
222 d = new MockSimpleDispatcher();
223 w.Init();
224 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 9));
225 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
226 stopwatch.Start();
227 EXPECT_EQ(MOJO_RESULT_CANCELLED, w.Wait(MOJO_DEADLINE_INDEFINITE));
228 elapsed_micros = stopwatch.Elapsed();
229 EXPECT_LT(elapsed_micros, kEpsilonMicros);
230 // Don't need to remove waiters from closed dispatchers.
231
232 // Wait for zero time for writable and then the dispatcher is closed.
233 d = new MockSimpleDispatcher();
234 w.Init();
235 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 10));
236 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
237 stopwatch.Start();
238 EXPECT_EQ(MOJO_RESULT_CANCELLED, w.Wait(0));
239 elapsed_micros = stopwatch.Elapsed();
240 EXPECT_LT(elapsed_micros, kEpsilonMicros);
241 // Don't need to remove waiters from closed dispatchers.
242
243 // Wait for non-zero, finite time for writable and then the dispatcher is
244 // closed.
245 d = new MockSimpleDispatcher();
246 w.Init();
247 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 11));
248 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
249 stopwatch.Start();
250 EXPECT_EQ(MOJO_RESULT_CANCELLED, w.Wait(2 * kEpsilonMicros));
251 elapsed_micros = stopwatch.Elapsed();
252 EXPECT_LT(elapsed_micros, kEpsilonMicros);
253 // Don't need to remove waiters from closed dispatchers.
254 }
255
256 TEST(SimpleDispatcherTest, BasicThreaded) {
257 test::Stopwatch stopwatch;
258 bool did_wait;
259 MojoResult result;
260 int64_t elapsed_micros;
261
262 // Wait for readable (already readable).
263 {
264 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
265 {
266 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
267 test::WaiterThread thread(d,
268 MOJO_WAIT_FLAG_READABLE,
269 MOJO_DEADLINE_INDEFINITE,
270 0,
271 &did_wait, &result);
272 stopwatch.Start();
273 thread.Start();
274 } // Joins the thread.
275 // If we closed earlier, then probably we'd get a |MOJO_RESULT_CANCELLED|.
276 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
277 }
278 elapsed_micros = stopwatch.Elapsed();
279 EXPECT_FALSE(did_wait);
280 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, result);
281 EXPECT_LT(elapsed_micros, kEpsilonMicros);
282
283 // Wait for readable and becomes readable after some time.
284 {
285 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
286 test::WaiterThread thread(d,
287 MOJO_WAIT_FLAG_READABLE,
288 MOJO_DEADLINE_INDEFINITE,
289 1,
290 &did_wait, &result);
291 stopwatch.Start();
292 thread.Start();
293 base::PlatformThread::Sleep(
294 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
295 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
296 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
297 } // Joins the thread.
298 elapsed_micros = stopwatch.Elapsed();
299 EXPECT_TRUE(did_wait);
300 EXPECT_EQ(1, result);
301 EXPECT_GT(elapsed_micros, (2-1) * kEpsilonMicros);
302 EXPECT_LT(elapsed_micros, (2+1) * kEpsilonMicros);
303
304 // Wait for readable and becomes never-readable after some time.
305 {
306 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
307 test::WaiterThread thread(d,
308 MOJO_WAIT_FLAG_READABLE,
309 MOJO_DEADLINE_INDEFINITE,
310 2,
311 &did_wait, &result);
312 stopwatch.Start();
313 thread.Start();
314 base::PlatformThread::Sleep(
315 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
316 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_NONE);
317 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
318 } // Joins the thread.
319 elapsed_micros = stopwatch.Elapsed();
320 EXPECT_TRUE(did_wait);
321 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
322 EXPECT_GT(elapsed_micros, (2-1) * kEpsilonMicros);
323 EXPECT_LT(elapsed_micros, (2+1) * kEpsilonMicros);
324
325 // Wait for readable and dispatcher gets closed.
326 {
327 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
328 test::WaiterThread thread(d,
329 MOJO_WAIT_FLAG_READABLE,
330 MOJO_DEADLINE_INDEFINITE,
331 3,
332 &did_wait, &result);
333 stopwatch.Start();
334 thread.Start();
335 base::PlatformThread::Sleep(
336 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
337 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
338 } // Joins the thread.
339 elapsed_micros = stopwatch.Elapsed();
340 EXPECT_TRUE(did_wait);
341 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
342 EXPECT_GT(elapsed_micros, (2-1) * kEpsilonMicros);
343 EXPECT_LT(elapsed_micros, (2+1) * kEpsilonMicros);
344
345 // Wait for readable and times out.
346 {
347 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
348 {
349 test::WaiterThread thread(d,
350 MOJO_WAIT_FLAG_READABLE,
351 2 * kEpsilonMicros,
352 4,
353 &did_wait, &result);
354 stopwatch.Start();
355 thread.Start();
356 base::PlatformThread::Sleep(
357 base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros));
358 // Not what we're waiting for.
359 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_WRITABLE);
360 } // Joins the thread (after its wait times out).
361 // If we closed earlier, then probably we'd get a |MOJO_RESULT_CANCELLED|.
362 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
363 }
364 elapsed_micros = stopwatch.Elapsed();
365 EXPECT_TRUE(did_wait);
366 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result);
367 EXPECT_GT(elapsed_micros, (2-1) * kEpsilonMicros);
368 EXPECT_LT(elapsed_micros, (2+1) * kEpsilonMicros);
369 }
370
371 TEST(SimpleDispatcherTest, MultipleWaiters) {
372 static const size_t kNumWaiters = 20;
373
374 bool did_wait[kNumWaiters];
375 MojoResult result[kNumWaiters];
376
377 // All wait for readable and becomes readable after some time.
378 {
379 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
380 ScopedVector<test::WaiterThread> threads;
381 for (size_t i = 0; i < kNumWaiters; i++) {
382 threads.push_back(new test::WaiterThread(d,
383 MOJO_WAIT_FLAG_READABLE,
384 MOJO_DEADLINE_INDEFINITE,
385 static_cast<MojoResult>(i),
386 &did_wait[i], &result[i]));
387 threads.back()->Start();
388 }
389 base::PlatformThread::Sleep(
390 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
391 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
392 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
393 } // Joins the threads.
394 for (size_t i = 0; i < kNumWaiters; i++) {
395 EXPECT_TRUE(did_wait[i]);
396 EXPECT_EQ(static_cast<MojoResult>(i), result[i]);
397 }
398
399 // Some wait for readable, some for writable, and becomes readable after some
400 // time.
401 {
402 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
403 ScopedVector<test::WaiterThread> threads;
404 for (size_t i = 0; i < kNumWaiters / 2; i++) {
405 threads.push_back(new test::WaiterThread(d,
406 MOJO_WAIT_FLAG_READABLE,
407 MOJO_DEADLINE_INDEFINITE,
408 static_cast<MojoResult>(i),
409 &did_wait[i], &result[i]));
410 threads.back()->Start();
411 }
412 for (size_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
413 threads.push_back(new test::WaiterThread(d,
414 MOJO_WAIT_FLAG_WRITABLE,
415 MOJO_DEADLINE_INDEFINITE,
416 static_cast<MojoResult>(i),
417 &did_wait[i], &result[i]));
418 threads.back()->Start();
419 }
420 base::PlatformThread::Sleep(
421 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
422 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
423 // This will wake up the ones waiting to write.
424 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
425 } // Joins the threads.
426 for (size_t i = 0; i < kNumWaiters / 2; i++) {
427 EXPECT_TRUE(did_wait[i]);
428 EXPECT_EQ(static_cast<MojoResult>(i), result[i]);
429 }
430 for (size_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
431 EXPECT_TRUE(did_wait[i]);
432 EXPECT_EQ(MOJO_RESULT_CANCELLED, result[i]);
433 }
434
435 // Some wait for readable, some for writable, and becomes readable and
436 // never-writable after some time.
437 {
438 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
439 ScopedVector<test::WaiterThread> threads;
440 for (size_t i = 0; i < kNumWaiters / 2; i++) {
441 threads.push_back(new test::WaiterThread(d,
442 MOJO_WAIT_FLAG_READABLE,
443 MOJO_DEADLINE_INDEFINITE,
444 static_cast<MojoResult>(i),
445 &did_wait[i], &result[i]));
446 threads.back()->Start();
447 }
448 for (size_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
449 threads.push_back(new test::WaiterThread(d,
450 MOJO_WAIT_FLAG_WRITABLE,
451 MOJO_DEADLINE_INDEFINITE,
452 static_cast<MojoResult>(i),
453 &did_wait[i], &result[i]));
454 threads.back()->Start();
455 }
456 base::PlatformThread::Sleep(
457 base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros));
458 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE);
459 base::PlatformThread::Sleep(
460 base::TimeDelta::FromMicroseconds(1 * kEpsilonMicros));
461 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
462 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
463 } // Joins the threads.
464 for (size_t i = 0; i < kNumWaiters / 2; i++) {
465 EXPECT_TRUE(did_wait[i]);
466 EXPECT_EQ(static_cast<MojoResult>(i), result[i]);
467 }
468 for (size_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
469 EXPECT_TRUE(did_wait[i]);
470 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result[i]);
471 }
472
473 // Some wait for readable, some for writable, and becomes readable after some
474 // time.
475 {
476 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
477 ScopedVector<test::WaiterThread> threads;
478 for (size_t i = 0; i < kNumWaiters / 2; i++) {
479 threads.push_back(new test::WaiterThread(d,
480 MOJO_WAIT_FLAG_READABLE,
481 3 * kEpsilonMicros,
482 static_cast<MojoResult>(i),
483 &did_wait[i], &result[i]));
484 threads.back()->Start();
485 }
486 for (size_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
487 threads.push_back(new test::WaiterThread(d,
488 MOJO_WAIT_FLAG_WRITABLE,
489 1 * kEpsilonMicros,
490 static_cast<MojoResult>(i),
491 &did_wait[i], &result[i]));
492 threads.back()->Start();
493 }
494 base::PlatformThread::Sleep(
495 base::TimeDelta::FromMicroseconds(2 * kEpsilonMicros));
496 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
497 // All those waiting for writable should have timed out.
498 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
499 } // Joins the threads.
500 for (size_t i = 0; i < kNumWaiters / 2; i++) {
501 EXPECT_TRUE(did_wait[i]);
502 EXPECT_EQ(static_cast<MojoResult>(i), result[i]);
503 }
504 for (size_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
505 EXPECT_TRUE(did_wait[i]);
506 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result[i]);
507 }
508 }
509
510 // TODO(vtl): Stress test?
511
512 } // namespace
513 } // namespace system
514 } // namespace mojo
OLDNEW
« mojo/mojo.gyp ('K') | « mojo/system/simple_dispatcher.cc ('k') | mojo/system/test_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698