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

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

Issue 1649633002: Remove files that are no longer used in the Port EDK. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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/transport_data.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::EpsilonDeadline()| 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 <stdint.h>
13
14 #include "base/logging.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/memory/scoped_vector.h"
17 #include "base/synchronization/lock.h"
18 #include "mojo/edk/system/test_utils.h"
19 #include "mojo/edk/system/waiter.h"
20 #include "mojo/edk/system/waiter_test_utils.h"
21 #include "mojo/public/cpp/system/macros.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 namespace mojo {
25 namespace edk {
26 namespace {
27
28 class MockSimpleDispatcher final : 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 Type::UNKNOWN; }
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 MOJO_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 uintptr_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::EpsilonDeadline());
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::EpsilonDeadline());
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, w.Wait(2 * test::EpsilonDeadline(), &context));
153 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline());
154 EXPECT_EQ(3u, context);
155 hss = HandleSignalsState();
156 d->RemoveAwakable(&w, &hss);
157 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
158 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
159 hss.satisfiable_signals);
160
161 // Wait for zero time for writable when not writable (will time out).
162 w.Init();
163 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
164 ASSERT_EQ(MOJO_RESULT_OK,
165 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 4, nullptr));
166 stopwatch.Start();
167 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0, nullptr));
168 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline());
169 hss = HandleSignalsState();
170 d->RemoveAwakable(&w, &hss);
171 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
172 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
173 hss.satisfiable_signals);
174
175 // Wait for non-zero, finite time for writable when not writable (will time
176 // out).
177 w.Init();
178 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
179 ASSERT_EQ(MOJO_RESULT_OK,
180 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 5, nullptr));
181 stopwatch.Start();
182 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
183 w.Wait(2 * test::EpsilonDeadline(), nullptr));
184 MojoDeadline elapsed = stopwatch.Elapsed();
185 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonDeadline());
186 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonDeadline());
187 hss = HandleSignalsState();
188 d->RemoveAwakable(&w, &hss);
189 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
190 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
191 hss.satisfiable_signals);
192
193 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
194 }
195
196 TEST(SimpleDispatcherTest, BasicUnsatisfiable) {
197 test::Stopwatch stopwatch;
198
199 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
200 Waiter w;
201 uintptr_t context = 0;
202 HandleSignalsState hss;
203
204 // Try adding a writable waiter when it can never be writable.
205 w.Init();
206 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE);
207 d->SetSatisfiedSignals(0);
208 hss = HandleSignalsState();
209 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
210 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 1, &hss));
211 EXPECT_EQ(0u, hss.satisfied_signals);
212 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
213 // Shouldn't need to remove the waiter (it was not added).
214
215 // Wait (forever) for writable and then it becomes never writable.
216 w.Init();
217 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE |
218 MOJO_HANDLE_SIGNAL_WRITABLE);
219 ASSERT_EQ(MOJO_RESULT_OK,
220 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 2, nullptr));
221 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE);
222 stopwatch.Start();
223 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
224 w.Wait(MOJO_DEADLINE_INDEFINITE, &context));
225 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline());
226 EXPECT_EQ(2u, context);
227 hss = HandleSignalsState();
228 d->RemoveAwakable(&w, &hss);
229 EXPECT_EQ(0u, hss.satisfied_signals);
230 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
231
232 // Wait for zero time for writable and then it becomes never writable.
233 w.Init();
234 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE |
235 MOJO_HANDLE_SIGNAL_WRITABLE);
236 ASSERT_EQ(MOJO_RESULT_OK,
237 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 3, nullptr));
238 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE);
239 stopwatch.Start();
240 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, w.Wait(0, &context));
241 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline());
242 EXPECT_EQ(3u, context);
243 hss = HandleSignalsState();
244 d->RemoveAwakable(&w, &hss);
245 EXPECT_EQ(0u, hss.satisfied_signals);
246 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
247
248 // Wait for non-zero, finite time for writable and then it becomes never
249 // writable.
250 w.Init();
251 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE |
252 MOJO_HANDLE_SIGNAL_WRITABLE);
253 ASSERT_EQ(MOJO_RESULT_OK,
254 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 4, nullptr));
255 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE);
256 stopwatch.Start();
257 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
258 w.Wait(2 * test::EpsilonDeadline(), &context));
259 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline());
260 EXPECT_EQ(4u, context);
261 hss = HandleSignalsState();
262 d->RemoveAwakable(&w, &hss);
263 EXPECT_EQ(0u, hss.satisfied_signals);
264 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
265
266 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
267 }
268
269 TEST(SimpleDispatcherTest, BasicClosed) {
270 test::Stopwatch stopwatch;
271
272 scoped_refptr<MockSimpleDispatcher> d;
273 Waiter w;
274 uintptr_t context = 0;
275 HandleSignalsState hss;
276
277 // Try adding a writable waiter when the dispatcher has been closed.
278 d = new MockSimpleDispatcher();
279 w.Init();
280 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
281 hss = HandleSignalsState();
282 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
283 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 1, &hss));
284 EXPECT_EQ(0u, hss.satisfied_signals);
285 EXPECT_EQ(0u, hss.satisfiable_signals);
286 // Shouldn't need to remove the waiter (it was not added).
287
288 // Wait (forever) for writable and then the dispatcher is closed.
289 d = new MockSimpleDispatcher();
290 w.Init();
291 ASSERT_EQ(MOJO_RESULT_OK,
292 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 2, nullptr));
293 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
294 stopwatch.Start();
295 EXPECT_EQ(MOJO_RESULT_CANCELLED, w.Wait(MOJO_DEADLINE_INDEFINITE, &context));
296 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline());
297 EXPECT_EQ(2u, context);
298 // Don't need to remove waiters from closed dispatchers.
299
300 // Wait for zero time for writable and then the dispatcher is closed.
301 d = new MockSimpleDispatcher();
302 w.Init();
303 ASSERT_EQ(MOJO_RESULT_OK,
304 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 3, nullptr));
305 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
306 stopwatch.Start();
307 EXPECT_EQ(MOJO_RESULT_CANCELLED, w.Wait(0, &context));
308 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline());
309 EXPECT_EQ(3u, context);
310 // Don't need to remove waiters from closed dispatchers.
311
312 // Wait for non-zero, finite time for writable and then the dispatcher is
313 // closed.
314 d = new MockSimpleDispatcher();
315 w.Init();
316 ASSERT_EQ(MOJO_RESULT_OK,
317 d->AddAwakable(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 4, nullptr));
318 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
319 stopwatch.Start();
320 EXPECT_EQ(MOJO_RESULT_CANCELLED,
321 w.Wait(2 * test::EpsilonDeadline(), &context));
322 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline());
323 EXPECT_EQ(4u, context);
324 // Don't need to remove waiters from closed dispatchers.
325 }
326
327 #if defined(OS_WIN)
328 // http://crbug.com/396393
329 #define MAYBE_BasicThreaded DISABLED_BasicThreaded
330 #else
331 #define MAYBE_BasicThreaded BasicThreaded
332 #endif
333 TEST(SimpleDispatcherTest, MAYBE_BasicThreaded) {
334 test::Stopwatch stopwatch;
335 bool did_wait;
336 MojoResult result;
337 uintptr_t context;
338 HandleSignalsState hss;
339
340 // Wait for readable (already readable).
341 {
342 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
343 {
344 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
345 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE,
346 MOJO_DEADLINE_INDEFINITE, 1, &did_wait, &result,
347 &context, &hss);
348 stopwatch.Start();
349 thread.Start();
350 } // Joins the thread.
351 // If we closed earlier, then probably we'd get a |MOJO_RESULT_CANCELLED|.
352 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
353 }
354 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonDeadline());
355 EXPECT_FALSE(did_wait);
356 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, result);
357 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
358 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
359 hss.satisfiable_signals);
360
361 // Wait for readable and becomes readable after some time.
362 {
363 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
364 {
365 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE,
366 MOJO_DEADLINE_INDEFINITE, 2, &did_wait, &result,
367 &context, &hss);
368 stopwatch.Start();
369 thread.Start();
370 test::Sleep(2 * test::EpsilonDeadline());
371 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
372 } // Joins the thread.
373 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
374 }
375 MojoDeadline elapsed = stopwatch.Elapsed();
376 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonDeadline());
377 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonDeadline());
378 EXPECT_TRUE(did_wait);
379 EXPECT_EQ(MOJO_RESULT_OK, result);
380 EXPECT_EQ(2u, context);
381 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
382 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
383 hss.satisfiable_signals);
384
385 // Wait for readable and becomes never-readable after some time.
386 {
387 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
388 {
389 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE,
390 MOJO_DEADLINE_INDEFINITE, 3, &did_wait, &result,
391 &context, &hss);
392 stopwatch.Start();
393 thread.Start();
394 test::Sleep(2 * test::EpsilonDeadline());
395 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_NONE);
396 } // Joins the thread.
397 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
398 }
399 elapsed = stopwatch.Elapsed();
400 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonDeadline());
401 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonDeadline());
402 EXPECT_TRUE(did_wait);
403 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
404 EXPECT_EQ(3u, context);
405 EXPECT_EQ(0u, hss.satisfied_signals);
406 EXPECT_EQ(0u, hss.satisfiable_signals);
407
408 // Wait for readable and dispatcher gets closed.
409 {
410 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
411 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE,
412 MOJO_DEADLINE_INDEFINITE, 4, &did_wait, &result,
413 &context, &hss);
414 stopwatch.Start();
415 thread.Start();
416 test::Sleep(2 * test::EpsilonDeadline());
417 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
418 } // Joins the thread.
419 elapsed = stopwatch.Elapsed();
420 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonDeadline());
421 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonDeadline());
422 EXPECT_TRUE(did_wait);
423 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
424 EXPECT_EQ(4u, context);
425 EXPECT_EQ(0u, hss.satisfied_signals);
426 EXPECT_EQ(0u, hss.satisfiable_signals);
427
428 // Wait for readable and times out.
429 {
430 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
431 {
432 test::WaiterThread thread(d, MOJO_HANDLE_SIGNAL_READABLE,
433 2 * test::EpsilonDeadline(), 5, &did_wait,
434 &result, &context, &hss);
435 stopwatch.Start();
436 thread.Start();
437 test::Sleep(1 * test::EpsilonDeadline());
438 // Not what we're waiting for.
439 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_WRITABLE);
440 } // Joins the thread (after its wait times out).
441 // If we closed earlier, then probably we'd get a |MOJO_RESULT_CANCELLED|.
442 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
443 }
444 elapsed = stopwatch.Elapsed();
445 EXPECT_GT(elapsed, (2 - 1) * test::EpsilonDeadline());
446 EXPECT_LT(elapsed, (2 + 1) * test::EpsilonDeadline());
447 EXPECT_TRUE(did_wait);
448 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result);
449 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
450 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
451 hss.satisfiable_signals);
452 }
453
454 #if defined(OS_WIN)
455 // http://crbug.com/387124
456 #define MAYBE_MultipleWaiters DISABLED_MultipleWaiters
457 #else
458 #define MAYBE_MultipleWaiters MultipleWaiters
459 #endif
460 TEST(SimpleDispatcherTest, MAYBE_MultipleWaiters) {
461 static const uint32_t kNumWaiters = 20;
462
463 bool did_wait[kNumWaiters];
464 MojoResult result[kNumWaiters];
465 uintptr_t context[kNumWaiters];
466 HandleSignalsState hss[kNumWaiters];
467
468 // All wait for readable and becomes readable after some time.
469 {
470 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
471 ScopedVector<test::WaiterThread> threads;
472 for (uint32_t i = 0; i < kNumWaiters; i++) {
473 threads.push_back(new test::WaiterThread(
474 d, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, i,
475 &did_wait[i], &result[i], &context[i], &hss[i]));
476 threads.back()->Start();
477 }
478 test::Sleep(2 * test::EpsilonDeadline());
479 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
480 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
481 } // Joins the threads.
482 for (uint32_t i = 0; i < kNumWaiters; i++) {
483 EXPECT_TRUE(did_wait[i]) << i;
484 EXPECT_EQ(MOJO_RESULT_OK, result[i]) << i;
485 EXPECT_EQ(i, context[i]) << i;
486 // Since we closed before joining, we can't say much about what each thread
487 // saw as the state.
488 }
489
490 // Some wait for readable, some for writable, and becomes readable after some
491 // time.
492 {
493 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
494 ScopedVector<test::WaiterThread> threads;
495 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
496 threads.push_back(new test::WaiterThread(
497 d, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, i,
498 &did_wait[i], &result[i], &context[i], &hss[i]));
499 threads.back()->Start();
500 }
501 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
502 threads.push_back(new test::WaiterThread(
503 d, MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE, i,
504 &did_wait[i], &result[i], &context[i], &hss[i]));
505 threads.back()->Start();
506 }
507 test::Sleep(2 * test::EpsilonDeadline());
508 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
509 // This will wake up the ones waiting to write.
510 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
511 } // Joins the threads.
512 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
513 EXPECT_TRUE(did_wait[i]) << i;
514 EXPECT_EQ(MOJO_RESULT_OK, result[i]) << i;
515 EXPECT_EQ(i, context[i]) << i;
516 // Since we closed before joining, we can't say much about what each thread
517 // saw as the state.
518 }
519 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
520 EXPECT_TRUE(did_wait[i]) << i;
521 EXPECT_EQ(MOJO_RESULT_CANCELLED, result[i]) << i;
522 EXPECT_EQ(i, context[i]) << i;
523 // Since we closed before joining, we can't say much about what each thread
524 // saw as the state.
525 }
526
527 // Some wait for readable, some for writable, and becomes readable and
528 // never-writable after some time.
529 {
530 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
531 ScopedVector<test::WaiterThread> threads;
532 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
533 threads.push_back(new test::WaiterThread(
534 d, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, i,
535 &did_wait[i], &result[i], &context[i], &hss[i]));
536 threads.back()->Start();
537 }
538 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
539 threads.push_back(new test::WaiterThread(
540 d, MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_DEADLINE_INDEFINITE, i,
541 &did_wait[i], &result[i], &context[i], &hss[i]));
542 threads.back()->Start();
543 }
544 test::Sleep(1 * test::EpsilonDeadline());
545 d->SetSatisfiableSignals(MOJO_HANDLE_SIGNAL_READABLE);
546 test::Sleep(1 * test::EpsilonDeadline());
547 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
548 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
549 } // Joins the threads.
550 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
551 EXPECT_TRUE(did_wait[i]) << i;
552 EXPECT_EQ(MOJO_RESULT_OK, result[i]) << i;
553 EXPECT_EQ(i, context[i]) << i;
554 // Since we closed before joining, we can't say much about what each thread
555 // saw as the state.
556 }
557 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
558 EXPECT_TRUE(did_wait[i]) << i;
559 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result[i]) << i;
560 EXPECT_EQ(i, context[i]) << i;
561 // Since we closed before joining, we can't say much about what each thread
562 // saw as the state.
563 }
564
565 // Some wait for readable, some for writable, and becomes readable after some
566 // time.
567 {
568 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
569 ScopedVector<test::WaiterThread> threads;
570 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
571 threads.push_back(new test::WaiterThread(
572 d, MOJO_HANDLE_SIGNAL_READABLE, 3 * test::EpsilonDeadline(), i,
573 &did_wait[i], &result[i], &context[i], &hss[i]));
574 threads.back()->Start();
575 }
576 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
577 threads.push_back(new test::WaiterThread(
578 d, MOJO_HANDLE_SIGNAL_WRITABLE, 1 * test::EpsilonDeadline(), i,
579 &did_wait[i], &result[i], &context[i], &hss[i]));
580 threads.back()->Start();
581 }
582 test::Sleep(2 * test::EpsilonDeadline());
583 d->SetSatisfiedSignals(MOJO_HANDLE_SIGNAL_READABLE);
584 // All those waiting for writable should have timed out.
585 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
586 } // Joins the threads.
587 for (uint32_t i = 0; i < kNumWaiters / 2; i++) {
588 EXPECT_TRUE(did_wait[i]) << i;
589 EXPECT_EQ(MOJO_RESULT_OK, result[i]) << i;
590 EXPECT_EQ(i, context[i]) << i;
591 // Since we closed before joining, we can't say much about what each thread
592 // saw as the state.
593 }
594 for (uint32_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
595 EXPECT_TRUE(did_wait[i]) << i;
596 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result[i]) << i;
597 // Since we closed before joining, we can't say much about what each thread
598 // saw as the state.
599 }
600 }
601
602 // TODO(vtl): Stress test?
603
604 } // namespace
605 } // namespace edk
606 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/simple_dispatcher.cc ('k') | mojo/edk/system/transport_data.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698