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

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

Issue 623883002: Revert "Move mojo edk into mojo/edk" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 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
« no previous file with comments | « mojo/edk/system/simple_dispatcher.cc ('k') | mojo/edk/system/system_impl_export.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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. |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/edk/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/edk/system/test_utils.h"
20 #include "mojo/edk/system/waiter.h"
21 #include "mojo/edk/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
OLDNEW
« no previous file with comments | « mojo/edk/system/simple_dispatcher.cc ('k') | mojo/edk/system/system_impl_export.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698