OLD | NEW |
| (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 #include "mojo/edk/system/core.h" | |
6 | |
7 #include <stdint.h> | |
8 | |
9 #include <limits> | |
10 | |
11 #include "base/threading/platform_thread.h" | |
12 #include "base/time/time.h" | |
13 #include "mojo/edk/system/core_test_base.h" | |
14 | |
15 namespace mojo { | |
16 namespace system { | |
17 namespace { | |
18 | |
19 const MojoHandleSignalsState kEmptyMojoHandleSignalsState = {0u, 0u}; | |
20 const MojoHandleSignalsState kFullMojoHandleSignalsState = {~0u, ~0u}; | |
21 | |
22 typedef test::CoreTestBase CoreTest; | |
23 | |
24 TEST_F(CoreTest, GetTimeTicksNow) { | |
25 const MojoTimeTicks start = core()->GetTimeTicksNow(); | |
26 EXPECT_NE(static_cast<MojoTimeTicks>(0), start) | |
27 << "GetTimeTicksNow should return nonzero value"; | |
28 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(15)); | |
29 const MojoTimeTicks finish = core()->GetTimeTicksNow(); | |
30 // Allow for some fuzz in sleep. | |
31 EXPECT_GE((finish - start), static_cast<MojoTimeTicks>(8000)) | |
32 << "Sleeping should result in increasing time ticks"; | |
33 } | |
34 | |
35 TEST_F(CoreTest, Basic) { | |
36 MockHandleInfo info; | |
37 | |
38 EXPECT_EQ(0u, info.GetCtorCallCount()); | |
39 MojoHandle h = CreateMockHandle(&info); | |
40 EXPECT_EQ(1u, info.GetCtorCallCount()); | |
41 EXPECT_NE(h, MOJO_HANDLE_INVALID); | |
42 | |
43 EXPECT_EQ(0u, info.GetWriteMessageCallCount()); | |
44 EXPECT_EQ(MOJO_RESULT_OK, | |
45 core()->WriteMessage(h, | |
46 NullUserPointer(), | |
47 0, | |
48 NullUserPointer(), | |
49 0, | |
50 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
51 EXPECT_EQ(1u, info.GetWriteMessageCallCount()); | |
52 | |
53 EXPECT_EQ(0u, info.GetReadMessageCallCount()); | |
54 uint32_t num_bytes = 0; | |
55 EXPECT_EQ(MOJO_RESULT_OK, | |
56 core()->ReadMessage(h, | |
57 NullUserPointer(), | |
58 MakeUserPointer(&num_bytes), | |
59 NullUserPointer(), | |
60 NullUserPointer(), | |
61 MOJO_READ_MESSAGE_FLAG_NONE)); | |
62 EXPECT_EQ(1u, info.GetReadMessageCallCount()); | |
63 EXPECT_EQ(MOJO_RESULT_OK, | |
64 core()->ReadMessage(h, | |
65 NullUserPointer(), | |
66 NullUserPointer(), | |
67 NullUserPointer(), | |
68 NullUserPointer(), | |
69 MOJO_READ_MESSAGE_FLAG_NONE)); | |
70 EXPECT_EQ(2u, info.GetReadMessageCallCount()); | |
71 | |
72 EXPECT_EQ(0u, info.GetWriteDataCallCount()); | |
73 EXPECT_EQ( | |
74 MOJO_RESULT_UNIMPLEMENTED, | |
75 core()->WriteData( | |
76 h, NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE)); | |
77 EXPECT_EQ(1u, info.GetWriteDataCallCount()); | |
78 | |
79 EXPECT_EQ(0u, info.GetBeginWriteDataCallCount()); | |
80 EXPECT_EQ( | |
81 MOJO_RESULT_UNIMPLEMENTED, | |
82 core()->BeginWriteData( | |
83 h, NullUserPointer(), NullUserPointer(), MOJO_WRITE_DATA_FLAG_NONE)); | |
84 EXPECT_EQ(1u, info.GetBeginWriteDataCallCount()); | |
85 | |
86 EXPECT_EQ(0u, info.GetEndWriteDataCallCount()); | |
87 EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndWriteData(h, 0)); | |
88 EXPECT_EQ(1u, info.GetEndWriteDataCallCount()); | |
89 | |
90 EXPECT_EQ(0u, info.GetReadDataCallCount()); | |
91 EXPECT_EQ( | |
92 MOJO_RESULT_UNIMPLEMENTED, | |
93 core()->ReadData( | |
94 h, NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE)); | |
95 EXPECT_EQ(1u, info.GetReadDataCallCount()); | |
96 | |
97 EXPECT_EQ(0u, info.GetBeginReadDataCallCount()); | |
98 EXPECT_EQ( | |
99 MOJO_RESULT_UNIMPLEMENTED, | |
100 core()->BeginReadData( | |
101 h, NullUserPointer(), NullUserPointer(), MOJO_READ_DATA_FLAG_NONE)); | |
102 EXPECT_EQ(1u, info.GetBeginReadDataCallCount()); | |
103 | |
104 EXPECT_EQ(0u, info.GetEndReadDataCallCount()); | |
105 EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndReadData(h, 0)); | |
106 EXPECT_EQ(1u, info.GetEndReadDataCallCount()); | |
107 | |
108 EXPECT_EQ(0u, info.GetAddWaiterCallCount()); | |
109 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
110 core()->Wait(h, | |
111 ~MOJO_HANDLE_SIGNAL_NONE, | |
112 MOJO_DEADLINE_INDEFINITE, | |
113 NullUserPointer())); | |
114 EXPECT_EQ(1u, info.GetAddWaiterCallCount()); | |
115 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
116 core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, 0, NullUserPointer())); | |
117 EXPECT_EQ(2u, info.GetAddWaiterCallCount()); | |
118 MojoHandleSignalsState hss = kFullMojoHandleSignalsState; | |
119 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
120 core()->Wait(h, | |
121 ~MOJO_HANDLE_SIGNAL_NONE, | |
122 MOJO_DEADLINE_INDEFINITE, | |
123 MakeUserPointer(&hss))); | |
124 EXPECT_EQ(3u, info.GetAddWaiterCallCount()); | |
125 EXPECT_EQ(0u, hss.satisfied_signals); | |
126 EXPECT_EQ(0u, hss.satisfiable_signals); | |
127 EXPECT_EQ( | |
128 MOJO_RESULT_FAILED_PRECONDITION, | |
129 core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, 10 * 1000, NullUserPointer())); | |
130 EXPECT_EQ(4u, info.GetAddWaiterCallCount()); | |
131 hss = kFullMojoHandleSignalsState; | |
132 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
133 core()->Wait( | |
134 h, ~MOJO_HANDLE_SIGNAL_NONE, 10 * 1000, MakeUserPointer(&hss))); | |
135 EXPECT_EQ(5u, info.GetAddWaiterCallCount()); | |
136 EXPECT_EQ(0u, hss.satisfied_signals); | |
137 EXPECT_EQ(0u, hss.satisfiable_signals); | |
138 | |
139 MojoHandleSignals handle_signals = ~MOJO_HANDLE_SIGNAL_NONE; | |
140 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
141 core()->WaitMany(MakeUserPointer(&h), | |
142 MakeUserPointer(&handle_signals), | |
143 1, | |
144 MOJO_DEADLINE_INDEFINITE, | |
145 NullUserPointer(), | |
146 NullUserPointer())); | |
147 EXPECT_EQ(6u, info.GetAddWaiterCallCount()); | |
148 uint32_t result_index = static_cast<uint32_t>(-1); | |
149 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
150 core()->WaitMany(MakeUserPointer(&h), | |
151 MakeUserPointer(&handle_signals), | |
152 1, | |
153 MOJO_DEADLINE_INDEFINITE, | |
154 MakeUserPointer(&result_index), | |
155 NullUserPointer())); | |
156 EXPECT_EQ(7u, info.GetAddWaiterCallCount()); | |
157 EXPECT_EQ(0u, result_index); | |
158 hss = kFullMojoHandleSignalsState; | |
159 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
160 core()->WaitMany(MakeUserPointer(&h), | |
161 MakeUserPointer(&handle_signals), | |
162 1, | |
163 MOJO_DEADLINE_INDEFINITE, | |
164 NullUserPointer(), | |
165 MakeUserPointer(&hss))); | |
166 EXPECT_EQ(8u, info.GetAddWaiterCallCount()); | |
167 EXPECT_EQ(0u, hss.satisfied_signals); | |
168 EXPECT_EQ(0u, hss.satisfiable_signals); | |
169 result_index = static_cast<uint32_t>(-1); | |
170 hss = kFullMojoHandleSignalsState; | |
171 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
172 core()->WaitMany(MakeUserPointer(&h), | |
173 MakeUserPointer(&handle_signals), | |
174 1, | |
175 MOJO_DEADLINE_INDEFINITE, | |
176 MakeUserPointer(&result_index), | |
177 MakeUserPointer(&hss))); | |
178 EXPECT_EQ(9u, info.GetAddWaiterCallCount()); | |
179 EXPECT_EQ(0u, result_index); | |
180 EXPECT_EQ(0u, hss.satisfied_signals); | |
181 EXPECT_EQ(0u, hss.satisfiable_signals); | |
182 | |
183 EXPECT_EQ(0u, info.GetDtorCallCount()); | |
184 EXPECT_EQ(0u, info.GetCloseCallCount()); | |
185 EXPECT_EQ(0u, info.GetCancelAllWaitersCallCount()); | |
186 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); | |
187 EXPECT_EQ(1u, info.GetCancelAllWaitersCallCount()); | |
188 EXPECT_EQ(1u, info.GetCloseCallCount()); | |
189 EXPECT_EQ(1u, info.GetDtorCallCount()); | |
190 | |
191 // No waiters should ever have ever been added. | |
192 EXPECT_EQ(0u, info.GetRemoveWaiterCallCount()); | |
193 } | |
194 | |
195 TEST_F(CoreTest, InvalidArguments) { | |
196 // |Close()|: | |
197 { | |
198 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(MOJO_HANDLE_INVALID)); | |
199 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(10)); | |
200 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(1000000000)); | |
201 | |
202 // Test a double-close. | |
203 MockHandleInfo info; | |
204 MojoHandle h = CreateMockHandle(&info); | |
205 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); | |
206 EXPECT_EQ(1u, info.GetCloseCallCount()); | |
207 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(h)); | |
208 EXPECT_EQ(1u, info.GetCloseCallCount()); | |
209 } | |
210 | |
211 // |Wait()|: | |
212 { | |
213 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
214 core()->Wait(MOJO_HANDLE_INVALID, | |
215 ~MOJO_HANDLE_SIGNAL_NONE, | |
216 MOJO_DEADLINE_INDEFINITE, | |
217 NullUserPointer())); | |
218 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
219 core()->Wait(10, | |
220 ~MOJO_HANDLE_SIGNAL_NONE, | |
221 MOJO_DEADLINE_INDEFINITE, | |
222 NullUserPointer())); | |
223 | |
224 MojoHandleSignalsState hss = kFullMojoHandleSignalsState; | |
225 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
226 core()->Wait(MOJO_HANDLE_INVALID, | |
227 ~MOJO_HANDLE_SIGNAL_NONE, | |
228 MOJO_DEADLINE_INDEFINITE, | |
229 MakeUserPointer(&hss))); | |
230 // On invalid argument, it shouldn't modify the handle signals state. | |
231 EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals, | |
232 hss.satisfied_signals); | |
233 EXPECT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, | |
234 hss.satisfiable_signals); | |
235 hss = kFullMojoHandleSignalsState; | |
236 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
237 core()->Wait(10, | |
238 ~MOJO_HANDLE_SIGNAL_NONE, | |
239 MOJO_DEADLINE_INDEFINITE, | |
240 MakeUserPointer(&hss))); | |
241 // On invalid argument, it shouldn't modify the handle signals state. | |
242 EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals, | |
243 hss.satisfied_signals); | |
244 EXPECT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, | |
245 hss.satisfiable_signals); | |
246 } | |
247 | |
248 // |WaitMany()|: | |
249 { | |
250 MojoHandle handles[2] = {MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID}; | |
251 MojoHandleSignals signals[2] = {~MOJO_HANDLE_SIGNAL_NONE, | |
252 ~MOJO_HANDLE_SIGNAL_NONE}; | |
253 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
254 core()->WaitMany(MakeUserPointer(handles), | |
255 MakeUserPointer(signals), | |
256 0, | |
257 MOJO_DEADLINE_INDEFINITE, | |
258 NullUserPointer(), | |
259 NullUserPointer())); | |
260 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
261 core()->WaitMany(NullUserPointer(), | |
262 MakeUserPointer(signals), | |
263 0, | |
264 MOJO_DEADLINE_INDEFINITE, | |
265 NullUserPointer(), | |
266 NullUserPointer())); | |
267 // If |num_handles| is invalid, it should leave |result_index| and | |
268 // |signals_states| alone. | |
269 // (We use -1 internally; make sure that doesn't leak.) | |
270 uint32_t result_index = 123; | |
271 MojoHandleSignalsState hss = kFullMojoHandleSignalsState; | |
272 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
273 core()->WaitMany(NullUserPointer(), | |
274 MakeUserPointer(signals), | |
275 0, | |
276 MOJO_DEADLINE_INDEFINITE, | |
277 MakeUserPointer(&result_index), | |
278 MakeUserPointer(&hss))); | |
279 EXPECT_EQ(123u, result_index); | |
280 EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals, | |
281 hss.satisfied_signals); | |
282 EXPECT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, | |
283 hss.satisfiable_signals); | |
284 | |
285 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
286 core()->WaitMany(MakeUserPointer(handles), | |
287 NullUserPointer(), | |
288 0, | |
289 MOJO_DEADLINE_INDEFINITE, | |
290 NullUserPointer(), | |
291 NullUserPointer())); | |
292 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
293 core()->WaitMany(MakeUserPointer(handles), | |
294 MakeUserPointer(signals), | |
295 1, | |
296 MOJO_DEADLINE_INDEFINITE, | |
297 NullUserPointer(), | |
298 NullUserPointer())); | |
299 // But if a handle is bad, then it should set |result_index| but still leave | |
300 // |signals_states| alone. | |
301 result_index = static_cast<uint32_t>(-1); | |
302 hss = kFullMojoHandleSignalsState; | |
303 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
304 core()->WaitMany(MakeUserPointer(handles), | |
305 MakeUserPointer(signals), | |
306 1, | |
307 MOJO_DEADLINE_INDEFINITE, | |
308 MakeUserPointer(&result_index), | |
309 MakeUserPointer(&hss))); | |
310 EXPECT_EQ(0u, result_index); | |
311 EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals, | |
312 hss.satisfied_signals); | |
313 EXPECT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, | |
314 hss.satisfiable_signals); | |
315 | |
316 MockHandleInfo info[2]; | |
317 handles[0] = CreateMockHandle(&info[0]); | |
318 | |
319 result_index = static_cast<uint32_t>(-1); | |
320 hss = kFullMojoHandleSignalsState; | |
321 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
322 core()->WaitMany(MakeUserPointer(handles), | |
323 MakeUserPointer(signals), | |
324 1, | |
325 MOJO_DEADLINE_INDEFINITE, | |
326 MakeUserPointer(&result_index), | |
327 MakeUserPointer(&hss))); | |
328 EXPECT_EQ(0u, result_index); | |
329 EXPECT_EQ(0u, hss.satisfied_signals); | |
330 EXPECT_EQ(0u, hss.satisfiable_signals); | |
331 | |
332 // On invalid argument, it'll leave |signals_states| alone. | |
333 result_index = static_cast<uint32_t>(-1); | |
334 hss = kFullMojoHandleSignalsState; | |
335 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
336 core()->WaitMany(MakeUserPointer(handles), | |
337 MakeUserPointer(signals), | |
338 2, | |
339 MOJO_DEADLINE_INDEFINITE, | |
340 MakeUserPointer(&result_index), | |
341 MakeUserPointer(&hss))); | |
342 EXPECT_EQ(1u, result_index); | |
343 EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals, | |
344 hss.satisfied_signals); | |
345 EXPECT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, | |
346 hss.satisfiable_signals); | |
347 handles[1] = handles[0] + 1; // Invalid handle. | |
348 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
349 core()->WaitMany(MakeUserPointer(handles), | |
350 MakeUserPointer(signals), | |
351 2, | |
352 MOJO_DEADLINE_INDEFINITE, | |
353 NullUserPointer(), | |
354 NullUserPointer())); | |
355 handles[1] = CreateMockHandle(&info[1]); | |
356 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
357 core()->WaitMany(MakeUserPointer(handles), | |
358 MakeUserPointer(signals), | |
359 2, | |
360 MOJO_DEADLINE_INDEFINITE, | |
361 NullUserPointer(), | |
362 NullUserPointer())); | |
363 | |
364 // TODO(vtl): Test one where we get "failed precondition" only for the | |
365 // second handle (and the first one is valid to wait on). | |
366 | |
367 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(handles[0])); | |
368 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(handles[1])); | |
369 } | |
370 | |
371 // |CreateMessagePipe()|: Nothing to check (apart from things that cause | |
372 // death). | |
373 | |
374 // |WriteMessage()|: | |
375 // Only check arguments checked by |Core|, namely |handle|, |handles|, and | |
376 // |num_handles|. | |
377 { | |
378 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
379 core()->WriteMessage(MOJO_HANDLE_INVALID, | |
380 NullUserPointer(), | |
381 0, | |
382 NullUserPointer(), | |
383 0, | |
384 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
385 | |
386 MockHandleInfo info; | |
387 MojoHandle h = CreateMockHandle(&info); | |
388 MojoHandle handles[2] = {MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID}; | |
389 | |
390 // Huge handle count (implausibly big on some systems -- more than can be | |
391 // stored in a 32-bit address space). | |
392 // Note: This may return either |MOJO_RESULT_INVALID_ARGUMENT| or | |
393 // |MOJO_RESULT_RESOURCE_EXHAUSTED|, depending on whether it's plausible or | |
394 // not. | |
395 EXPECT_NE(MOJO_RESULT_OK, | |
396 core()->WriteMessage(h, | |
397 NullUserPointer(), | |
398 0, | |
399 MakeUserPointer(handles), | |
400 std::numeric_limits<uint32_t>::max(), | |
401 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
402 EXPECT_EQ(0u, info.GetWriteMessageCallCount()); | |
403 | |
404 // Huge handle count (plausibly big). | |
405 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, | |
406 core()->WriteMessage( | |
407 h, | |
408 NullUserPointer(), | |
409 0, | |
410 MakeUserPointer(handles), | |
411 std::numeric_limits<uint32_t>::max() / sizeof(handles[0]), | |
412 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
413 EXPECT_EQ(0u, info.GetWriteMessageCallCount()); | |
414 | |
415 // Invalid handle in |handles|. | |
416 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
417 core()->WriteMessage(h, | |
418 NullUserPointer(), | |
419 0, | |
420 MakeUserPointer(handles), | |
421 1, | |
422 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
423 EXPECT_EQ(0u, info.GetWriteMessageCallCount()); | |
424 | |
425 // Two invalid handles in |handles|. | |
426 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
427 core()->WriteMessage(h, | |
428 NullUserPointer(), | |
429 0, | |
430 MakeUserPointer(handles), | |
431 2, | |
432 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
433 EXPECT_EQ(0u, info.GetWriteMessageCallCount()); | |
434 | |
435 // Can't send a handle over itself. | |
436 handles[0] = h; | |
437 EXPECT_EQ(MOJO_RESULT_BUSY, | |
438 core()->WriteMessage(h, | |
439 NullUserPointer(), | |
440 0, | |
441 MakeUserPointer(handles), | |
442 1, | |
443 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
444 EXPECT_EQ(0u, info.GetWriteMessageCallCount()); | |
445 | |
446 MockHandleInfo info2; | |
447 MojoHandle h2 = CreateMockHandle(&info2); | |
448 | |
449 // This is "okay", but |MockDispatcher| doesn't implement it. | |
450 handles[0] = h2; | |
451 EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED, | |
452 core()->WriteMessage(h, | |
453 NullUserPointer(), | |
454 0, | |
455 MakeUserPointer(handles), | |
456 1, | |
457 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
458 EXPECT_EQ(1u, info.GetWriteMessageCallCount()); | |
459 | |
460 // One of the |handles| is still invalid. | |
461 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
462 core()->WriteMessage(h, | |
463 NullUserPointer(), | |
464 0, | |
465 MakeUserPointer(handles), | |
466 2, | |
467 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
468 EXPECT_EQ(1u, info.GetWriteMessageCallCount()); | |
469 | |
470 // One of the |handles| is the same as |handle|. | |
471 handles[1] = h; | |
472 EXPECT_EQ(MOJO_RESULT_BUSY, | |
473 core()->WriteMessage(h, | |
474 NullUserPointer(), | |
475 0, | |
476 MakeUserPointer(handles), | |
477 2, | |
478 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
479 EXPECT_EQ(1u, info.GetWriteMessageCallCount()); | |
480 | |
481 // Can't send a handle twice in the same message. | |
482 handles[1] = h2; | |
483 EXPECT_EQ(MOJO_RESULT_BUSY, | |
484 core()->WriteMessage(h, | |
485 NullUserPointer(), | |
486 0, | |
487 MakeUserPointer(handles), | |
488 2, | |
489 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
490 EXPECT_EQ(1u, info.GetWriteMessageCallCount()); | |
491 | |
492 // Note: Since we never successfully sent anything with it, |h2| should | |
493 // still be valid. | |
494 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h2)); | |
495 | |
496 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); | |
497 } | |
498 | |
499 // |ReadMessage()|: | |
500 // Only check arguments checked by |Core|, namely |handle|, |handles|, and | |
501 // |num_handles|. | |
502 { | |
503 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
504 core()->ReadMessage(MOJO_HANDLE_INVALID, | |
505 NullUserPointer(), | |
506 NullUserPointer(), | |
507 NullUserPointer(), | |
508 NullUserPointer(), | |
509 MOJO_READ_MESSAGE_FLAG_NONE)); | |
510 | |
511 MockHandleInfo info; | |
512 MojoHandle h = CreateMockHandle(&info); | |
513 | |
514 // Okay. | |
515 uint32_t handle_count = 0; | |
516 EXPECT_EQ(MOJO_RESULT_OK, | |
517 core()->ReadMessage(h, | |
518 NullUserPointer(), | |
519 NullUserPointer(), | |
520 NullUserPointer(), | |
521 MakeUserPointer(&handle_count), | |
522 MOJO_READ_MESSAGE_FLAG_NONE)); | |
523 // Checked by |Core|, shouldn't go through to the dispatcher. | |
524 EXPECT_EQ(1u, info.GetReadMessageCallCount()); | |
525 | |
526 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); | |
527 } | |
528 } | |
529 | |
530 // These test invalid arguments that should cause death if we're being paranoid | |
531 // about checking arguments (which we would want to do if, e.g., we were in a | |
532 // true "kernel" situation, but we might not want to do otherwise for | |
533 // performance reasons). Probably blatant errors like passing in null pointers | |
534 // (for required pointer arguments) will still cause death, but perhaps not | |
535 // predictably. | |
536 TEST_F(CoreTest, InvalidArgumentsDeath) { | |
537 const char kMemoryCheckFailedRegex[] = "Check failed"; | |
538 | |
539 // |WaitMany()|: | |
540 { | |
541 MojoHandle handle = MOJO_HANDLE_INVALID; | |
542 MojoHandleSignals signals = ~MOJO_HANDLE_SIGNAL_NONE; | |
543 EXPECT_DEATH_IF_SUPPORTED(core()->WaitMany(NullUserPointer(), | |
544 MakeUserPointer(&signals), | |
545 1, | |
546 MOJO_DEADLINE_INDEFINITE, | |
547 NullUserPointer(), | |
548 NullUserPointer()), | |
549 kMemoryCheckFailedRegex); | |
550 EXPECT_DEATH_IF_SUPPORTED(core()->WaitMany(MakeUserPointer(&handle), | |
551 NullUserPointer(), | |
552 1, | |
553 MOJO_DEADLINE_INDEFINITE, | |
554 NullUserPointer(), | |
555 NullUserPointer()), | |
556 kMemoryCheckFailedRegex); | |
557 // TODO(vtl): |result_index| and |signals_states| are optional. Test them | |
558 // with non-null invalid pointers? | |
559 } | |
560 | |
561 // |CreateMessagePipe()|: | |
562 { | |
563 MojoHandle h; | |
564 EXPECT_DEATH_IF_SUPPORTED( | |
565 core()->CreateMessagePipe( | |
566 NullUserPointer(), NullUserPointer(), NullUserPointer()), | |
567 kMemoryCheckFailedRegex); | |
568 EXPECT_DEATH_IF_SUPPORTED( | |
569 core()->CreateMessagePipe( | |
570 NullUserPointer(), MakeUserPointer(&h), NullUserPointer()), | |
571 kMemoryCheckFailedRegex); | |
572 EXPECT_DEATH_IF_SUPPORTED( | |
573 core()->CreateMessagePipe( | |
574 NullUserPointer(), NullUserPointer(), MakeUserPointer(&h)), | |
575 kMemoryCheckFailedRegex); | |
576 } | |
577 | |
578 // |WriteMessage()|: | |
579 // Only check arguments checked by |Core|, namely |handle|, |handles|, and | |
580 // |num_handles|. | |
581 { | |
582 MockHandleInfo info; | |
583 MojoHandle h = CreateMockHandle(&info); | |
584 | |
585 // Null |handles| with nonzero |num_handles|. | |
586 EXPECT_DEATH_IF_SUPPORTED( | |
587 core()->WriteMessage(h, | |
588 NullUserPointer(), | |
589 0, | |
590 NullUserPointer(), | |
591 1, | |
592 MOJO_WRITE_MESSAGE_FLAG_NONE), | |
593 kMemoryCheckFailedRegex); | |
594 | |
595 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); | |
596 } | |
597 | |
598 // |ReadMessage()|: | |
599 // Only check arguments checked by |Core|, namely |handle|, |handles|, and | |
600 // |num_handles|. | |
601 { | |
602 MockHandleInfo info; | |
603 MojoHandle h = CreateMockHandle(&info); | |
604 | |
605 uint32_t handle_count = 1; | |
606 EXPECT_DEATH_IF_SUPPORTED( | |
607 core()->ReadMessage(h, | |
608 NullUserPointer(), | |
609 NullUserPointer(), | |
610 NullUserPointer(), | |
611 MakeUserPointer(&handle_count), | |
612 MOJO_READ_MESSAGE_FLAG_NONE), | |
613 kMemoryCheckFailedRegex); | |
614 | |
615 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); | |
616 } | |
617 } | |
618 | |
619 // TODO(vtl): test |Wait()| and |WaitMany()| properly | |
620 // - including |WaitMany()| with the same handle more than once (with | |
621 // same/different signals) | |
622 | |
623 TEST_F(CoreTest, MessagePipe) { | |
624 MojoHandle h[2]; | |
625 MojoHandleSignalsState hss[2]; | |
626 uint32_t result_index; | |
627 | |
628 EXPECT_EQ( | |
629 MOJO_RESULT_OK, | |
630 core()->CreateMessagePipe( | |
631 NullUserPointer(), MakeUserPointer(&h[0]), MakeUserPointer(&h[1]))); | |
632 // Should get two distinct, valid handles. | |
633 EXPECT_NE(h[0], MOJO_HANDLE_INVALID); | |
634 EXPECT_NE(h[1], MOJO_HANDLE_INVALID); | |
635 EXPECT_NE(h[0], h[1]); | |
636 | |
637 // Neither should be readable. | |
638 MojoHandleSignals signals[2] = {MOJO_HANDLE_SIGNAL_READABLE, | |
639 MOJO_HANDLE_SIGNAL_READABLE}; | |
640 result_index = static_cast<uint32_t>(-1); | |
641 hss[0] = kEmptyMojoHandleSignalsState; | |
642 hss[1] = kEmptyMojoHandleSignalsState; | |
643 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, | |
644 core()->WaitMany(MakeUserPointer(h), | |
645 MakeUserPointer(signals), | |
646 2, | |
647 0, | |
648 MakeUserPointer(&result_index), | |
649 MakeUserPointer(hss))); | |
650 EXPECT_EQ(static_cast<uint32_t>(-1), result_index); | |
651 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); | |
652 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
653 hss[0].satisfiable_signals); | |
654 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals); | |
655 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
656 hss[1].satisfiable_signals); | |
657 | |
658 // Try to read anyway. | |
659 char buffer[1] = {'a'}; | |
660 uint32_t buffer_size = 1; | |
661 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
662 core()->ReadMessage(h[0], | |
663 UserPointer<void>(buffer), | |
664 MakeUserPointer(&buffer_size), | |
665 NullUserPointer(), | |
666 NullUserPointer(), | |
667 MOJO_READ_MESSAGE_FLAG_NONE)); | |
668 // Check that it left its inputs alone. | |
669 EXPECT_EQ('a', buffer[0]); | |
670 EXPECT_EQ(1u, buffer_size); | |
671 | |
672 // Both should be writable. | |
673 hss[0] = kEmptyMojoHandleSignalsState; | |
674 EXPECT_EQ(MOJO_RESULT_OK, | |
675 core()->Wait(h[0], | |
676 MOJO_HANDLE_SIGNAL_WRITABLE, | |
677 1000000000, | |
678 MakeUserPointer(&hss[0]))); | |
679 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); | |
680 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
681 hss[0].satisfiable_signals); | |
682 hss[0] = kEmptyMojoHandleSignalsState; | |
683 EXPECT_EQ(MOJO_RESULT_OK, | |
684 core()->Wait(h[1], | |
685 MOJO_HANDLE_SIGNAL_WRITABLE, | |
686 1000000000, | |
687 MakeUserPointer(&hss[0]))); | |
688 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); | |
689 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
690 hss[0].satisfiable_signals); | |
691 | |
692 // Also check that |h[1]| is writable using |WaitMany()|. | |
693 signals[0] = MOJO_HANDLE_SIGNAL_READABLE; | |
694 signals[1] = MOJO_HANDLE_SIGNAL_WRITABLE; | |
695 result_index = static_cast<uint32_t>(-1); | |
696 hss[0] = kEmptyMojoHandleSignalsState; | |
697 hss[1] = kEmptyMojoHandleSignalsState; | |
698 EXPECT_EQ(MOJO_RESULT_OK, | |
699 core()->WaitMany(MakeUserPointer(h), | |
700 MakeUserPointer(signals), | |
701 2, | |
702 MOJO_DEADLINE_INDEFINITE, | |
703 MakeUserPointer(&result_index), | |
704 MakeUserPointer(hss))); | |
705 EXPECT_EQ(1u, result_index); | |
706 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); | |
707 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
708 hss[0].satisfiable_signals); | |
709 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals); | |
710 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
711 hss[1].satisfiable_signals); | |
712 | |
713 // Write to |h[1]|. | |
714 buffer[0] = 'b'; | |
715 EXPECT_EQ(MOJO_RESULT_OK, | |
716 core()->WriteMessage(h[1], | |
717 UserPointer<const void>(buffer), | |
718 1, | |
719 NullUserPointer(), | |
720 0, | |
721 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
722 | |
723 // Check that |h[0]| is now readable. | |
724 signals[0] = MOJO_HANDLE_SIGNAL_READABLE; | |
725 signals[1] = MOJO_HANDLE_SIGNAL_READABLE; | |
726 result_index = static_cast<uint32_t>(-1); | |
727 hss[0] = kEmptyMojoHandleSignalsState; | |
728 hss[1] = kEmptyMojoHandleSignalsState; | |
729 EXPECT_EQ(MOJO_RESULT_OK, | |
730 core()->WaitMany(MakeUserPointer(h), | |
731 MakeUserPointer(signals), | |
732 2, | |
733 MOJO_DEADLINE_INDEFINITE, | |
734 MakeUserPointer(&result_index), | |
735 MakeUserPointer(hss))); | |
736 EXPECT_EQ(0u, result_index); | |
737 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
738 hss[0].satisfied_signals); | |
739 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
740 hss[0].satisfiable_signals); | |
741 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals); | |
742 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
743 hss[1].satisfiable_signals); | |
744 | |
745 // Read from |h[0]|. | |
746 // First, get only the size. | |
747 buffer_size = 0; | |
748 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, | |
749 core()->ReadMessage(h[0], | |
750 NullUserPointer(), | |
751 MakeUserPointer(&buffer_size), | |
752 NullUserPointer(), | |
753 NullUserPointer(), | |
754 MOJO_READ_MESSAGE_FLAG_NONE)); | |
755 EXPECT_EQ(1u, buffer_size); | |
756 // Then actually read it. | |
757 buffer[0] = 'c'; | |
758 buffer_size = 1; | |
759 EXPECT_EQ(MOJO_RESULT_OK, | |
760 core()->ReadMessage(h[0], | |
761 UserPointer<void>(buffer), | |
762 MakeUserPointer(&buffer_size), | |
763 NullUserPointer(), | |
764 NullUserPointer(), | |
765 MOJO_READ_MESSAGE_FLAG_NONE)); | |
766 EXPECT_EQ('b', buffer[0]); | |
767 EXPECT_EQ(1u, buffer_size); | |
768 | |
769 // |h[0]| should no longer be readable. | |
770 hss[0] = kEmptyMojoHandleSignalsState; | |
771 EXPECT_EQ( | |
772 MOJO_RESULT_DEADLINE_EXCEEDED, | |
773 core()->Wait( | |
774 h[0], MOJO_HANDLE_SIGNAL_READABLE, 0, MakeUserPointer(&hss[0]))); | |
775 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); | |
776 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
777 hss[0].satisfiable_signals); | |
778 | |
779 // Write to |h[0]|. | |
780 buffer[0] = 'd'; | |
781 EXPECT_EQ(MOJO_RESULT_OK, | |
782 core()->WriteMessage(h[0], | |
783 UserPointer<const void>(buffer), | |
784 1, | |
785 NullUserPointer(), | |
786 0, | |
787 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
788 | |
789 // Close |h[0]|. | |
790 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h[0])); | |
791 | |
792 // Check that |h[1]| is no longer writable (and will never be). | |
793 hss[0] = kEmptyMojoHandleSignalsState; | |
794 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
795 core()->Wait(h[1], | |
796 MOJO_HANDLE_SIGNAL_WRITABLE, | |
797 1000000000, | |
798 MakeUserPointer(&hss[0]))); | |
799 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss[0].satisfied_signals); | |
800 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss[0].satisfiable_signals); | |
801 | |
802 // Check that |h[1]| is still readable (for the moment). | |
803 hss[0] = kEmptyMojoHandleSignalsState; | |
804 EXPECT_EQ(MOJO_RESULT_OK, | |
805 core()->Wait(h[1], | |
806 MOJO_HANDLE_SIGNAL_READABLE, | |
807 1000000000, | |
808 MakeUserPointer(&hss[0]))); | |
809 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss[0].satisfied_signals); | |
810 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss[0].satisfiable_signals); | |
811 | |
812 // Discard a message from |h[1]|. | |
813 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, | |
814 core()->ReadMessage(h[1], | |
815 NullUserPointer(), | |
816 NullUserPointer(), | |
817 NullUserPointer(), | |
818 NullUserPointer(), | |
819 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
820 | |
821 // |h[1]| is no longer readable (and will never be). | |
822 hss[0] = kFullMojoHandleSignalsState; | |
823 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
824 core()->Wait(h[1], | |
825 MOJO_HANDLE_SIGNAL_READABLE, | |
826 1000000000, | |
827 MakeUserPointer(&hss[0]))); | |
828 EXPECT_EQ(0u, hss[0].satisfied_signals); | |
829 EXPECT_EQ(0u, hss[0].satisfiable_signals); | |
830 | |
831 // Try writing to |h[1]|. | |
832 buffer[0] = 'e'; | |
833 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
834 core()->WriteMessage(h[1], | |
835 UserPointer<const void>(buffer), | |
836 1, | |
837 NullUserPointer(), | |
838 0, | |
839 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
840 | |
841 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h[1])); | |
842 } | |
843 | |
844 // Tests passing a message pipe handle. | |
845 TEST_F(CoreTest, MessagePipeBasicLocalHandlePassing1) { | |
846 const char kHello[] = "hello"; | |
847 const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello)); | |
848 const char kWorld[] = "world!!!"; | |
849 const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld)); | |
850 char buffer[100]; | |
851 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | |
852 uint32_t num_bytes; | |
853 MojoHandle handles[10]; | |
854 uint32_t num_handles; | |
855 MojoHandleSignalsState hss; | |
856 MojoHandle h_received; | |
857 | |
858 MojoHandle h_passing[2]; | |
859 EXPECT_EQ(MOJO_RESULT_OK, | |
860 core()->CreateMessagePipe(NullUserPointer(), | |
861 MakeUserPointer(&h_passing[0]), | |
862 MakeUserPointer(&h_passing[1]))); | |
863 | |
864 // Make sure that |h_passing[]| work properly. | |
865 EXPECT_EQ(MOJO_RESULT_OK, | |
866 core()->WriteMessage(h_passing[0], | |
867 UserPointer<const void>(kHello), | |
868 kHelloSize, | |
869 NullUserPointer(), | |
870 0, | |
871 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
872 hss = kEmptyMojoHandleSignalsState; | |
873 EXPECT_EQ(MOJO_RESULT_OK, | |
874 core()->Wait(h_passing[1], | |
875 MOJO_HANDLE_SIGNAL_READABLE, | |
876 1000000000, | |
877 MakeUserPointer(&hss))); | |
878 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
879 hss.satisfied_signals); | |
880 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
881 hss.satisfiable_signals); | |
882 num_bytes = kBufferSize; | |
883 num_handles = arraysize(handles); | |
884 EXPECT_EQ(MOJO_RESULT_OK, | |
885 core()->ReadMessage(h_passing[1], | |
886 UserPointer<void>(buffer), | |
887 MakeUserPointer(&num_bytes), | |
888 MakeUserPointer(handles), | |
889 MakeUserPointer(&num_handles), | |
890 MOJO_READ_MESSAGE_FLAG_NONE)); | |
891 EXPECT_EQ(kHelloSize, num_bytes); | |
892 EXPECT_STREQ(kHello, buffer); | |
893 EXPECT_EQ(0u, num_handles); | |
894 | |
895 // Make sure that you can't pass either of the message pipe's handles over | |
896 // itself. | |
897 EXPECT_EQ(MOJO_RESULT_BUSY, | |
898 core()->WriteMessage(h_passing[0], | |
899 UserPointer<const void>(kHello), | |
900 kHelloSize, | |
901 MakeUserPointer(&h_passing[0]), | |
902 1, | |
903 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
904 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, | |
905 core()->WriteMessage(h_passing[0], | |
906 UserPointer<const void>(kHello), | |
907 kHelloSize, | |
908 MakeUserPointer(&h_passing[1]), | |
909 1, | |
910 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
911 | |
912 MojoHandle h_passed[2]; | |
913 EXPECT_EQ(MOJO_RESULT_OK, | |
914 core()->CreateMessagePipe(NullUserPointer(), | |
915 MakeUserPointer(&h_passed[0]), | |
916 MakeUserPointer(&h_passed[1]))); | |
917 | |
918 // Make sure that |h_passed[]| work properly. | |
919 EXPECT_EQ(MOJO_RESULT_OK, | |
920 core()->WriteMessage(h_passed[0], | |
921 UserPointer<const void>(kHello), | |
922 kHelloSize, | |
923 NullUserPointer(), | |
924 0, | |
925 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
926 hss = kEmptyMojoHandleSignalsState; | |
927 EXPECT_EQ(MOJO_RESULT_OK, | |
928 core()->Wait(h_passed[1], | |
929 MOJO_HANDLE_SIGNAL_READABLE, | |
930 1000000000, | |
931 MakeUserPointer(&hss))); | |
932 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
933 hss.satisfied_signals); | |
934 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
935 hss.satisfiable_signals); | |
936 num_bytes = kBufferSize; | |
937 num_handles = arraysize(handles); | |
938 EXPECT_EQ(MOJO_RESULT_OK, | |
939 core()->ReadMessage(h_passed[1], | |
940 UserPointer<void>(buffer), | |
941 MakeUserPointer(&num_bytes), | |
942 MakeUserPointer(handles), | |
943 MakeUserPointer(&num_handles), | |
944 MOJO_READ_MESSAGE_FLAG_NONE)); | |
945 EXPECT_EQ(kHelloSize, num_bytes); | |
946 EXPECT_STREQ(kHello, buffer); | |
947 EXPECT_EQ(0u, num_handles); | |
948 | |
949 // Send |h_passed[1]| from |h_passing[0]| to |h_passing[1]|. | |
950 EXPECT_EQ(MOJO_RESULT_OK, | |
951 core()->WriteMessage(h_passing[0], | |
952 UserPointer<const void>(kWorld), | |
953 kWorldSize, | |
954 MakeUserPointer(&h_passed[1]), | |
955 1, | |
956 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
957 hss = kEmptyMojoHandleSignalsState; | |
958 EXPECT_EQ(MOJO_RESULT_OK, | |
959 core()->Wait(h_passing[1], | |
960 MOJO_HANDLE_SIGNAL_READABLE, | |
961 1000000000, | |
962 MakeUserPointer(&hss))); | |
963 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
964 hss.satisfied_signals); | |
965 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
966 hss.satisfiable_signals); | |
967 num_bytes = kBufferSize; | |
968 num_handles = arraysize(handles); | |
969 EXPECT_EQ(MOJO_RESULT_OK, | |
970 core()->ReadMessage(h_passing[1], | |
971 UserPointer<void>(buffer), | |
972 MakeUserPointer(&num_bytes), | |
973 MakeUserPointer(handles), | |
974 MakeUserPointer(&num_handles), | |
975 MOJO_READ_MESSAGE_FLAG_NONE)); | |
976 EXPECT_EQ(kWorldSize, num_bytes); | |
977 EXPECT_STREQ(kWorld, buffer); | |
978 EXPECT_EQ(1u, num_handles); | |
979 h_received = handles[0]; | |
980 EXPECT_NE(h_received, MOJO_HANDLE_INVALID); | |
981 EXPECT_NE(h_received, h_passing[0]); | |
982 EXPECT_NE(h_received, h_passing[1]); | |
983 EXPECT_NE(h_received, h_passed[0]); | |
984 | |
985 // Note: We rely on the Mojo system not re-using handle values very often. | |
986 EXPECT_NE(h_received, h_passed[1]); | |
987 | |
988 // |h_passed[1]| should no longer be valid; check that trying to close it | |
989 // fails. See above note. | |
990 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(h_passed[1])); | |
991 | |
992 // Write to |h_passed[0]|. Should receive on |h_received|. | |
993 EXPECT_EQ(MOJO_RESULT_OK, | |
994 core()->WriteMessage(h_passed[0], | |
995 UserPointer<const void>(kHello), | |
996 kHelloSize, | |
997 NullUserPointer(), | |
998 0, | |
999 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
1000 hss = kEmptyMojoHandleSignalsState; | |
1001 EXPECT_EQ(MOJO_RESULT_OK, | |
1002 core()->Wait(h_received, | |
1003 MOJO_HANDLE_SIGNAL_READABLE, | |
1004 1000000000, | |
1005 MakeUserPointer(&hss))); | |
1006 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
1007 hss.satisfied_signals); | |
1008 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
1009 hss.satisfiable_signals); | |
1010 num_bytes = kBufferSize; | |
1011 num_handles = arraysize(handles); | |
1012 EXPECT_EQ(MOJO_RESULT_OK, | |
1013 core()->ReadMessage(h_received, | |
1014 UserPointer<void>(buffer), | |
1015 MakeUserPointer(&num_bytes), | |
1016 MakeUserPointer(handles), | |
1017 MakeUserPointer(&num_handles), | |
1018 MOJO_READ_MESSAGE_FLAG_NONE)); | |
1019 EXPECT_EQ(kHelloSize, num_bytes); | |
1020 EXPECT_STREQ(kHello, buffer); | |
1021 EXPECT_EQ(0u, num_handles); | |
1022 | |
1023 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[0])); | |
1024 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[1])); | |
1025 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_passed[0])); | |
1026 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_received)); | |
1027 } | |
1028 | |
1029 TEST_F(CoreTest, DataPipe) { | |
1030 MojoHandle ph, ch; // p is for producer and c is for consumer. | |
1031 MojoHandleSignalsState hss; | |
1032 | |
1033 EXPECT_EQ(MOJO_RESULT_OK, | |
1034 core()->CreateDataPipe( | |
1035 NullUserPointer(), MakeUserPointer(&ph), MakeUserPointer(&ch))); | |
1036 // Should get two distinct, valid handles. | |
1037 EXPECT_NE(ph, MOJO_HANDLE_INVALID); | |
1038 EXPECT_NE(ch, MOJO_HANDLE_INVALID); | |
1039 EXPECT_NE(ph, ch); | |
1040 | |
1041 // Producer should be never-readable, but already writable. | |
1042 hss = kEmptyMojoHandleSignalsState; | |
1043 EXPECT_EQ( | |
1044 MOJO_RESULT_FAILED_PRECONDITION, | |
1045 core()->Wait(ph, MOJO_HANDLE_SIGNAL_READABLE, 0, MakeUserPointer(&hss))); | |
1046 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); | |
1047 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfiable_signals); | |
1048 hss = kEmptyMojoHandleSignalsState; | |
1049 EXPECT_EQ( | |
1050 MOJO_RESULT_OK, | |
1051 core()->Wait(ph, MOJO_HANDLE_SIGNAL_WRITABLE, 0, MakeUserPointer(&hss))); | |
1052 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); | |
1053 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfiable_signals); | |
1054 | |
1055 // Consumer should be never-writable, and not yet readable. | |
1056 hss = kFullMojoHandleSignalsState; | |
1057 EXPECT_EQ( | |
1058 MOJO_RESULT_FAILED_PRECONDITION, | |
1059 core()->Wait(ch, MOJO_HANDLE_SIGNAL_WRITABLE, 0, MakeUserPointer(&hss))); | |
1060 EXPECT_EQ(0u, hss.satisfied_signals); | |
1061 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); | |
1062 hss = kFullMojoHandleSignalsState; | |
1063 EXPECT_EQ( | |
1064 MOJO_RESULT_DEADLINE_EXCEEDED, | |
1065 core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, MakeUserPointer(&hss))); | |
1066 EXPECT_EQ(0u, hss.satisfied_signals); | |
1067 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); | |
1068 | |
1069 // Write. | |
1070 char elements[2] = {'A', 'B'}; | |
1071 uint32_t num_bytes = 2u; | |
1072 EXPECT_EQ(MOJO_RESULT_OK, | |
1073 core()->WriteData(ph, | |
1074 UserPointer<const void>(elements), | |
1075 MakeUserPointer(&num_bytes), | |
1076 MOJO_WRITE_DATA_FLAG_NONE)); | |
1077 EXPECT_EQ(2u, num_bytes); | |
1078 | |
1079 // Consumer should now be readable. | |
1080 hss = kEmptyMojoHandleSignalsState; | |
1081 EXPECT_EQ( | |
1082 MOJO_RESULT_OK, | |
1083 core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, MakeUserPointer(&hss))); | |
1084 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); | |
1085 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); | |
1086 | |
1087 // Read one character. | |
1088 elements[0] = -1; | |
1089 elements[1] = -1; | |
1090 num_bytes = 1u; | |
1091 EXPECT_EQ(MOJO_RESULT_OK, | |
1092 core()->ReadData(ch, | |
1093 UserPointer<void>(elements), | |
1094 MakeUserPointer(&num_bytes), | |
1095 MOJO_READ_DATA_FLAG_NONE)); | |
1096 EXPECT_EQ('A', elements[0]); | |
1097 EXPECT_EQ(-1, elements[1]); | |
1098 | |
1099 // Two-phase write. | |
1100 void* write_ptr = nullptr; | |
1101 num_bytes = 0u; | |
1102 ASSERT_EQ(MOJO_RESULT_OK, | |
1103 core()->BeginWriteData(ph, | |
1104 MakeUserPointer(&write_ptr), | |
1105 MakeUserPointer(&num_bytes), | |
1106 MOJO_WRITE_DATA_FLAG_NONE)); | |
1107 // We count on the default options providing a decent buffer size. | |
1108 ASSERT_GE(num_bytes, 3u); | |
1109 | |
1110 // Trying to do a normal write during a two-phase write should fail. | |
1111 elements[0] = 'X'; | |
1112 num_bytes = 1u; | |
1113 EXPECT_EQ(MOJO_RESULT_BUSY, | |
1114 core()->WriteData(ph, | |
1115 UserPointer<const void>(elements), | |
1116 MakeUserPointer(&num_bytes), | |
1117 MOJO_WRITE_DATA_FLAG_NONE)); | |
1118 | |
1119 // Actually write the data, and complete it now. | |
1120 static_cast<char*>(write_ptr)[0] = 'C'; | |
1121 static_cast<char*>(write_ptr)[1] = 'D'; | |
1122 static_cast<char*>(write_ptr)[2] = 'E'; | |
1123 EXPECT_EQ(MOJO_RESULT_OK, core()->EndWriteData(ph, 3u)); | |
1124 | |
1125 // Query how much data we have. | |
1126 num_bytes = 0; | |
1127 EXPECT_EQ(MOJO_RESULT_OK, | |
1128 core()->ReadData(ch, | |
1129 NullUserPointer(), | |
1130 MakeUserPointer(&num_bytes), | |
1131 MOJO_READ_DATA_FLAG_QUERY)); | |
1132 EXPECT_EQ(4u, num_bytes); | |
1133 | |
1134 // Try to discard ten characters, in all-or-none mode. Should fail. | |
1135 num_bytes = 10; | |
1136 EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, | |
1137 core()->ReadData( | |
1138 ch, | |
1139 NullUserPointer(), | |
1140 MakeUserPointer(&num_bytes), | |
1141 MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE)); | |
1142 | |
1143 // Discard two characters. | |
1144 num_bytes = 2; | |
1145 EXPECT_EQ(MOJO_RESULT_OK, | |
1146 core()->ReadData( | |
1147 ch, | |
1148 NullUserPointer(), | |
1149 MakeUserPointer(&num_bytes), | |
1150 MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE)); | |
1151 | |
1152 // Read the remaining two characters, in two-phase mode (all-or-none). | |
1153 const void* read_ptr = nullptr; | |
1154 num_bytes = 2; | |
1155 ASSERT_EQ(MOJO_RESULT_OK, | |
1156 core()->BeginReadData(ch, | |
1157 MakeUserPointer(&read_ptr), | |
1158 MakeUserPointer(&num_bytes), | |
1159 MOJO_READ_DATA_FLAG_ALL_OR_NONE)); | |
1160 // Note: Count on still being able to do the contiguous read here. | |
1161 ASSERT_EQ(2u, num_bytes); | |
1162 | |
1163 // Discarding right now should fail. | |
1164 num_bytes = 1; | |
1165 EXPECT_EQ(MOJO_RESULT_BUSY, | |
1166 core()->ReadData(ch, | |
1167 NullUserPointer(), | |
1168 MakeUserPointer(&num_bytes), | |
1169 MOJO_READ_DATA_FLAG_DISCARD)); | |
1170 | |
1171 // Actually check our data and end the two-phase read. | |
1172 EXPECT_EQ('D', static_cast<const char*>(read_ptr)[0]); | |
1173 EXPECT_EQ('E', static_cast<const char*>(read_ptr)[1]); | |
1174 EXPECT_EQ(MOJO_RESULT_OK, core()->EndReadData(ch, 2u)); | |
1175 | |
1176 // Consumer should now be no longer readable. | |
1177 hss = kFullMojoHandleSignalsState; | |
1178 EXPECT_EQ( | |
1179 MOJO_RESULT_DEADLINE_EXCEEDED, | |
1180 core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, MakeUserPointer(&hss))); | |
1181 EXPECT_EQ(0u, hss.satisfied_signals); | |
1182 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); | |
1183 | |
1184 // TODO(vtl): More. | |
1185 | |
1186 // Close the producer. | |
1187 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(ph)); | |
1188 | |
1189 // The consumer should now be never-readable. | |
1190 hss = kFullMojoHandleSignalsState; | |
1191 EXPECT_EQ( | |
1192 MOJO_RESULT_FAILED_PRECONDITION, | |
1193 core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, MakeUserPointer(&hss))); | |
1194 EXPECT_EQ(0u, hss.satisfied_signals); | |
1195 EXPECT_EQ(0u, hss.satisfiable_signals); | |
1196 | |
1197 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(ch)); | |
1198 } | |
1199 | |
1200 // Tests passing data pipe producer and consumer handles. | |
1201 TEST_F(CoreTest, MessagePipeBasicLocalHandlePassing2) { | |
1202 const char kHello[] = "hello"; | |
1203 const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello)); | |
1204 const char kWorld[] = "world!!!"; | |
1205 const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld)); | |
1206 char buffer[100]; | |
1207 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | |
1208 uint32_t num_bytes; | |
1209 MojoHandle handles[10]; | |
1210 uint32_t num_handles; | |
1211 MojoHandleSignalsState hss; | |
1212 | |
1213 MojoHandle h_passing[2]; | |
1214 EXPECT_EQ(MOJO_RESULT_OK, | |
1215 core()->CreateMessagePipe(NullUserPointer(), | |
1216 MakeUserPointer(&h_passing[0]), | |
1217 MakeUserPointer(&h_passing[1]))); | |
1218 | |
1219 MojoHandle ph, ch; | |
1220 EXPECT_EQ(MOJO_RESULT_OK, | |
1221 core()->CreateDataPipe( | |
1222 NullUserPointer(), MakeUserPointer(&ph), MakeUserPointer(&ch))); | |
1223 | |
1224 // Send |ch| from |h_passing[0]| to |h_passing[1]|. | |
1225 EXPECT_EQ(MOJO_RESULT_OK, | |
1226 core()->WriteMessage(h_passing[0], | |
1227 UserPointer<const void>(kHello), | |
1228 kHelloSize, | |
1229 MakeUserPointer(&ch), | |
1230 1, | |
1231 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
1232 hss = kEmptyMojoHandleSignalsState; | |
1233 EXPECT_EQ(MOJO_RESULT_OK, | |
1234 core()->Wait(h_passing[1], | |
1235 MOJO_HANDLE_SIGNAL_READABLE, | |
1236 1000000000, | |
1237 MakeUserPointer(&hss))); | |
1238 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
1239 hss.satisfied_signals); | |
1240 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
1241 hss.satisfiable_signals); | |
1242 num_bytes = kBufferSize; | |
1243 num_handles = arraysize(handles); | |
1244 EXPECT_EQ(MOJO_RESULT_OK, | |
1245 core()->ReadMessage(h_passing[1], | |
1246 UserPointer<void>(buffer), | |
1247 MakeUserPointer(&num_bytes), | |
1248 MakeUserPointer(handles), | |
1249 MakeUserPointer(&num_handles), | |
1250 MOJO_READ_MESSAGE_FLAG_NONE)); | |
1251 EXPECT_EQ(kHelloSize, num_bytes); | |
1252 EXPECT_STREQ(kHello, buffer); | |
1253 EXPECT_EQ(1u, num_handles); | |
1254 MojoHandle ch_received = handles[0]; | |
1255 EXPECT_NE(ch_received, MOJO_HANDLE_INVALID); | |
1256 EXPECT_NE(ch_received, h_passing[0]); | |
1257 EXPECT_NE(ch_received, h_passing[1]); | |
1258 EXPECT_NE(ch_received, ph); | |
1259 | |
1260 // Note: We rely on the Mojo system not re-using handle values very often. | |
1261 EXPECT_NE(ch_received, ch); | |
1262 | |
1263 // |ch| should no longer be valid; check that trying to close it fails. See | |
1264 // above note. | |
1265 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(ch)); | |
1266 | |
1267 // Write to |ph|. Should receive on |ch_received|. | |
1268 num_bytes = kWorldSize; | |
1269 EXPECT_EQ(MOJO_RESULT_OK, | |
1270 core()->WriteData(ph, | |
1271 UserPointer<const void>(kWorld), | |
1272 MakeUserPointer(&num_bytes), | |
1273 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); | |
1274 hss = kEmptyMojoHandleSignalsState; | |
1275 EXPECT_EQ(MOJO_RESULT_OK, | |
1276 core()->Wait(ch_received, | |
1277 MOJO_HANDLE_SIGNAL_READABLE, | |
1278 1000000000, | |
1279 MakeUserPointer(&hss))); | |
1280 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); | |
1281 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); | |
1282 num_bytes = kBufferSize; | |
1283 EXPECT_EQ(MOJO_RESULT_OK, | |
1284 core()->ReadData(ch_received, | |
1285 UserPointer<void>(buffer), | |
1286 MakeUserPointer(&num_bytes), | |
1287 MOJO_READ_MESSAGE_FLAG_NONE)); | |
1288 EXPECT_EQ(kWorldSize, num_bytes); | |
1289 EXPECT_STREQ(kWorld, buffer); | |
1290 | |
1291 // Now pass |ph| in the same direction. | |
1292 EXPECT_EQ(MOJO_RESULT_OK, | |
1293 core()->WriteMessage(h_passing[0], | |
1294 UserPointer<const void>(kWorld), | |
1295 kWorldSize, | |
1296 MakeUserPointer(&ph), | |
1297 1, | |
1298 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
1299 hss = kEmptyMojoHandleSignalsState; | |
1300 EXPECT_EQ(MOJO_RESULT_OK, | |
1301 core()->Wait(h_passing[1], | |
1302 MOJO_HANDLE_SIGNAL_READABLE, | |
1303 1000000000, | |
1304 MakeUserPointer(&hss))); | |
1305 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
1306 hss.satisfied_signals); | |
1307 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
1308 hss.satisfiable_signals); | |
1309 num_bytes = kBufferSize; | |
1310 num_handles = arraysize(handles); | |
1311 EXPECT_EQ(MOJO_RESULT_OK, | |
1312 core()->ReadMessage(h_passing[1], | |
1313 UserPointer<void>(buffer), | |
1314 MakeUserPointer(&num_bytes), | |
1315 MakeUserPointer(handles), | |
1316 MakeUserPointer(&num_handles), | |
1317 MOJO_READ_MESSAGE_FLAG_NONE)); | |
1318 EXPECT_EQ(kWorldSize, num_bytes); | |
1319 EXPECT_STREQ(kWorld, buffer); | |
1320 EXPECT_EQ(1u, num_handles); | |
1321 MojoHandle ph_received = handles[0]; | |
1322 EXPECT_NE(ph_received, MOJO_HANDLE_INVALID); | |
1323 EXPECT_NE(ph_received, h_passing[0]); | |
1324 EXPECT_NE(ph_received, h_passing[1]); | |
1325 EXPECT_NE(ph_received, ch_received); | |
1326 | |
1327 // Again, rely on the Mojo system not re-using handle values very often. | |
1328 EXPECT_NE(ph_received, ph); | |
1329 | |
1330 // |ph| should no longer be valid; check that trying to close it fails. See | |
1331 // above note. | |
1332 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(ph)); | |
1333 | |
1334 // Write to |ph_received|. Should receive on |ch_received|. | |
1335 num_bytes = kHelloSize; | |
1336 EXPECT_EQ(MOJO_RESULT_OK, | |
1337 core()->WriteData(ph_received, | |
1338 UserPointer<const void>(kHello), | |
1339 MakeUserPointer(&num_bytes), | |
1340 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); | |
1341 hss = kEmptyMojoHandleSignalsState; | |
1342 EXPECT_EQ(MOJO_RESULT_OK, | |
1343 core()->Wait(ch_received, | |
1344 MOJO_HANDLE_SIGNAL_READABLE, | |
1345 1000000000, | |
1346 MakeUserPointer(&hss))); | |
1347 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); | |
1348 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); | |
1349 num_bytes = kBufferSize; | |
1350 EXPECT_EQ(MOJO_RESULT_OK, | |
1351 core()->ReadData(ch_received, | |
1352 UserPointer<void>(buffer), | |
1353 MakeUserPointer(&num_bytes), | |
1354 MOJO_READ_MESSAGE_FLAG_NONE)); | |
1355 EXPECT_EQ(kHelloSize, num_bytes); | |
1356 EXPECT_STREQ(kHello, buffer); | |
1357 | |
1358 ph = ph_received; | |
1359 ph_received = MOJO_HANDLE_INVALID; | |
1360 ch = ch_received; | |
1361 ch_received = MOJO_HANDLE_INVALID; | |
1362 | |
1363 // Make sure that |ph| can't be sent if it's in a two-phase write. | |
1364 void* write_ptr = nullptr; | |
1365 num_bytes = 0; | |
1366 ASSERT_EQ(MOJO_RESULT_OK, | |
1367 core()->BeginWriteData(ph, | |
1368 MakeUserPointer(&write_ptr), | |
1369 MakeUserPointer(&num_bytes), | |
1370 MOJO_WRITE_DATA_FLAG_NONE)); | |
1371 ASSERT_GE(num_bytes, 1u); | |
1372 EXPECT_EQ(MOJO_RESULT_BUSY, | |
1373 core()->WriteMessage(h_passing[0], | |
1374 UserPointer<const void>(kHello), | |
1375 kHelloSize, | |
1376 MakeUserPointer(&ph), | |
1377 1, | |
1378 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
1379 | |
1380 // But |ch| can, even if |ph| is in a two-phase write. | |
1381 EXPECT_EQ(MOJO_RESULT_OK, | |
1382 core()->WriteMessage(h_passing[0], | |
1383 UserPointer<const void>(kHello), | |
1384 kHelloSize, | |
1385 MakeUserPointer(&ch), | |
1386 1, | |
1387 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
1388 ch = MOJO_HANDLE_INVALID; | |
1389 EXPECT_EQ(MOJO_RESULT_OK, | |
1390 core()->Wait(h_passing[1], | |
1391 MOJO_HANDLE_SIGNAL_READABLE, | |
1392 1000000000, | |
1393 NullUserPointer())); | |
1394 num_bytes = kBufferSize; | |
1395 num_handles = arraysize(handles); | |
1396 EXPECT_EQ(MOJO_RESULT_OK, | |
1397 core()->ReadMessage(h_passing[1], | |
1398 UserPointer<void>(buffer), | |
1399 MakeUserPointer(&num_bytes), | |
1400 MakeUserPointer(handles), | |
1401 MakeUserPointer(&num_handles), | |
1402 MOJO_READ_MESSAGE_FLAG_NONE)); | |
1403 EXPECT_EQ(kHelloSize, num_bytes); | |
1404 EXPECT_STREQ(kHello, buffer); | |
1405 EXPECT_EQ(1u, num_handles); | |
1406 ch = handles[0]; | |
1407 EXPECT_NE(ch, MOJO_HANDLE_INVALID); | |
1408 | |
1409 // Complete the two-phase write. | |
1410 static_cast<char*>(write_ptr)[0] = 'x'; | |
1411 EXPECT_EQ(MOJO_RESULT_OK, core()->EndWriteData(ph, 1)); | |
1412 | |
1413 // Wait for |ch| to be readable. | |
1414 hss = kEmptyMojoHandleSignalsState; | |
1415 EXPECT_EQ( | |
1416 MOJO_RESULT_OK, | |
1417 core()->Wait( | |
1418 ch, MOJO_HANDLE_SIGNAL_READABLE, 1000000000, MakeUserPointer(&hss))); | |
1419 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); | |
1420 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); | |
1421 | |
1422 // Make sure that |ch| can't be sent if it's in a two-phase read. | |
1423 const void* read_ptr = nullptr; | |
1424 num_bytes = 1; | |
1425 ASSERT_EQ(MOJO_RESULT_OK, | |
1426 core()->BeginReadData(ch, | |
1427 MakeUserPointer(&read_ptr), | |
1428 MakeUserPointer(&num_bytes), | |
1429 MOJO_READ_DATA_FLAG_ALL_OR_NONE)); | |
1430 EXPECT_EQ(MOJO_RESULT_BUSY, | |
1431 core()->WriteMessage(h_passing[0], | |
1432 UserPointer<const void>(kHello), | |
1433 kHelloSize, | |
1434 MakeUserPointer(&ch), | |
1435 1, | |
1436 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
1437 | |
1438 // But |ph| can, even if |ch| is in a two-phase read. | |
1439 EXPECT_EQ(MOJO_RESULT_OK, | |
1440 core()->WriteMessage(h_passing[0], | |
1441 UserPointer<const void>(kWorld), | |
1442 kWorldSize, | |
1443 MakeUserPointer(&ph), | |
1444 1, | |
1445 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
1446 ph = MOJO_HANDLE_INVALID; | |
1447 hss = kEmptyMojoHandleSignalsState; | |
1448 EXPECT_EQ(MOJO_RESULT_OK, | |
1449 core()->Wait(h_passing[1], | |
1450 MOJO_HANDLE_SIGNAL_READABLE, | |
1451 1000000000, | |
1452 MakeUserPointer(&hss))); | |
1453 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
1454 hss.satisfied_signals); | |
1455 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
1456 hss.satisfiable_signals); | |
1457 num_bytes = kBufferSize; | |
1458 num_handles = arraysize(handles); | |
1459 EXPECT_EQ(MOJO_RESULT_OK, | |
1460 core()->ReadMessage(h_passing[1], | |
1461 UserPointer<void>(buffer), | |
1462 MakeUserPointer(&num_bytes), | |
1463 MakeUserPointer(handles), | |
1464 MakeUserPointer(&num_handles), | |
1465 MOJO_READ_MESSAGE_FLAG_NONE)); | |
1466 EXPECT_EQ(kWorldSize, num_bytes); | |
1467 EXPECT_STREQ(kWorld, buffer); | |
1468 EXPECT_EQ(1u, num_handles); | |
1469 ph = handles[0]; | |
1470 EXPECT_NE(ph, MOJO_HANDLE_INVALID); | |
1471 | |
1472 // Complete the two-phase read. | |
1473 EXPECT_EQ('x', static_cast<const char*>(read_ptr)[0]); | |
1474 EXPECT_EQ(MOJO_RESULT_OK, core()->EndReadData(ch, 1)); | |
1475 | |
1476 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[0])); | |
1477 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[1])); | |
1478 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(ph)); | |
1479 EXPECT_EQ(MOJO_RESULT_OK, core()->Close(ch)); | |
1480 } | |
1481 | |
1482 // TODO(vtl): Test |DuplicateBufferHandle()| and |MapBuffer()|. | |
1483 | |
1484 } // namespace | |
1485 } // namespace system | |
1486 } // namespace mojo | |
OLD | NEW |