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

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

Issue 814543006: Move //mojo/{public, edk} underneath //third_party (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 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 Type GetType() const override { return kTypeUnknown; }
64
65 private:
66 friend class base::RefCountedThreadSafe<MockSimpleDispatcher>;
67 ~MockSimpleDispatcher() override {}
68
69 scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndCloseImplNoLock()
70 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 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->AddAwakable(&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->AddAwakable(&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->RemoveAwakable(&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->AddAwakable(&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->RemoveAwakable(&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->AddAwakable(&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->RemoveAwakable(&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->AddAwakable(&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->RemoveAwakable(&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->AddAwakable(&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->RemoveAwakable(&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->AddAwakable(&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->AddAwakable(&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->RemoveAwakable(&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->AddAwakable(&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->RemoveAwakable(&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->AddAwakable(&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->RemoveAwakable(&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->AddAwakable(&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->AddAwakable(&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->AddAwakable(&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->AddAwakable(&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, MOJO_HANDLE_SIGNAL_READABLE,
347 MOJO_DEADLINE_INDEFINITE, 1, &did_wait, &result,
348 &context, &hss);
349 stopwatch.Start();
350 thread.Start();
351 } // Joins the thread.
352 // If we closed earlier, then probably we'd get a |MOJO_RESULT_CANCELLED|.
353 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
354 }
355 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
356 EXPECT_FALSE(did_wait);
357 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, result);
358 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
359 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
360 hss.satisfiable_signals);
361
362 // Wait for readable and becomes readable after some time.
363 {
364 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
365 {
366 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE,
367 MOJO_DEADLINE_INDEFINITE, 2, &did_wait, &result,
368 &context, &hss);
369 stopwatch.Start();
370 thread.Start();
371 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
372 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
373 } // Joins the thread.
374 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
375 }
376 base::TimeDelta elapsed = stopwatch.Elapsed();
377 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonTimeout());
378 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonTimeout());
379 EXPECT_TRUE(did_wait);
380 EXPECT_EQ(MOJO_RESULT_OK, result);
381 EXPECT_EQ(2u, context);
382 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
383 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
384 hss.satisfiable_signals);
385
386 // Wait for readable and becomes never-readable after some time.
387 {
388 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
389 {
390 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE,
391 MOJO_DEADLINE_INDEFINITE, 3, &did_wait, &result,
392 &context, &hss);
393 stopwatch.Start();
394 thread.Start();
395 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
396 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_NONE);
397 } // Joins the thread.
398 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
399 }
400 elapsed = stopwatch.Elapsed();
401 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonTimeout());
402 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonTimeout());
403 EXPECT_TRUE(did_wait);
404 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
405 EXPECT_EQ(3u, context);
406 EXPECT_EQ(0u, hss.satisfied_signals);
407 EXPECT_EQ(0u, hss.satisfiable_signals);
408
409 // Wait for readable and dispatcher gets closed.
410 {
411 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
412 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE,
413 MOJO_DEADLINE_INDEFINITE, 4, &did_wait, &result,
414 &context, &hss);
415 stopwatch.Start();
416 thread.Start();
417 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
418 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
419 } // Joins the thread.
420 elapsed = stopwatch.Elapsed();
421 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonTimeout());
422 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonTimeout());
423 EXPECT_TRUE(did_wait);
424 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
425 EXPECT_EQ(4u, context);
426 EXPECT_EQ(0u, hss.satisfied_signals);
427 EXPECT_EQ(0u, hss.satisfiable_signals);
428
429 // Wait for readable and times out.
430 {
431 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
432 {
433 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE,
434 2 * test::EpsilonTimeout().InMicroseconds(), 5,
435 &did_wait, &result, &context, &hss);
436 stopwatch.Start();
437 thread.Start();
438 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
439 // Not what we're waiting for.
440 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_WRITABLE);
441 } // Joins the thread (after its wait times out).
442 // If we closed earlier, then probably we'd get a |MOJO_RESULT_CANCELLED|.
443 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
444 }
445 elapsed = stopwatch.Elapsed();
446 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonTimeout());
447 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonTimeout());
448 EXPECT_TRUE(did_wait);
449 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result);
450 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
451 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
452 hss.satisfiable_signals);
453 }
454
455 #if defined(OS_WIN)
456 // http://crbug.com/387124
457 #define MAYBE_MultipleWaiters DISABLED_MultipleWaiters
458 #else
459 #define MAYBE_MultipleWaiters MultipleWaiters
460 #endif
461 TEST(SimpleDispatcherTest, MAYBE_MultipleWaiters) {
462 static const uint32_t kNumWaiters = 20;
463
464 bool did_wait[kNumWaiters];
465 MojoResult result[kNumWaiters];
466 uint32_t context[kNumWaiters];
467 HandleSignalsState hss[kNumWaiters];
468
469 // All wait for readable and becomes readable after some time.
470 {
471 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
472 ScopedVector<test::WaiterThread> threads;
473 for (uint32_t i = 0; i < kNumWaiters; i++) {
474 threads.push_back(new test::WaiterThread(
475 d, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, i,
476 &did_wait[i], &result[i], &context[i], &hss[i]));
477 threads.back()->Start();
478 }
479 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
480 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
481 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
482 } // Joins the threads.
483 for (uint32_t i = 0; i < kNumWaiters; i++) {
484 EXPECT_TRUE(did_wait[i]) << i;
485 EXPECT_EQ(MOJO_RESULT_OK, result[i]) << i;
486 EXPECT_EQ(i, context[i]) << i;
487 // Since we closed before joining, we can't say much about what each thread
488 // saw as the state.
489 }
490
491 // Some wait for readable, some for writable, and becomes readable after some
492 // time.
493 {
494 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
495 ScopedVector<test::WaiterThread> threads;
496 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
497 threads.push_back(new test::WaiterThread(
498 d, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, i,
499 &did_wait[i], &result[i], &context[i], &hss[i]));
500 threads.back()->Start();
501 }
502 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
503 threads.push_back(new test::WaiterThread(
504 d, MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE, i,
505 &did_wait[i], &result[i], &context[i], &hss[i]));
506 threads.back()->Start();
507 }
508 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
509 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
510 // This will wake up the ones waiting to write.
511 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
512 } // Joins the threads.
513 for (uint32_t i = 0; i < kNumWaiters / 2; 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 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
521 EXPECT_TRUE(did_wait[i]) << i;
522 EXPECT_EQ(MOJO_RESULT_CANCELLED, result[i]) << i;
523 EXPECT_EQ(i, context[i]) << i;
524 // Since we closed before joining, we can't say much about what each thread
525 // saw as the state.
526 }
527
528 // Some wait for readable, some for writable, and becomes readable and
529 // never-writable after some time.
530 {
531 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
532 ScopedVector<test::WaiterThread> threads;
533 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
534 threads.push_back(new test::WaiterThread(
535 d, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, i,
536 &did_wait[i], &result[i], &context[i], &hss[i]));
537 threads.back()->Start();
538 }
539 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
540 threads.push_back(new test::WaiterThread(
541 d, MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE, i,
542 &did_wait[i], &result[i], &context[i], &hss[i]));
543 threads.back()->Start();
544 }
545 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
546 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE);
547 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
548 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
549 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
550 } // Joins the threads.
551 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
552 EXPECT_TRUE(did_wait[i]) << i;
553 EXPECT_EQ(MOJO_RESULT_OK, result[i]) << i;
554 EXPECT_EQ(i, context[i]) << i;
555 // Since we closed before joining, we can't say much about what each thread
556 // saw as the state.
557 }
558 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
559 EXPECT_TRUE(did_wait[i]) << i;
560 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result[i]) << i;
561 EXPECT_EQ(i, context[i]) << i;
562 // Since we closed before joining, we can't say much about what each thread
563 // saw as the state.
564 }
565
566 // Some wait for readable, some for writable, and becomes readable after some
567 // time.
568 {
569 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
570 ScopedVector<test::WaiterThread> threads;
571 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
572 threads.push_back(new test::WaiterThread(
573 d, MOJO_HANDLE_SIGNAL_READABLE,
574 3 * test::EpsilonTimeout().InMicroseconds(), i, &did_wait[i],
575 &result[i], &context[i], &hss[i]));
576 threads.back()->Start();
577 }
578 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
579 threads.push_back(new test::WaiterThread(
580 d, MOJO_HANDLE_SIGNAL_WRITABLE,
581 1 * test::EpsilonTimeout().InMicroseconds(), i, &did_wait[i],
582 &result[i], &context[i], &hss[i]));
583 threads.back()->Start();
584 }
585 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
586 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
587 // All those waiting for writable should have timed out.
588 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
589 } // Joins the threads.
590 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
591 EXPECT_TRUE(did_wait[i]) << i;
592 EXPECT_EQ(MOJO_RESULT_OK, result[i]) << i;
593 EXPECT_EQ(i, context[i]) << i;
594 // Since we closed before joining, we can't say much about what each thread
595 // saw as the state.
596 }
597 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
598 EXPECT_TRUE(did_wait[i]) << i;
599 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result[i]) << i;
600 // Since we closed before joining, we can't say much about what each thread
601 // saw as the state.
602 }
603 }
604
605 // TODO(vtl): Stress test?
606
607 } // namespace
608 } // namespace system
609 } // 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