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/core/core.h"
6
7 #include <stdint.h>
8
9 #include <limits>
10
11 #include "base/bind.h"
12 #include "build/build_config.h"
13 #include "mojo/core/core_test_base.h"
14 #include "mojo/core/test_utils.h"
15 #include "mojo/public/cpp/system/wait.h"
16
17 #if defined(OS_WIN)
18 #include "base/win/windows_version.h"
19 #endif
20
21 namespace mojo {
22 namespace core {
23 namespace {
24
25 const MojoHandleSignalsState kEmptyMojoHandleSignalsState = {0u, 0u};
26 const MojoHandleSignalsState kFullMojoHandleSignalsState = {~0u, ~0u};
27 const MojoHandleSignals kAllSignals =
28 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE |
29 MOJO_HANDLE_SIGNAL_PEER_CLOSED | MOJO_HANDLE_SIGNAL_PEER_REMOTE |
30 MOJO_HANDLE_SIGNAL_QUOTA_EXCEEDED;
31
32 using CoreTest = test::CoreTestBase;
33
TEST_F(CoreTest,GetTimeTicksNow)34 TEST_F(CoreTest, GetTimeTicksNow) {
35 const MojoTimeTicks start = core()->GetTimeTicksNow();
36 ASSERT_NE(static_cast<MojoTimeTicks>(0), start)
37 << "GetTimeTicksNow should return nonzero value";
38 test::Sleep(test::DeadlineFromMilliseconds(15));
39 const MojoTimeTicks finish = core()->GetTimeTicksNow();
40 // Allow for some fuzz in sleep.
41 ASSERT_GE((finish - start), static_cast<MojoTimeTicks>(8000))
42 << "Sleeping should result in increasing time ticks";
43 }
44
TEST_F(CoreTest,Basic)45 TEST_F(CoreTest, Basic) {
46 MockHandleInfo info;
47
48 ASSERT_EQ(0u, info.GetCtorCallCount());
49 MojoHandle h = CreateMockHandle(&info);
50 ASSERT_EQ(1u, info.GetCtorCallCount());
51 ASSERT_NE(h, MOJO_HANDLE_INVALID);
52
53 ASSERT_EQ(0u, info.GetWriteMessageCallCount());
54 MojoMessageHandle message;
55 ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(nullptr, &message));
56 ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h, message, nullptr));
57 ASSERT_EQ(1u, info.GetWriteMessageCallCount());
58
59 ASSERT_EQ(0u, info.GetReadMessageCallCount());
60 ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage(h, nullptr, &message));
61 ASSERT_EQ(1u, info.GetReadMessageCallCount());
62 ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage(h, nullptr, &message));
63 ASSERT_EQ(2u, info.GetReadMessageCallCount());
64
65 ASSERT_EQ(0u, info.GetWriteDataCallCount());
66 ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
67 core()->WriteData(h, nullptr, nullptr, nullptr));
68 ASSERT_EQ(1u, info.GetWriteDataCallCount());
69
70 ASSERT_EQ(0u, info.GetBeginWriteDataCallCount());
71 ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
72 core()->BeginWriteData(h, nullptr, nullptr, nullptr));
73 ASSERT_EQ(1u, info.GetBeginWriteDataCallCount());
74
75 ASSERT_EQ(0u, info.GetEndWriteDataCallCount());
76 ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndWriteData(h, 0, nullptr));
77 ASSERT_EQ(1u, info.GetEndWriteDataCallCount());
78
79 ASSERT_EQ(0u, info.GetReadDataCallCount());
80 ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
81 core()->ReadData(h, nullptr, nullptr, nullptr));
82 ASSERT_EQ(1u, info.GetReadDataCallCount());
83
84 ASSERT_EQ(0u, info.GetBeginReadDataCallCount());
85 ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
86 core()->BeginReadData(h, nullptr, nullptr, nullptr));
87 ASSERT_EQ(1u, info.GetBeginReadDataCallCount());
88
89 ASSERT_EQ(0u, info.GetEndReadDataCallCount());
90 ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndReadData(h, 0, nullptr));
91 ASSERT_EQ(1u, info.GetEndReadDataCallCount());
92
93 ASSERT_EQ(0u, info.GetDtorCallCount());
94 ASSERT_EQ(0u, info.GetCloseCallCount());
95 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
96 ASSERT_EQ(1u, info.GetCloseCallCount());
97 ASSERT_EQ(1u, info.GetDtorCallCount());
98 }
99
TEST_F(CoreTest,InvalidArguments)100 TEST_F(CoreTest, InvalidArguments) {
101 // |Close()|:
102 {
103 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(MOJO_HANDLE_INVALID));
104 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(10));
105 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(1000000000));
106
107 // Test a double-close.
108 MockHandleInfo info;
109 MojoHandle h = CreateMockHandle(&info);
110 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
111 ASSERT_EQ(1u, info.GetCloseCallCount());
112 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(h));
113 ASSERT_EQ(1u, info.GetCloseCallCount());
114 }
115
116 // |CreateMessagePipe()|: Nothing to check (apart from things that cause
117 // death).
118
119 // |WriteMessageNew()|:
120 // Only check arguments checked by |Core|, namely |handle|, |handles|, and
121 // |num_handles|.
122 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
123 core()->WriteMessage(MOJO_HANDLE_INVALID, 0, nullptr));
124
125 // |ReadMessageNew()|:
126 // Only check arguments checked by |Core|, namely |handle|, |handles|, and
127 // |num_handles|.
128 {
129 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
130 core()->ReadMessage(MOJO_HANDLE_INVALID, nullptr, nullptr));
131
132 MockHandleInfo info;
133 MojoHandle h = CreateMockHandle(&info);
134 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
135 core()->ReadMessage(h, nullptr, nullptr));
136 // Checked by |Core|, shouldn't go through to the dispatcher.
137 ASSERT_EQ(0u, info.GetReadMessageCallCount());
138 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
139 }
140 }
141
TEST_F(CoreTest,MessagePipe)142 TEST_F(CoreTest, MessagePipe) {
143 MojoHandle h[2];
144 MojoHandleSignalsState hss[2];
145
146 ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessagePipe(nullptr, &h[0], &h[1]));
147 // Should get two distinct, valid handles.
148 ASSERT_NE(h[0], MOJO_HANDLE_INVALID);
149 ASSERT_NE(h[1], MOJO_HANDLE_INVALID);
150 ASSERT_NE(h[0], h[1]);
151
152 // Neither should be readable.
153 hss[0] = kEmptyMojoHandleSignalsState;
154 hss[1] = kEmptyMojoHandleSignalsState;
155 EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(h[0], &hss[0]));
156 EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(h[1], &hss[1]));
157 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
158 ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
159 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals);
160 ASSERT_EQ(kAllSignals, hss[1].satisfiable_signals);
161
162 // Try to read anyway.
163 MojoMessageHandle message;
164 ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT,
165 core()->ReadMessage(h[0], nullptr, &message));
166
167 // Write to |h[1]|.
168 const uintptr_t kTestMessageContext = 123;
169 ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(nullptr, &message));
170 ASSERT_EQ(MOJO_RESULT_OK,
171 core()->SetMessageContext(message, kTestMessageContext, nullptr,
172 nullptr, nullptr));
173 ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h[1], message, nullptr));
174
175 // Wait for |h[0]| to become readable.
176 EXPECT_EQ(MOJO_RESULT_OK, mojo::Wait(mojo::Handle(h[0]),
177 MOJO_HANDLE_SIGNAL_READABLE, &hss[0]));
178
179 // Read from |h[0]|.
180 ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage(h[0], nullptr, &message));
181 uintptr_t context;
182 ASSERT_EQ(MOJO_RESULT_OK,
183 core()->GetMessageContext(message, nullptr, &context));
184 ASSERT_EQ(MOJO_RESULT_OK,
185 core()->SetMessageContext(message, 0, nullptr, nullptr, nullptr));
186 ASSERT_EQ(kTestMessageContext, context);
187 ASSERT_EQ(MOJO_RESULT_OK, core()->DestroyMessage(message));
188
189 // |h[0]| should no longer be readable.
190 hss[0] = kEmptyMojoHandleSignalsState;
191 EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(h[0], &hss[0]));
192 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
193 ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
194
195 // Write to |h[0]|.
196 ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(nullptr, &message));
197 ASSERT_EQ(MOJO_RESULT_OK,
198 core()->SetMessageContext(message, kTestMessageContext, nullptr,
199 nullptr, nullptr));
200 ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h[0], message, nullptr));
201
202 // Close |h[0]|.
203 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h[0]));
204
205 // Wait for |h[1]| to learn about the other end's closure.
206 EXPECT_EQ(
207 MOJO_RESULT_OK,
208 mojo::Wait(mojo::Handle(h[1]), MOJO_HANDLE_SIGNAL_PEER_CLOSED, &hss[1]));
209
210 // Check that |h[1]| is no longer writable (and will never be).
211 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
212 hss[1].satisfied_signals);
213 EXPECT_FALSE(hss[1].satisfiable_signals & MOJO_HANDLE_SIGNAL_WRITABLE);
214
215 // Check that |h[1]| is still readable (for the moment).
216 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
217 hss[1].satisfied_signals);
218 EXPECT_TRUE(hss[1].satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE);
219
220 // Discard a message from |h[1]|.
221 ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage(h[1], nullptr, &message));
222 ASSERT_EQ(MOJO_RESULT_OK, core()->DestroyMessage(message));
223
224 // |h[1]| is no longer readable (and will never be).
225 hss[1] = kFullMojoHandleSignalsState;
226 EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(h[1], &hss[1]));
227 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss[1].satisfied_signals);
228 EXPECT_FALSE(hss[1].satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE);
229
230 // Try writing to |h[1]|.
231 ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(nullptr, &message));
232 ASSERT_EQ(MOJO_RESULT_OK,
233 core()->SetMessageContext(message, kTestMessageContext, nullptr,
234 nullptr, nullptr));
235 ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
236 core()->WriteMessage(h[1], message, nullptr));
237
238 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h[1]));
239 }
240
241 // Tests passing a message pipe handle.
TEST_F(CoreTest,MessagePipeBasicLocalHandlePassing1)242 TEST_F(CoreTest, MessagePipeBasicLocalHandlePassing1) {
243 MojoHandleSignalsState hss;
244 MojoHandle h_passing[2];
245 ASSERT_EQ(MOJO_RESULT_OK,
246 core()->CreateMessagePipe(nullptr, &h_passing[0], &h_passing[1]));
247
248 // Make sure that |h_passing[]| work properly.
249 const uintptr_t kTestMessageContext = 42;
250 MojoMessageHandle message;
251 ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(nullptr, &message));
252 ASSERT_EQ(MOJO_RESULT_OK,
253 core()->SetMessageContext(message, kTestMessageContext, nullptr,
254 nullptr, nullptr));
255 ASSERT_EQ(MOJO_RESULT_OK,
256 core()->WriteMessage(h_passing[0], message, nullptr));
257 hss = kEmptyMojoHandleSignalsState;
258 EXPECT_EQ(MOJO_RESULT_OK, mojo::Wait(mojo::Handle(h_passing[1]),
259 MOJO_HANDLE_SIGNAL_READABLE, &hss));
260 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
261 hss.satisfied_signals);
262 ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
263 MojoMessageHandle message_handle;
264 ASSERT_EQ(MOJO_RESULT_OK,
265 core()->ReadMessage(h_passing[1], nullptr, &message_handle));
266 uintptr_t context;
267 ASSERT_EQ(MOJO_RESULT_OK,
268 core()->GetMessageContext(message_handle, nullptr, &context));
269 ASSERT_EQ(MOJO_RESULT_OK,
270 core()->SetMessageContext(message, 0, nullptr, nullptr, nullptr));
271 ASSERT_EQ(kTestMessageContext, context);
272 ASSERT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message_handle));
273
274 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[0]));
275 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[1]));
276 }
277
TEST_F(CoreTest,DataPipe)278 TEST_F(CoreTest, DataPipe) {
279 MojoHandle ph, ch; // p is for producer and c is for consumer.
280 MojoHandleSignalsState hss;
281
282 ASSERT_EQ(MOJO_RESULT_OK, core()->CreateDataPipe(nullptr, &ph, &ch));
283 // Should get two distinct, valid handles.
284 ASSERT_NE(ph, MOJO_HANDLE_INVALID);
285 ASSERT_NE(ch, MOJO_HANDLE_INVALID);
286 ASSERT_NE(ph, ch);
287
288 // Producer should be never-readable, but already writable.
289 hss = kEmptyMojoHandleSignalsState;
290 EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(ph, &hss));
291 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
292 ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
293 MOJO_HANDLE_SIGNAL_PEER_REMOTE,
294 hss.satisfiable_signals);
295
296 // Consumer should be never-writable, and not yet readable.
297 hss = kFullMojoHandleSignalsState;
298 EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(ch, &hss));
299 EXPECT_EQ(0u, hss.satisfied_signals);
300 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
301 MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE |
302 MOJO_HANDLE_SIGNAL_PEER_REMOTE,
303 hss.satisfiable_signals);
304
305 // Write.
306 signed char elements[2] = {'A', 'B'};
307 uint32_t num_bytes = 2u;
308 ASSERT_EQ(MOJO_RESULT_OK,
309 core()->WriteData(ph, elements, &num_bytes, nullptr));
310 ASSERT_EQ(2u, num_bytes);
311
312 // Wait for the data to arrive to the consumer.
313 EXPECT_EQ(MOJO_RESULT_OK,
314 mojo::Wait(mojo::Handle(ch), MOJO_HANDLE_SIGNAL_READABLE, &hss));
315
316 // Consumer should now be readable.
317 hss = kEmptyMojoHandleSignalsState;
318 EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(ch, &hss));
319 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
320 hss.satisfied_signals);
321 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
322 MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE |
323 MOJO_HANDLE_SIGNAL_PEER_REMOTE,
324 hss.satisfiable_signals);
325
326 // Peek one character.
327 elements[0] = -1;
328 elements[1] = -1;
329 num_bytes = 1u;
330 MojoReadDataOptions read_options;
331 read_options.struct_size = sizeof(read_options);
332 read_options.flags = MOJO_READ_DATA_FLAG_NONE | MOJO_READ_DATA_FLAG_PEEK;
333 ASSERT_EQ(MOJO_RESULT_OK,
334 core()->ReadData(ch, &read_options, elements, &num_bytes));
335 ASSERT_EQ('A', elements[0]);
336 ASSERT_EQ(-1, elements[1]);
337
338 // Read one character.
339 elements[0] = -1;
340 elements[1] = -1;
341 num_bytes = 1u;
342 read_options.flags = MOJO_READ_DATA_FLAG_NONE;
343 ASSERT_EQ(MOJO_RESULT_OK,
344 core()->ReadData(ch, &read_options, elements, &num_bytes));
345 ASSERT_EQ('A', elements[0]);
346 ASSERT_EQ(-1, elements[1]);
347
348 // Two-phase write.
349 void* write_ptr = nullptr;
350 num_bytes = 0u;
351 ASSERT_EQ(MOJO_RESULT_OK,
352 core()->BeginWriteData(ph, nullptr, &write_ptr, &num_bytes));
353 // We count on the default options providing a decent buffer size.
354 ASSERT_GE(num_bytes, 3u);
355
356 // Trying to do a normal write during a two-phase write should fail.
357 elements[0] = 'X';
358 num_bytes = 1u;
359 ASSERT_EQ(MOJO_RESULT_BUSY,
360 core()->WriteData(ph, elements, &num_bytes, nullptr));
361
362 // Actually write the data, and complete it now.
363 static_cast<char*>(write_ptr)[0] = 'C';
364 static_cast<char*>(write_ptr)[1] = 'D';
365 static_cast<char*>(write_ptr)[2] = 'E';
366 ASSERT_EQ(MOJO_RESULT_OK, core()->EndWriteData(ph, 3u, nullptr));
367
368 // Wait for the data to arrive to the consumer.
369 ASSERT_EQ(MOJO_RESULT_OK,
370 mojo::Wait(mojo::Handle(ch), MOJO_HANDLE_SIGNAL_READABLE, &hss));
371
372 // Query how much data we have.
373 num_bytes = 0;
374 read_options.flags = MOJO_READ_DATA_FLAG_QUERY;
375 ASSERT_EQ(MOJO_RESULT_OK,
376 core()->ReadData(ch, &read_options, nullptr, &num_bytes));
377 ASSERT_GE(num_bytes, 1u);
378
379 // Try to query with peek. Should fail.
380 num_bytes = 0;
381 read_options.flags = MOJO_READ_DATA_FLAG_QUERY | MOJO_READ_DATA_FLAG_PEEK;
382 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
383 core()->ReadData(ch, &read_options, nullptr, &num_bytes));
384 ASSERT_EQ(0u, num_bytes);
385
386 // Try to discard ten characters, in all-or-none mode. Should fail.
387 num_bytes = 10;
388 read_options.flags =
389 MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE;
390 ASSERT_EQ(MOJO_RESULT_OUT_OF_RANGE,
391 core()->ReadData(ch, &read_options, nullptr, &num_bytes));
392
393 // Try to discard two characters, in peek mode. Should fail.
394 num_bytes = 2;
395 read_options.flags = MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_PEEK;
396 ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
397 core()->ReadData(ch, &read_options, nullptr, &num_bytes));
398
399 // Discard a character.
400 num_bytes = 1;
401 read_options.flags =
402 MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE;
403 ASSERT_EQ(MOJO_RESULT_OK,
404 core()->ReadData(ch, &read_options, nullptr, &num_bytes));
405
406 // Ensure the 3 bytes were read.
407 ASSERT_EQ(MOJO_RESULT_OK,
408 mojo::Wait(mojo::Handle(ch), MOJO_HANDLE_SIGNAL_READABLE, &hss));
409
410 // Read the remaining three characters, in two-phase mode.
411 const void* read_ptr = nullptr;
412 num_bytes = 3;
413 ASSERT_EQ(MOJO_RESULT_OK,
414 core()->BeginReadData(ch, nullptr, &read_ptr, &num_bytes));
415 // Note: Count on still being able to do the contiguous read here.
416 ASSERT_EQ(3u, num_bytes);
417
418 // Discarding right now should fail.
419 num_bytes = 1;
420 read_options.flags = MOJO_READ_DATA_FLAG_DISCARD;
421 ASSERT_EQ(MOJO_RESULT_BUSY,
422 core()->ReadData(ch, &read_options, nullptr, &num_bytes));
423
424 // Actually check our data and end the two-phase read.
425 ASSERT_EQ('C', static_cast<const char*>(read_ptr)[0]);
426 ASSERT_EQ('D', static_cast<const char*>(read_ptr)[1]);
427 ASSERT_EQ('E', static_cast<const char*>(read_ptr)[2]);
428 ASSERT_EQ(MOJO_RESULT_OK, core()->EndReadData(ch, 3u, nullptr));
429
430 // Consumer should now be no longer readable.
431 hss = kFullMojoHandleSignalsState;
432 EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(ch, &hss));
433 EXPECT_EQ(0u, hss.satisfied_signals);
434 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
435 MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE |
436 MOJO_HANDLE_SIGNAL_PEER_REMOTE,
437 hss.satisfiable_signals);
438
439 // TODO(vtl): More.
440
441 // Close the producer.
442 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ph));
443
444 // Wait for this to get to the consumer.
445 EXPECT_EQ(MOJO_RESULT_OK,
446 mojo::Wait(mojo::Handle(ch), MOJO_HANDLE_SIGNAL_PEER_CLOSED, &hss));
447
448 // The consumer should now be never-readable.
449 hss = kFullMojoHandleSignalsState;
450 EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(ch, &hss));
451 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
452 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
453
454 ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ch));
455 }
456
457 } // namespace
458 } // namespace core
459 } // namespace mojo
460