Add an extension override bubble and warning box for proxy extensions. (2nd attempt...
[chromium-blink-merge.git] / mojo / system / simple_dispatcher_unittest.cc
blob6f232693ab658e1662d121caf4e2b5e44100f14e
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.
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).
10 #include "mojo/system/simple_dispatcher.h"
12 #include "base/basictypes.h"
13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_vector.h"
16 #include "base/synchronization/lock.h"
17 #include "base/threading/platform_thread.h" // For |Sleep()|.
18 #include "base/time/time.h"
19 #include "mojo/system/test_utils.h"
20 #include "mojo/system/waiter.h"
21 #include "mojo/system/waiter_test_utils.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 namespace mojo {
25 namespace system {
26 namespace {
28 class MockSimpleDispatcher : public SimpleDispatcher {
29 public:
30 MockSimpleDispatcher()
31 : satisfied_flags_(MOJO_WAIT_FLAG_NONE),
32 satisfiable_flags_(MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE) {}
34 void SetSatisfiedFlags(MojoWaitFlags new_satisfied_flags) {
35 base::AutoLock locker(lock());
37 // Any new flags that are set should be satisfiable.
38 CHECK_EQ(new_satisfied_flags & ~satisfied_flags_,
39 new_satisfied_flags & ~satisfied_flags_ & satisfiable_flags_);
41 if (new_satisfied_flags == satisfied_flags_)
42 return;
44 satisfied_flags_ = new_satisfied_flags;
45 StateChangedNoLock();
48 void SetSatisfiableFlags(MojoWaitFlags new_satisfiable_flags) {
49 base::AutoLock locker(lock());
51 if (new_satisfiable_flags == satisfiable_flags_)
52 return;
54 satisfiable_flags_ = new_satisfiable_flags;
55 StateChangedNoLock();
58 virtual Type GetType() const OVERRIDE {
59 return kTypeUnknown;
62 private:
63 friend class base::RefCountedThreadSafe<MockSimpleDispatcher>;
64 virtual ~MockSimpleDispatcher() {}
66 virtual scoped_refptr<Dispatcher>
67 CreateEquivalentDispatcherAndCloseImplNoLock() OVERRIDE {
68 scoped_refptr<MockSimpleDispatcher> rv(new MockSimpleDispatcher());
69 rv->satisfied_flags_ = satisfied_flags_;
70 rv->satisfiable_flags_ = satisfiable_flags_;
71 return scoped_refptr<Dispatcher>(rv.get());
74 // |SimpleDispatcher| implementation:
75 virtual MojoWaitFlags SatisfiedFlagsNoLock() const OVERRIDE {
76 lock().AssertAcquired();
77 return satisfied_flags_;
80 virtual MojoWaitFlags SatisfiableFlagsNoLock() const OVERRIDE {
81 lock().AssertAcquired();
82 return satisfiable_flags_;
85 // Protected by |lock()|:
86 MojoWaitFlags satisfied_flags_;
87 MojoWaitFlags satisfiable_flags_;
89 DISALLOW_COPY_AND_ASSIGN(MockSimpleDispatcher);
92 TEST(SimpleDispatcherTest, Basic) {
93 test::Stopwatch stopwatch;
95 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
96 Waiter w;
98 // Try adding a readable waiter when already readable.
99 w.Init();
100 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
101 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
102 d->AddWaiter(&w, MOJO_WAIT_FLAG_READABLE, 0));
103 // Shouldn't need to remove the waiter (it was not added).
105 // Wait (forever) for writable when already writable.
106 w.Init();
107 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
108 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 1));
109 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_WRITABLE);
110 stopwatch.Start();
111 EXPECT_EQ(1, w.Wait(MOJO_DEADLINE_INDEFINITE));
112 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
113 d->RemoveWaiter(&w);
115 // Wait for zero time for writable when already writable.
116 w.Init();
117 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
118 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 2));
119 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_WRITABLE);
120 stopwatch.Start();
121 EXPECT_EQ(2, w.Wait(0));
122 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
123 d->RemoveWaiter(&w);
125 // Wait for non-zero, finite time for writable when already writable.
126 w.Init();
127 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
128 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 3));
129 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_WRITABLE);
130 stopwatch.Start();
131 EXPECT_EQ(3, w.Wait(2 * test::EpsilonTimeout().InMicroseconds()));
132 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
133 d->RemoveWaiter(&w);
135 // Wait for zero time for writable when not writable (will time out).
136 w.Init();
137 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
138 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 4));
139 stopwatch.Start();
140 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0));
141 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
142 d->RemoveWaiter(&w);
144 // Wait for non-zero, finite time for writable when not writable (will time
145 // out).
146 w.Init();
147 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
148 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 4));
149 stopwatch.Start();
150 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED,
151 w.Wait(2 * test::EpsilonTimeout().InMicroseconds()));
152 base::TimeDelta elapsed = stopwatch.Elapsed();
153 EXPECT_GT(elapsed, (2-1) * test::EpsilonTimeout());
154 EXPECT_LT(elapsed, (2+1) * test::EpsilonTimeout());
155 d->RemoveWaiter(&w);
157 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
160 TEST(SimpleDispatcherTest, BasicUnsatisfiable) {
161 test::Stopwatch stopwatch;
163 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
164 Waiter w;
166 // Try adding a writable waiter when it can never be writable.
167 w.Init();
168 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE);
169 d->SetSatisfiedFlags(0);
170 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
171 d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 5));
172 // Shouldn't need to remove the waiter (it was not added).
174 // Wait (forever) for writable and then it becomes never writable.
175 w.Init();
176 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE);
177 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 6));
178 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE);
179 stopwatch.Start();
180 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, w.Wait(MOJO_DEADLINE_INDEFINITE));
181 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
182 d->RemoveWaiter(&w);
184 // Wait for zero time for writable and then it becomes never writable.
185 w.Init();
186 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE);
187 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 6));
188 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE);
189 stopwatch.Start();
190 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, w.Wait(0));
191 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
192 d->RemoveWaiter(&w);
194 // Wait for non-zero, finite time for writable and then it becomes never
195 // writable.
196 w.Init();
197 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE | MOJO_WAIT_FLAG_WRITABLE);
198 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 7));
199 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE);
200 stopwatch.Start();
201 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
202 w.Wait(2 * test::EpsilonTimeout().InMicroseconds()));
203 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
204 d->RemoveWaiter(&w);
206 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
209 TEST(SimpleDispatcherTest, BasicClosed) {
210 test::Stopwatch stopwatch;
212 scoped_refptr<MockSimpleDispatcher> d;
213 Waiter w;
215 // Try adding a writable waiter when the dispatcher has been closed.
216 d = new MockSimpleDispatcher();
217 w.Init();
218 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
219 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
220 d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 8));
221 // Shouldn't need to remove the waiter (it was not added).
223 // Wait (forever) for writable and then the dispatcher is closed.
224 d = new MockSimpleDispatcher();
225 w.Init();
226 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 9));
227 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
228 stopwatch.Start();
229 EXPECT_EQ(MOJO_RESULT_CANCELLED, w.Wait(MOJO_DEADLINE_INDEFINITE));
230 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
231 // Don't need to remove waiters from closed dispatchers.
233 // Wait for zero time for writable and then the dispatcher is closed.
234 d = new MockSimpleDispatcher();
235 w.Init();
236 EXPECT_EQ(MOJO_RESULT_OK, d->AddWaiter(&w, MOJO_WAIT_FLAG_WRITABLE, 10));
237 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
238 stopwatch.Start();
239 EXPECT_EQ(MOJO_RESULT_CANCELLED, w.Wait(0));
240 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
241 // Don't need to remove waiters from closed dispatchers.
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,
251 w.Wait(2 * test::EpsilonTimeout().InMicroseconds()));
252 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
253 // Don't need to remove waiters from closed dispatchers.
256 TEST(SimpleDispatcherTest, BasicThreaded) {
257 test::Stopwatch stopwatch;
258 bool did_wait;
259 MojoResult result;
261 // Wait for readable (already readable).
263 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
265 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
266 test::WaiterThread thread(d,
267 MOJO_WAIT_FLAG_READABLE,
268 MOJO_DEADLINE_INDEFINITE,
270 &did_wait, &result);
271 stopwatch.Start();
272 thread.Start();
273 } // Joins the thread.
274 // If we closed earlier, then probably we'd get a |MOJO_RESULT_CANCELLED|.
275 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
277 EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout());
278 EXPECT_FALSE(did_wait);
279 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, result);
281 // Wait for readable and becomes readable after some time.
283 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
284 test::WaiterThread thread(d,
285 MOJO_WAIT_FLAG_READABLE,
286 MOJO_DEADLINE_INDEFINITE,
288 &did_wait, &result);
289 stopwatch.Start();
290 thread.Start();
291 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
292 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
293 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
294 } // Joins the thread.
295 base::TimeDelta elapsed = stopwatch.Elapsed();
296 EXPECT_GT(elapsed, (2-1) * test::EpsilonTimeout());
297 EXPECT_LT(elapsed, (2+1) * test::EpsilonTimeout());
298 EXPECT_TRUE(did_wait);
299 EXPECT_EQ(1, result);
301 // Wait for readable and becomes never-readable after some time.
303 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
304 test::WaiterThread thread(d,
305 MOJO_WAIT_FLAG_READABLE,
306 MOJO_DEADLINE_INDEFINITE,
308 &did_wait, &result);
309 stopwatch.Start();
310 thread.Start();
311 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
312 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_NONE);
313 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
314 } // Joins the thread.
315 elapsed = stopwatch.Elapsed();
316 EXPECT_GT(elapsed, (2-1) * test::EpsilonTimeout());
317 EXPECT_LT(elapsed, (2+1) * test::EpsilonTimeout());
318 EXPECT_TRUE(did_wait);
319 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
321 // Wait for readable and dispatcher gets closed.
323 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
324 test::WaiterThread thread(d,
325 MOJO_WAIT_FLAG_READABLE,
326 MOJO_DEADLINE_INDEFINITE,
328 &did_wait, &result);
329 stopwatch.Start();
330 thread.Start();
331 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
332 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
333 } // Joins the thread.
334 elapsed = stopwatch.Elapsed();
335 EXPECT_GT(elapsed, (2-1) * test::EpsilonTimeout());
336 EXPECT_LT(elapsed, (2+1) * test::EpsilonTimeout());
337 EXPECT_TRUE(did_wait);
338 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
340 // Wait for readable and times out.
342 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
344 test::WaiterThread thread(d,
345 MOJO_WAIT_FLAG_READABLE,
346 2 * test::EpsilonTimeout().InMicroseconds(),
348 &did_wait, &result);
349 stopwatch.Start();
350 thread.Start();
351 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
352 // Not what we're waiting for.
353 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_WRITABLE);
354 } // Joins the thread (after its wait times out).
355 // If we closed earlier, then probably we'd get a |MOJO_RESULT_CANCELLED|.
356 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
358 elapsed = stopwatch.Elapsed();
359 EXPECT_GT(elapsed, (2-1) * test::EpsilonTimeout());
360 EXPECT_LT(elapsed, (2+1) * test::EpsilonTimeout());
361 EXPECT_TRUE(did_wait);
362 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result);
365 TEST(SimpleDispatcherTest, MultipleWaiters) {
366 static const size_t kNumWaiters = 20;
368 bool did_wait[kNumWaiters];
369 MojoResult result[kNumWaiters];
371 // All wait for readable and becomes readable after some time.
373 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
374 ScopedVector<test::WaiterThread> threads;
375 for (size_t i = 0; i < kNumWaiters; i++) {
376 threads.push_back(new test::WaiterThread(d,
377 MOJO_WAIT_FLAG_READABLE,
378 MOJO_DEADLINE_INDEFINITE,
379 static_cast<MojoResult>(i),
380 &did_wait[i], &result[i]));
381 threads.back()->Start();
383 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
384 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
385 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
386 } // Joins the threads.
387 for (size_t i = 0; i < kNumWaiters; i++) {
388 EXPECT_TRUE(did_wait[i]);
389 EXPECT_EQ(static_cast<MojoResult>(i), result[i]);
392 // Some wait for readable, some for writable, and becomes readable after some
393 // time.
395 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
396 ScopedVector<test::WaiterThread> threads;
397 for (size_t i = 0; i < kNumWaiters / 2; i++) {
398 threads.push_back(new test::WaiterThread(d,
399 MOJO_WAIT_FLAG_READABLE,
400 MOJO_DEADLINE_INDEFINITE,
401 static_cast<MojoResult>(i),
402 &did_wait[i], &result[i]));
403 threads.back()->Start();
405 for (size_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
406 threads.push_back(new test::WaiterThread(d,
407 MOJO_WAIT_FLAG_WRITABLE,
408 MOJO_DEADLINE_INDEFINITE,
409 static_cast<MojoResult>(i),
410 &did_wait[i], &result[i]));
411 threads.back()->Start();
413 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
414 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
415 // This will wake up the ones waiting to write.
416 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
417 } // Joins the threads.
418 for (size_t i = 0; i < kNumWaiters / 2; i++) {
419 EXPECT_TRUE(did_wait[i]);
420 EXPECT_EQ(static_cast<MojoResult>(i), result[i]);
422 for (size_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
423 EXPECT_TRUE(did_wait[i]);
424 EXPECT_EQ(MOJO_RESULT_CANCELLED, result[i]);
427 // Some wait for readable, some for writable, and becomes readable and
428 // never-writable after some time.
430 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
431 ScopedVector<test::WaiterThread> threads;
432 for (size_t i = 0; i < kNumWaiters / 2; i++) {
433 threads.push_back(new test::WaiterThread(d,
434 MOJO_WAIT_FLAG_READABLE,
435 MOJO_DEADLINE_INDEFINITE,
436 static_cast<MojoResult>(i),
437 &did_wait[i], &result[i]));
438 threads.back()->Start();
440 for (size_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
441 threads.push_back(new test::WaiterThread(d,
442 MOJO_WAIT_FLAG_WRITABLE,
443 MOJO_DEADLINE_INDEFINITE,
444 static_cast<MojoResult>(i),
445 &did_wait[i], &result[i]));
446 threads.back()->Start();
448 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
449 d->SetSatisfiableFlags(MOJO_WAIT_FLAG_READABLE);
450 base::PlatformThread::Sleep(1 * test::EpsilonTimeout());
451 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
452 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
453 } // Joins the threads.
454 for (size_t i = 0; i < kNumWaiters / 2; i++) {
455 EXPECT_TRUE(did_wait[i]);
456 EXPECT_EQ(static_cast<MojoResult>(i), result[i]);
458 for (size_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
459 EXPECT_TRUE(did_wait[i]);
460 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result[i]);
463 // Some wait for readable, some for writable, and becomes readable after some
464 // time.
466 scoped_refptr<MockSimpleDispatcher> d(new MockSimpleDispatcher());
467 ScopedVector<test::WaiterThread> threads;
468 for (size_t i = 0; i < kNumWaiters / 2; i++) {
469 threads.push_back(
470 new test::WaiterThread(d,
471 MOJO_WAIT_FLAG_READABLE,
472 3 * test::EpsilonTimeout().InMicroseconds(),
473 static_cast<MojoResult>(i),
474 &did_wait[i], &result[i]));
475 threads.back()->Start();
477 for (size_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
478 threads.push_back(
479 new test::WaiterThread(d,
480 MOJO_WAIT_FLAG_WRITABLE,
481 1 * test::EpsilonTimeout().InMicroseconds(),
482 static_cast<MojoResult>(i),
483 &did_wait[i], &result[i]));
484 threads.back()->Start();
486 base::PlatformThread::Sleep(2 * test::EpsilonTimeout());
487 d->SetSatisfiedFlags(MOJO_WAIT_FLAG_READABLE);
488 // All those waiting for writable should have timed out.
489 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
490 } // Joins the threads.
491 for (size_t i = 0; i < kNumWaiters / 2; i++) {
492 EXPECT_TRUE(did_wait[i]);
493 EXPECT_EQ(static_cast<MojoResult>(i), result[i]);
495 for (size_t i = kNumWaiters / 2; i < kNumWaiters; i++) {
496 EXPECT_TRUE(did_wait[i]);
497 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, result[i]);
501 // TODO(vtl): Stress test?
503 } // namespace
504 } // namespace system
505 } // namespace mojo