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