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/message_pipe.h" | |
6 | |
7 #include "base/memory/ref_counted.h" | |
8 #include "base/threading/platform_thread.h" // For |Sleep()|. | |
9 #include "base/time/time.h" | |
10 #include "mojo/edk/system/waiter.h" | |
11 #include "mojo/edk/system/waiter_test_utils.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 | |
14 namespace mojo { | |
15 namespace system { | |
16 namespace { | |
17 | |
18 // Tests: | |
19 // - only default flags | |
20 // - reading messages from a port | |
21 // - when there are no/one/two messages available for that port | |
22 // - with buffer size 0 (and null buffer) -- should get size | |
23 // - with too-small buffer -- should get size | |
24 // - also verify that buffers aren't modified when/where they shouldn't be | |
25 // - writing messages to a port | |
26 // - in the obvious scenarios (as above) | |
27 // - to a port that's been closed | |
28 // - writing a message to a port, closing the other (would be the source) port, | |
29 // and reading it | |
30 TEST(MessagePipeTest, Basic) { | |
31 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | |
32 | |
33 int32_t buffer[2]; | |
34 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | |
35 uint32_t buffer_size; | |
36 | |
37 // Nothing to read yet on port 0. | |
38 buffer[0] = 123; | |
39 buffer[1] = 456; | |
40 buffer_size = kBufferSize; | |
41 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
42 mp->ReadMessage(0, | |
43 UserPointer<void>(buffer), | |
44 MakeUserPointer(&buffer_size), | |
45 0, | |
46 nullptr, | |
47 MOJO_READ_MESSAGE_FLAG_NONE)); | |
48 EXPECT_EQ(kBufferSize, buffer_size); | |
49 EXPECT_EQ(123, buffer[0]); | |
50 EXPECT_EQ(456, buffer[1]); | |
51 | |
52 // Ditto for port 1. | |
53 buffer[0] = 123; | |
54 buffer[1] = 456; | |
55 buffer_size = kBufferSize; | |
56 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
57 mp->ReadMessage(1, | |
58 UserPointer<void>(buffer), | |
59 MakeUserPointer(&buffer_size), | |
60 0, | |
61 nullptr, | |
62 MOJO_READ_MESSAGE_FLAG_NONE)); | |
63 | |
64 // Write from port 1 (to port 0). | |
65 buffer[0] = 789012345; | |
66 buffer[1] = 0; | |
67 EXPECT_EQ(MOJO_RESULT_OK, | |
68 mp->WriteMessage(1, | |
69 UserPointer<const void>(buffer), | |
70 static_cast<uint32_t>(sizeof(buffer[0])), | |
71 nullptr, | |
72 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
73 | |
74 // Read from port 0. | |
75 buffer[0] = 123; | |
76 buffer[1] = 456; | |
77 buffer_size = kBufferSize; | |
78 EXPECT_EQ(MOJO_RESULT_OK, | |
79 mp->ReadMessage(0, | |
80 UserPointer<void>(buffer), | |
81 MakeUserPointer(&buffer_size), | |
82 0, | |
83 nullptr, | |
84 MOJO_READ_MESSAGE_FLAG_NONE)); | |
85 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
86 EXPECT_EQ(789012345, buffer[0]); | |
87 EXPECT_EQ(456, buffer[1]); | |
88 | |
89 // Read again from port 0 -- it should be empty. | |
90 buffer_size = kBufferSize; | |
91 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
92 mp->ReadMessage(0, | |
93 UserPointer<void>(buffer), | |
94 MakeUserPointer(&buffer_size), | |
95 0, | |
96 nullptr, | |
97 MOJO_READ_MESSAGE_FLAG_NONE)); | |
98 | |
99 // Write two messages from port 0 (to port 1). | |
100 buffer[0] = 123456789; | |
101 buffer[1] = 0; | |
102 EXPECT_EQ(MOJO_RESULT_OK, | |
103 mp->WriteMessage(0, | |
104 UserPointer<const void>(buffer), | |
105 static_cast<uint32_t>(sizeof(buffer[0])), | |
106 nullptr, | |
107 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
108 buffer[0] = 234567890; | |
109 buffer[1] = 0; | |
110 EXPECT_EQ(MOJO_RESULT_OK, | |
111 mp->WriteMessage(0, | |
112 UserPointer<const void>(buffer), | |
113 static_cast<uint32_t>(sizeof(buffer[0])), | |
114 nullptr, | |
115 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
116 | |
117 // Read from port 1 with buffer size 0 (should get the size of next message). | |
118 // Also test that giving a null buffer is okay when the buffer size is 0. | |
119 buffer_size = 0; | |
120 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, | |
121 mp->ReadMessage(1, | |
122 NullUserPointer(), | |
123 MakeUserPointer(&buffer_size), | |
124 0, | |
125 nullptr, | |
126 MOJO_READ_MESSAGE_FLAG_NONE)); | |
127 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
128 | |
129 // Read from port 1 with buffer size 1 (too small; should get the size of next | |
130 // message). | |
131 buffer[0] = 123; | |
132 buffer[1] = 456; | |
133 buffer_size = 1; | |
134 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, | |
135 mp->ReadMessage(1, | |
136 UserPointer<void>(buffer), | |
137 MakeUserPointer(&buffer_size), | |
138 0, | |
139 nullptr, | |
140 MOJO_READ_MESSAGE_FLAG_NONE)); | |
141 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
142 EXPECT_EQ(123, buffer[0]); | |
143 EXPECT_EQ(456, buffer[1]); | |
144 | |
145 // Read from port 1. | |
146 buffer[0] = 123; | |
147 buffer[1] = 456; | |
148 buffer_size = kBufferSize; | |
149 EXPECT_EQ(MOJO_RESULT_OK, | |
150 mp->ReadMessage(1, | |
151 UserPointer<void>(buffer), | |
152 MakeUserPointer(&buffer_size), | |
153 0, | |
154 nullptr, | |
155 MOJO_READ_MESSAGE_FLAG_NONE)); | |
156 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
157 EXPECT_EQ(123456789, buffer[0]); | |
158 EXPECT_EQ(456, buffer[1]); | |
159 | |
160 // Read again from port 1. | |
161 buffer[0] = 123; | |
162 buffer[1] = 456; | |
163 buffer_size = kBufferSize; | |
164 EXPECT_EQ(MOJO_RESULT_OK, | |
165 mp->ReadMessage(1, | |
166 UserPointer<void>(buffer), | |
167 MakeUserPointer(&buffer_size), | |
168 0, | |
169 nullptr, | |
170 MOJO_READ_MESSAGE_FLAG_NONE)); | |
171 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
172 EXPECT_EQ(234567890, buffer[0]); | |
173 EXPECT_EQ(456, buffer[1]); | |
174 | |
175 // Read again from port 1 -- it should be empty. | |
176 buffer_size = kBufferSize; | |
177 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
178 mp->ReadMessage(1, | |
179 UserPointer<void>(buffer), | |
180 MakeUserPointer(&buffer_size), | |
181 0, | |
182 nullptr, | |
183 MOJO_READ_MESSAGE_FLAG_NONE)); | |
184 | |
185 // Write from port 0 (to port 1). | |
186 buffer[0] = 345678901; | |
187 buffer[1] = 0; | |
188 EXPECT_EQ(MOJO_RESULT_OK, | |
189 mp->WriteMessage(0, | |
190 UserPointer<const void>(buffer), | |
191 static_cast<uint32_t>(sizeof(buffer[0])), | |
192 nullptr, | |
193 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
194 | |
195 // Close port 0. | |
196 mp->Close(0); | |
197 | |
198 // Try to write from port 1 (to port 0). | |
199 buffer[0] = 456789012; | |
200 buffer[1] = 0; | |
201 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
202 mp->WriteMessage(1, | |
203 UserPointer<const void>(buffer), | |
204 static_cast<uint32_t>(sizeof(buffer[0])), | |
205 nullptr, | |
206 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
207 | |
208 // Read from port 1; should still get message (even though port 0 was closed). | |
209 buffer[0] = 123; | |
210 buffer[1] = 456; | |
211 buffer_size = kBufferSize; | |
212 EXPECT_EQ(MOJO_RESULT_OK, | |
213 mp->ReadMessage(1, | |
214 UserPointer<void>(buffer), | |
215 MakeUserPointer(&buffer_size), | |
216 0, | |
217 nullptr, | |
218 MOJO_READ_MESSAGE_FLAG_NONE)); | |
219 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
220 EXPECT_EQ(345678901, buffer[0]); | |
221 EXPECT_EQ(456, buffer[1]); | |
222 | |
223 // Read again from port 1 -- it should be empty (and port 0 is closed). | |
224 buffer_size = kBufferSize; | |
225 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
226 mp->ReadMessage(1, | |
227 UserPointer<void>(buffer), | |
228 MakeUserPointer(&buffer_size), | |
229 0, | |
230 nullptr, | |
231 MOJO_READ_MESSAGE_FLAG_NONE)); | |
232 | |
233 mp->Close(1); | |
234 } | |
235 | |
236 TEST(MessagePipeTest, CloseWithQueuedIncomingMessages) { | |
237 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | |
238 | |
239 int32_t buffer[1]; | |
240 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | |
241 uint32_t buffer_size; | |
242 | |
243 // Write some messages from port 1 (to port 0). | |
244 for (int32_t i = 0; i < 5; i++) { | |
245 buffer[0] = i; | |
246 EXPECT_EQ(MOJO_RESULT_OK, | |
247 mp->WriteMessage(1, | |
248 UserPointer<const void>(buffer), | |
249 kBufferSize, | |
250 nullptr, | |
251 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
252 } | |
253 | |
254 // Port 0 shouldn't be empty. | |
255 buffer_size = 0; | |
256 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, | |
257 mp->ReadMessage(0, | |
258 NullUserPointer(), | |
259 MakeUserPointer(&buffer_size), | |
260 0, | |
261 nullptr, | |
262 MOJO_READ_MESSAGE_FLAG_NONE)); | |
263 EXPECT_EQ(kBufferSize, buffer_size); | |
264 | |
265 // Close port 0 first, which should have outstanding (incoming) messages. | |
266 mp->Close(0); | |
267 mp->Close(1); | |
268 } | |
269 | |
270 TEST(MessagePipeTest, DiscardMode) { | |
271 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | |
272 | |
273 int32_t buffer[2]; | |
274 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | |
275 uint32_t buffer_size; | |
276 | |
277 // Write from port 1 (to port 0). | |
278 buffer[0] = 789012345; | |
279 buffer[1] = 0; | |
280 EXPECT_EQ(MOJO_RESULT_OK, | |
281 mp->WriteMessage(1, | |
282 UserPointer<const void>(buffer), | |
283 static_cast<uint32_t>(sizeof(buffer[0])), | |
284 nullptr, | |
285 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
286 | |
287 // Read/discard from port 0 (no buffer); get size. | |
288 buffer_size = 0; | |
289 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, | |
290 mp->ReadMessage(0, | |
291 NullUserPointer(), | |
292 MakeUserPointer(&buffer_size), | |
293 0, | |
294 nullptr, | |
295 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
296 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
297 | |
298 // Read again from port 0 -- it should be empty. | |
299 buffer_size = kBufferSize; | |
300 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
301 mp->ReadMessage(0, | |
302 UserPointer<void>(buffer), | |
303 MakeUserPointer(&buffer_size), | |
304 0, | |
305 nullptr, | |
306 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
307 | |
308 // Write from port 1 (to port 0). | |
309 buffer[0] = 890123456; | |
310 buffer[1] = 0; | |
311 EXPECT_EQ(MOJO_RESULT_OK, | |
312 mp->WriteMessage(1, | |
313 UserPointer<const void>(buffer), | |
314 static_cast<uint32_t>(sizeof(buffer[0])), | |
315 nullptr, | |
316 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
317 | |
318 // Read from port 0 (buffer big enough). | |
319 buffer[0] = 123; | |
320 buffer[1] = 456; | |
321 buffer_size = kBufferSize; | |
322 EXPECT_EQ(MOJO_RESULT_OK, | |
323 mp->ReadMessage(0, | |
324 UserPointer<void>(buffer), | |
325 MakeUserPointer(&buffer_size), | |
326 0, | |
327 nullptr, | |
328 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
329 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
330 EXPECT_EQ(890123456, buffer[0]); | |
331 EXPECT_EQ(456, buffer[1]); | |
332 | |
333 // Read again from port 0 -- it should be empty. | |
334 buffer_size = kBufferSize; | |
335 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
336 mp->ReadMessage(0, | |
337 UserPointer<void>(buffer), | |
338 MakeUserPointer(&buffer_size), | |
339 0, | |
340 nullptr, | |
341 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
342 | |
343 // Write from port 1 (to port 0). | |
344 buffer[0] = 901234567; | |
345 buffer[1] = 0; | |
346 EXPECT_EQ(MOJO_RESULT_OK, | |
347 mp->WriteMessage(1, | |
348 UserPointer<const void>(buffer), | |
349 static_cast<uint32_t>(sizeof(buffer[0])), | |
350 nullptr, | |
351 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
352 | |
353 // Read/discard from port 0 (buffer too small); get size. | |
354 buffer_size = 1; | |
355 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, | |
356 mp->ReadMessage(0, | |
357 UserPointer<void>(buffer), | |
358 MakeUserPointer(&buffer_size), | |
359 0, | |
360 nullptr, | |
361 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
362 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); | |
363 | |
364 // Read again from port 0 -- it should be empty. | |
365 buffer_size = kBufferSize; | |
366 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
367 mp->ReadMessage(0, | |
368 UserPointer<void>(buffer), | |
369 MakeUserPointer(&buffer_size), | |
370 0, | |
371 nullptr, | |
372 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
373 | |
374 // Write from port 1 (to port 0). | |
375 buffer[0] = 123456789; | |
376 buffer[1] = 0; | |
377 EXPECT_EQ(MOJO_RESULT_OK, | |
378 mp->WriteMessage(1, | |
379 UserPointer<const void>(buffer), | |
380 static_cast<uint32_t>(sizeof(buffer[0])), | |
381 nullptr, | |
382 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
383 | |
384 // Discard from port 0. | |
385 buffer_size = 1; | |
386 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, | |
387 mp->ReadMessage(0, | |
388 NullUserPointer(), | |
389 NullUserPointer(), | |
390 0, | |
391 nullptr, | |
392 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
393 | |
394 // Read again from port 0 -- it should be empty. | |
395 buffer_size = kBufferSize; | |
396 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | |
397 mp->ReadMessage(0, | |
398 UserPointer<void>(buffer), | |
399 MakeUserPointer(&buffer_size), | |
400 0, | |
401 nullptr, | |
402 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | |
403 | |
404 mp->Close(0); | |
405 mp->Close(1); | |
406 } | |
407 | |
408 TEST(MessagePipeTest, BasicWaiting) { | |
409 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | |
410 Waiter waiter; | |
411 HandleSignalsState hss; | |
412 | |
413 int32_t buffer[1]; | |
414 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | |
415 uint32_t buffer_size; | |
416 | |
417 // Always writable (until the other port is closed). | |
418 waiter.Init(); | |
419 hss = HandleSignalsState(); | |
420 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | |
421 mp->AddWaiter(0, &waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss)); | |
422 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); | |
423 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
424 hss.satisfiable_signals); | |
425 waiter.Init(); | |
426 hss = HandleSignalsState(); | |
427 EXPECT_EQ( | |
428 MOJO_RESULT_ALREADY_EXISTS, | |
429 mp->AddWaiter(0, | |
430 &waiter, | |
431 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
432 0, | |
433 &hss)); | |
434 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); | |
435 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
436 hss.satisfiable_signals); | |
437 | |
438 // Not yet readable. | |
439 waiter.Init(); | |
440 ASSERT_EQ(MOJO_RESULT_OK, | |
441 mp->AddWaiter(0, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 1, nullptr)); | |
442 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr)); | |
443 hss = HandleSignalsState(); | |
444 mp->RemoveWaiter(0, &waiter, &hss); | |
445 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); | |
446 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
447 hss.satisfiable_signals); | |
448 | |
449 // Write from port 0 (to port 1), to make port 1 readable. | |
450 buffer[0] = 123456789; | |
451 EXPECT_EQ(MOJO_RESULT_OK, | |
452 mp->WriteMessage(0, | |
453 UserPointer<const void>(buffer), | |
454 kBufferSize, | |
455 nullptr, | |
456 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
457 | |
458 // Port 1 should already be readable now. | |
459 waiter.Init(); | |
460 hss = HandleSignalsState(); | |
461 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | |
462 mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 2, &hss)); | |
463 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
464 hss.satisfied_signals); | |
465 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
466 hss.satisfiable_signals); | |
467 waiter.Init(); | |
468 hss = HandleSignalsState(); | |
469 EXPECT_EQ( | |
470 MOJO_RESULT_ALREADY_EXISTS, | |
471 mp->AddWaiter(1, | |
472 &waiter, | |
473 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
474 0, | |
475 &hss)); | |
476 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
477 hss.satisfied_signals); | |
478 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
479 hss.satisfiable_signals); | |
480 // ... and still writable. | |
481 waiter.Init(); | |
482 hss = HandleSignalsState(); | |
483 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | |
484 mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 3, &hss)); | |
485 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
486 hss.satisfied_signals); | |
487 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
488 hss.satisfiable_signals); | |
489 | |
490 // Close port 0. | |
491 mp->Close(0); | |
492 | |
493 // Now port 1 should not be writable. | |
494 waiter.Init(); | |
495 hss = HandleSignalsState(); | |
496 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
497 mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 4, &hss)); | |
498 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); | |
499 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); | |
500 | |
501 // But it should still be readable. | |
502 waiter.Init(); | |
503 hss = HandleSignalsState(); | |
504 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, | |
505 mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 5, &hss)); | |
506 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); | |
507 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); | |
508 | |
509 // Read from port 1. | |
510 buffer[0] = 0; | |
511 buffer_size = kBufferSize; | |
512 EXPECT_EQ(MOJO_RESULT_OK, | |
513 mp->ReadMessage(1, | |
514 UserPointer<void>(buffer), | |
515 MakeUserPointer(&buffer_size), | |
516 0, | |
517 nullptr, | |
518 MOJO_READ_MESSAGE_FLAG_NONE)); | |
519 EXPECT_EQ(123456789, buffer[0]); | |
520 | |
521 // Now port 1 should no longer be readable. | |
522 waiter.Init(); | |
523 hss = HandleSignalsState(); | |
524 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
525 mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 6, nullptr)); | |
526 EXPECT_EQ(0u, hss.satisfied_signals); | |
527 EXPECT_EQ(0u, hss.satisfiable_signals); | |
528 | |
529 mp->Close(1); | |
530 } | |
531 | |
532 TEST(MessagePipeTest, ThreadedWaiting) { | |
533 int32_t buffer[1]; | |
534 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | |
535 | |
536 MojoResult result; | |
537 uint32_t context; | |
538 | |
539 // Write to wake up waiter waiting for read. | |
540 { | |
541 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | |
542 test::SimpleWaiterThread thread(&result, &context); | |
543 | |
544 thread.waiter()->Init(); | |
545 ASSERT_EQ(MOJO_RESULT_OK, | |
546 mp->AddWaiter( | |
547 1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1, nullptr)); | |
548 thread.Start(); | |
549 | |
550 buffer[0] = 123456789; | |
551 // Write from port 0 (to port 1), which should wake up the waiter. | |
552 EXPECT_EQ(MOJO_RESULT_OK, | |
553 mp->WriteMessage(0, | |
554 UserPointer<const void>(buffer), | |
555 kBufferSize, | |
556 nullptr, | |
557 MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
558 | |
559 HandleSignalsState hss; | |
560 mp->RemoveWaiter(1, thread.waiter(), &hss); | |
561 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
562 hss.satisfied_signals); | |
563 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | |
564 hss.satisfiable_signals); | |
565 | |
566 mp->Close(0); | |
567 mp->Close(1); | |
568 } // Joins |thread|. | |
569 // The waiter should have woken up successfully. | |
570 EXPECT_EQ(MOJO_RESULT_OK, result); | |
571 EXPECT_EQ(1u, context); | |
572 | |
573 // Close to cancel waiter. | |
574 { | |
575 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | |
576 test::SimpleWaiterThread thread(&result, &context); | |
577 | |
578 thread.waiter()->Init(); | |
579 ASSERT_EQ(MOJO_RESULT_OK, | |
580 mp->AddWaiter( | |
581 1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 2, nullptr)); | |
582 thread.Start(); | |
583 | |
584 // Close port 1 first -- this should result in the waiter being cancelled. | |
585 mp->CancelAllWaiters(1); | |
586 mp->Close(1); | |
587 | |
588 // Port 1 is closed, so |Dispatcher::RemoveWaiter()| wouldn't call into the | |
589 // |MessagePipe| to remove any waiter. | |
590 | |
591 mp->Close(0); | |
592 } // Joins |thread|. | |
593 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | |
594 EXPECT_EQ(2u, context); | |
595 | |
596 // Close to make waiter un-wake-up-able. | |
597 { | |
598 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | |
599 test::SimpleWaiterThread thread(&result, &context); | |
600 | |
601 thread.waiter()->Init(); | |
602 ASSERT_EQ(MOJO_RESULT_OK, | |
603 mp->AddWaiter( | |
604 1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3, nullptr)); | |
605 thread.Start(); | |
606 | |
607 // Close port 0 first -- this should wake the waiter up, since port 1 will | |
608 // never be readable. | |
609 mp->CancelAllWaiters(0); | |
610 mp->Close(0); | |
611 | |
612 HandleSignalsState hss; | |
613 mp->RemoveWaiter(1, thread.waiter(), &hss); | |
614 EXPECT_EQ(0u, hss.satisfied_signals); | |
615 EXPECT_EQ(0u, hss.satisfiable_signals); | |
616 | |
617 mp->CancelAllWaiters(1); | |
618 mp->Close(1); | |
619 } // Joins |thread|. | |
620 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | |
621 EXPECT_EQ(3u, context); | |
622 } | |
623 | |
624 } // namespace | |
625 } // namespace system | |
626 } // namespace mojo | |
OLD | NEW |