Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: mojo/edk/system/remote_message_pipe_unittest.cc

Issue 814543006: Move //mojo/{public, edk} underneath //third_party (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/edk/system/raw_channel_win.cc ('k') | mojo/edk/system/run_all_unittests.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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 <stdint.h>
6 #include <stdio.h>
7 #include <string.h>
8
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/files/scoped_file.h"
15 #include "base/files/scoped_temp_dir.h"
16 #include "base/location.h"
17 #include "base/logging.h"
18 #include "base/macros.h"
19 #include "base/message_loop/message_loop.h"
20 #include "base/test/test_io_thread.h"
21 #include "base/threading/platform_thread.h" // For |Sleep()|.
22 #include "build/build_config.h" // TODO(vtl): Remove this.
23 #include "mojo/edk/embedder/platform_channel_pair.h"
24 #include "mojo/edk/embedder/platform_shared_buffer.h"
25 #include "mojo/edk/embedder/scoped_platform_handle.h"
26 #include "mojo/edk/embedder/simple_platform_support.h"
27 #include "mojo/edk/system/channel.h"
28 #include "mojo/edk/system/channel_endpoint.h"
29 #include "mojo/edk/system/channel_endpoint_id.h"
30 #include "mojo/edk/system/incoming_endpoint.h"
31 #include "mojo/edk/system/message_pipe.h"
32 #include "mojo/edk/system/message_pipe_dispatcher.h"
33 #include "mojo/edk/system/platform_handle_dispatcher.h"
34 #include "mojo/edk/system/raw_channel.h"
35 #include "mojo/edk/system/shared_buffer_dispatcher.h"
36 #include "mojo/edk/system/test_utils.h"
37 #include "mojo/edk/system/waiter.h"
38 #include "mojo/edk/test/test_utils.h"
39 #include "testing/gtest/include/gtest/gtest.h"
40
41 namespace mojo {
42 namespace system {
43 namespace {
44
45 const MojoHandleSignals kAllSignals = MOJO_HANDLE_SIGNAL_READABLE |
46 MOJO_HANDLE_SIGNAL_WRITABLE |
47 MOJO_HANDLE_SIGNAL_PEER_CLOSED;
48
49 class RemoteMessagePipeTest : public testing::Test {
50 public:
51 RemoteMessagePipeTest() : io_thread_(base::TestIOThread::kAutoStart) {}
52 ~RemoteMessagePipeTest() override {}
53
54 void SetUp() override {
55 io_thread_.PostTaskAndWait(
56 FROM_HERE, base::Bind(&RemoteMessagePipeTest::SetUpOnIOThread,
57 base::Unretained(this)));
58 }
59
60 void TearDown() override {
61 io_thread_.PostTaskAndWait(
62 FROM_HERE, base::Bind(&RemoteMessagePipeTest::TearDownOnIOThread,
63 base::Unretained(this)));
64 }
65
66 protected:
67 // This connects the two given |ChannelEndpoint|s. It assumes/requires that
68 // this is the bootstrap case (i.e., no other message pipes have ever been
69 // hosted on the channel).
70 void BootstrapChannelEndpoints(scoped_refptr<ChannelEndpoint> ep0,
71 scoped_refptr<ChannelEndpoint> ep1) {
72 io_thread_.PostTaskAndWait(
73 FROM_HERE,
74 base::Bind(&RemoteMessagePipeTest::BootstrapChannelEndpointsOnIOThread,
75 base::Unretained(this), ep0, ep1));
76 }
77
78 // This bootstraps |ep| on |channels_[channel_index]|. It assumes/requires
79 // that this is the bootstrap case (i.e., no message pipes have ever been
80 // hosted on the channel). This returns *without* waiting.
81 void BootstrapChannelEndpointNoWait(unsigned channel_index,
82 scoped_refptr<ChannelEndpoint> ep) {
83 io_thread_.PostTask(
84 FROM_HERE,
85 base::Bind(&RemoteMessagePipeTest::BootstrapChannelEndpointOnIOThread,
86 base::Unretained(this), channel_index, ep));
87 }
88
89 void RestoreInitialState() {
90 io_thread_.PostTaskAndWait(
91 FROM_HERE,
92 base::Bind(&RemoteMessagePipeTest::RestoreInitialStateOnIOThread,
93 base::Unretained(this)));
94 }
95
96 embedder::PlatformSupport* platform_support() { return &platform_support_; }
97 base::TestIOThread* io_thread() { return &io_thread_; }
98 // Warning: It's up to the caller to ensure that the returned channel
99 // is/remains valid.
100 Channel* channels(size_t i) { return channels_[i].get(); }
101
102 private:
103 void SetUpOnIOThread() {
104 CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop());
105
106 embedder::PlatformChannelPair channel_pair;
107 platform_handles_[0] = channel_pair.PassServerHandle();
108 platform_handles_[1] = channel_pair.PassClientHandle();
109 }
110
111 void TearDownOnIOThread() {
112 CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop());
113
114 if (channels_[0]) {
115 channels_[0]->Shutdown();
116 channels_[0] = nullptr;
117 }
118 if (channels_[1]) {
119 channels_[1]->Shutdown();
120 channels_[1] = nullptr;
121 }
122 }
123
124 void CreateAndInitChannel(unsigned channel_index) {
125 CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop());
126 CHECK(channel_index == 0 || channel_index == 1);
127 CHECK(!channels_[channel_index]);
128
129 channels_[channel_index] = new Channel(&platform_support_);
130 channels_[channel_index]->Init(
131 RawChannel::Create(platform_handles_[channel_index].Pass()));
132 }
133
134 void BootstrapChannelEndpointsOnIOThread(scoped_refptr<ChannelEndpoint> ep0,
135 scoped_refptr<ChannelEndpoint> ep1) {
136 CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop());
137
138 if (!channels_[0])
139 CreateAndInitChannel(0);
140 if (!channels_[1])
141 CreateAndInitChannel(1);
142
143 channels_[0]->SetBootstrapEndpoint(ep0);
144 channels_[1]->SetBootstrapEndpoint(ep1);
145 }
146
147 void BootstrapChannelEndpointOnIOThread(unsigned channel_index,
148 scoped_refptr<ChannelEndpoint> ep) {
149 CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop());
150 CHECK(channel_index == 0 || channel_index == 1);
151
152 CreateAndInitChannel(channel_index);
153 channels_[channel_index]->SetBootstrapEndpoint(ep);
154 }
155
156 void RestoreInitialStateOnIOThread() {
157 CHECK_EQ(base::MessageLoop::current(), io_thread()->message_loop());
158
159 TearDownOnIOThread();
160 SetUpOnIOThread();
161 }
162
163 embedder::SimplePlatformSupport platform_support_;
164 base::TestIOThread io_thread_;
165 embedder::ScopedPlatformHandle platform_handles_[2];
166 scoped_refptr<Channel> channels_[2];
167
168 DISALLOW_COPY_AND_ASSIGN(RemoteMessagePipeTest);
169 };
170
171 TEST_F(RemoteMessagePipeTest, Basic) {
172 static const char kHello[] = "hello";
173 static const char kWorld[] = "world!!!1!!!1!";
174 char buffer[100] = {0};
175 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
176 Waiter waiter;
177 HandleSignalsState hss;
178 uint32_t context = 0;
179
180 // Connect message pipes. MP 0, port 1 will be attached to channel 0 and
181 // connected to MP 1, port 0, which will be attached to channel 1. This leaves
182 // MP 0, port 0 and MP 1, port 1 as the "user-facing" endpoints.
183
184 scoped_refptr<ChannelEndpoint> ep0;
185 scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
186 scoped_refptr<ChannelEndpoint> ep1;
187 scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
188 BootstrapChannelEndpoints(ep0, ep1);
189
190 // Write in one direction: MP 0, port 0 -> ... -> MP 1, port 1.
191
192 // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do
193 // it later, it might already be readable.)
194 waiter.Init();
195 ASSERT_EQ(
196 MOJO_RESULT_OK,
197 mp1->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 123, nullptr));
198
199 // Write to MP 0, port 0.
200 EXPECT_EQ(
201 MOJO_RESULT_OK,
202 mp0->WriteMessage(0, UserPointer<const void>(kHello), sizeof(kHello),
203 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
204
205 // Wait.
206 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
207 EXPECT_EQ(123u, context);
208 hss = HandleSignalsState();
209 mp1->RemoveAwakable(1, &waiter, &hss);
210 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
211 hss.satisfied_signals);
212 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
213
214 // Read from MP 1, port 1.
215 EXPECT_EQ(MOJO_RESULT_OK,
216 mp1->ReadMessage(1, UserPointer<void>(buffer),
217 MakeUserPointer(&buffer_size), nullptr, nullptr,
218 MOJO_READ_MESSAGE_FLAG_NONE));
219 EXPECT_EQ(sizeof(kHello), static_cast<size_t>(buffer_size));
220 EXPECT_STREQ(kHello, buffer);
221
222 // Write in the other direction: MP 1, port 1 -> ... -> MP 0, port 0.
223
224 waiter.Init();
225 ASSERT_EQ(
226 MOJO_RESULT_OK,
227 mp0->AddAwakable(0, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 456, nullptr));
228
229 EXPECT_EQ(
230 MOJO_RESULT_OK,
231 mp1->WriteMessage(1, UserPointer<const void>(kWorld), sizeof(kWorld),
232 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
233
234 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
235 EXPECT_EQ(456u, context);
236 hss = HandleSignalsState();
237 mp0->RemoveAwakable(0, &waiter, &hss);
238 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
239 hss.satisfied_signals);
240 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
241
242 buffer_size = static_cast<uint32_t>(sizeof(buffer));
243 EXPECT_EQ(MOJO_RESULT_OK,
244 mp0->ReadMessage(0, UserPointer<void>(buffer),
245 MakeUserPointer(&buffer_size), nullptr, nullptr,
246 MOJO_READ_MESSAGE_FLAG_NONE));
247 EXPECT_EQ(sizeof(kWorld), static_cast<size_t>(buffer_size));
248 EXPECT_STREQ(kWorld, buffer);
249
250 // Close MP 0, port 0.
251 mp0->Close(0);
252
253 // Try to wait for MP 1, port 1 to become readable. This will eventually fail
254 // when it realizes that MP 0, port 0 has been closed. (It may also fail
255 // immediately.)
256 waiter.Init();
257 hss = HandleSignalsState();
258 MojoResult result =
259 mp1->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 789, &hss);
260 if (result == MOJO_RESULT_OK) {
261 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
262 waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
263 EXPECT_EQ(789u, context);
264 hss = HandleSignalsState();
265 mp1->RemoveAwakable(1, &waiter, &hss);
266 }
267 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
268 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
269
270 // And MP 1, port 1.
271 mp1->Close(1);
272 }
273
274 TEST_F(RemoteMessagePipeTest, PeerClosed) {
275 Waiter waiter;
276 HandleSignalsState hss;
277 uint32_t context = 0;
278
279 // Connect message pipes. MP 0, port 1 will be attached to channel 0 and
280 // connected to MP 1, port 0, which will be attached to channel 1. This leaves
281 // MP 0, port 0 and MP 1, port 1 as the "user-facing" endpoints.
282
283 scoped_refptr<ChannelEndpoint> ep0;
284 scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
285 scoped_refptr<ChannelEndpoint> ep1;
286 scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
287 BootstrapChannelEndpoints(ep0, ep1);
288
289 // Close MP 0, port 0.
290 mp0->Close(0);
291
292 // Try to wait for MP 1, port 1 to be signaled with peer closed.
293 waiter.Init();
294 hss = HandleSignalsState();
295 MojoResult result =
296 mp1->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_PEER_CLOSED, 101, &hss);
297 if (result == MOJO_RESULT_OK) {
298 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
299 EXPECT_EQ(101u, context);
300 hss = HandleSignalsState();
301 mp1->RemoveAwakable(1, &waiter, &hss);
302 }
303 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
304 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
305
306 // And MP 1, port 1.
307 mp1->Close(1);
308 }
309
310 TEST_F(RemoteMessagePipeTest, Multiplex) {
311 static const char kHello[] = "hello";
312 static const char kWorld[] = "world!!!1!!!1!";
313 char buffer[100] = {0};
314 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
315 Waiter waiter;
316 HandleSignalsState hss;
317 uint32_t context = 0;
318
319 // Connect message pipes as in the |Basic| test.
320
321 scoped_refptr<ChannelEndpoint> ep0;
322 scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
323 scoped_refptr<ChannelEndpoint> ep1;
324 scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
325 BootstrapChannelEndpoints(ep0, ep1);
326
327 // Now put another message pipe on the channel.
328
329 // Do this by creating a message pipe (for the |channels(0)| side) and
330 // attaching and running it, yielding the remote ID. A message is then sent
331 // via |ep0| (i.e., sent using |mp0|, port 0) with this remote ID. Upon
332 // receiving this message, |PassIncomingMessagePipe()| is used to obtain the
333 // message pipe on the other side.
334 scoped_refptr<MessagePipe> mp2(MessagePipe::CreateLocalLocal());
335 ASSERT_TRUE(channels(0));
336 size_t max_endpoint_info_size;
337 size_t max_platform_handle_count;
338 mp2->StartSerialize(1, channels(0), &max_endpoint_info_size,
339 &max_platform_handle_count);
340 EXPECT_GT(max_endpoint_info_size, 0u);
341 ASSERT_EQ(0u, max_platform_handle_count);
342 scoped_ptr<char[]> endpoint_info(new char[max_endpoint_info_size]);
343 size_t endpoint_info_size;
344 mp2->EndSerialize(1, channels(0), endpoint_info.get(), &endpoint_info_size,
345 nullptr);
346 EXPECT_EQ(max_endpoint_info_size, endpoint_info_size);
347
348 waiter.Init();
349 ASSERT_EQ(
350 MOJO_RESULT_OK,
351 mp1->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 123, nullptr));
352
353 EXPECT_EQ(MOJO_RESULT_OK,
354 mp0->WriteMessage(0, UserPointer<const void>(endpoint_info.get()),
355 static_cast<uint32_t>(endpoint_info_size),
356 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
357
358 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
359 EXPECT_EQ(123u, context);
360 hss = HandleSignalsState();
361 mp1->RemoveAwakable(1, &waiter, &hss);
362 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
363 hss.satisfied_signals);
364 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
365
366 EXPECT_EQ(endpoint_info_size, channels(1)->GetSerializedEndpointSize());
367 scoped_ptr<char[]> received_endpoint_info(new char[endpoint_info_size]);
368 buffer_size = static_cast<uint32_t>(endpoint_info_size);
369 EXPECT_EQ(MOJO_RESULT_OK,
370 mp1->ReadMessage(1, UserPointer<void>(received_endpoint_info.get()),
371 MakeUserPointer(&buffer_size), nullptr, nullptr,
372 MOJO_READ_MESSAGE_FLAG_NONE));
373 EXPECT_EQ(endpoint_info_size, static_cast<size_t>(buffer_size));
374 EXPECT_EQ(0, memcmp(received_endpoint_info.get(), endpoint_info.get(),
375 endpoint_info_size));
376
377 // Warning: The local side of mp3 is port 0, not port 1.
378 scoped_refptr<IncomingEndpoint> incoming_endpoint =
379 channels(1)->DeserializeEndpoint(received_endpoint_info.get());
380 ASSERT_TRUE(incoming_endpoint);
381 scoped_refptr<MessagePipe> mp3 = incoming_endpoint->ConvertToMessagePipe();
382 ASSERT_TRUE(mp3);
383
384 // Write: MP 2, port 0 -> MP 3, port 1.
385
386 waiter.Init();
387 ASSERT_EQ(
388 MOJO_RESULT_OK,
389 mp3->AddAwakable(0, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 789, nullptr));
390
391 EXPECT_EQ(
392 MOJO_RESULT_OK,
393 mp2->WriteMessage(0, UserPointer<const void>(kHello), sizeof(kHello),
394 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
395
396 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
397 EXPECT_EQ(789u, context);
398 hss = HandleSignalsState();
399 mp3->RemoveAwakable(0, &waiter, &hss);
400 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
401 hss.satisfied_signals);
402 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
403
404 // Make sure there's nothing on MP 0, port 0 or MP 1, port 1 or MP 2, port 0.
405 buffer_size = static_cast<uint32_t>(sizeof(buffer));
406 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
407 mp0->ReadMessage(0, UserPointer<void>(buffer),
408 MakeUserPointer(&buffer_size), nullptr, nullptr,
409 MOJO_READ_MESSAGE_FLAG_NONE));
410 buffer_size = static_cast<uint32_t>(sizeof(buffer));
411 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
412 mp1->ReadMessage(1, UserPointer<void>(buffer),
413 MakeUserPointer(&buffer_size), nullptr, nullptr,
414 MOJO_READ_MESSAGE_FLAG_NONE));
415 buffer_size = static_cast<uint32_t>(sizeof(buffer));
416 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
417 mp2->ReadMessage(0, UserPointer<void>(buffer),
418 MakeUserPointer(&buffer_size), nullptr, nullptr,
419 MOJO_READ_MESSAGE_FLAG_NONE));
420
421 // Read from MP 3, port 1.
422 buffer_size = static_cast<uint32_t>(sizeof(buffer));
423 EXPECT_EQ(MOJO_RESULT_OK,
424 mp3->ReadMessage(0, UserPointer<void>(buffer),
425 MakeUserPointer(&buffer_size), nullptr, nullptr,
426 MOJO_READ_MESSAGE_FLAG_NONE));
427 EXPECT_EQ(sizeof(kHello), static_cast<size_t>(buffer_size));
428 EXPECT_STREQ(kHello, buffer);
429
430 // Write: MP 0, port 0 -> MP 1, port 1 again.
431
432 waiter.Init();
433 ASSERT_EQ(
434 MOJO_RESULT_OK,
435 mp1->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 123, nullptr));
436
437 EXPECT_EQ(
438 MOJO_RESULT_OK,
439 mp0->WriteMessage(0, UserPointer<const void>(kWorld), sizeof(kWorld),
440 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
441
442 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
443 EXPECT_EQ(123u, context);
444 hss = HandleSignalsState();
445 mp1->RemoveAwakable(1, &waiter, &hss);
446 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
447 hss.satisfied_signals);
448 EXPECT_EQ(kAllSignals | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
449 hss.satisfiable_signals);
450
451 // Make sure there's nothing on the other ports.
452 buffer_size = static_cast<uint32_t>(sizeof(buffer));
453 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
454 mp0->ReadMessage(0, UserPointer<void>(buffer),
455 MakeUserPointer(&buffer_size), nullptr, nullptr,
456 MOJO_READ_MESSAGE_FLAG_NONE));
457 buffer_size = static_cast<uint32_t>(sizeof(buffer));
458 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
459 mp2->ReadMessage(0, UserPointer<void>(buffer),
460 MakeUserPointer(&buffer_size), nullptr, nullptr,
461 MOJO_READ_MESSAGE_FLAG_NONE));
462 buffer_size = static_cast<uint32_t>(sizeof(buffer));
463 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
464 mp3->ReadMessage(0, UserPointer<void>(buffer),
465 MakeUserPointer(&buffer_size), nullptr, nullptr,
466 MOJO_READ_MESSAGE_FLAG_NONE));
467
468 buffer_size = static_cast<uint32_t>(sizeof(buffer));
469 EXPECT_EQ(MOJO_RESULT_OK,
470 mp1->ReadMessage(1, UserPointer<void>(buffer),
471 MakeUserPointer(&buffer_size), nullptr, nullptr,
472 MOJO_READ_MESSAGE_FLAG_NONE));
473 EXPECT_EQ(sizeof(kWorld), static_cast<size_t>(buffer_size));
474 EXPECT_STREQ(kWorld, buffer);
475
476 mp0->Close(0);
477 mp1->Close(1);
478 mp2->Close(0);
479 mp3->Close(0);
480 }
481
482 TEST_F(RemoteMessagePipeTest, CloseBeforeAttachAndRun) {
483 static const char kHello[] = "hello";
484 char buffer[100] = {0};
485 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
486 Waiter waiter;
487 HandleSignalsState hss;
488 uint32_t context = 0;
489
490 // Connect message pipes. MP 0, port 1 will be attached to channel 0 and
491 // connected to MP 1, port 0, which will be attached to channel 1. This leaves
492 // MP 0, port 0 and MP 1, port 1 as the "user-facing" endpoints.
493
494 scoped_refptr<ChannelEndpoint> ep0;
495 scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
496
497 // Write to MP 0, port 0.
498 EXPECT_EQ(
499 MOJO_RESULT_OK,
500 mp0->WriteMessage(0, UserPointer<const void>(kHello), sizeof(kHello),
501 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
502
503 // Close MP 0, port 0 before it's even been attached to the channel and run.
504 mp0->Close(0);
505
506 BootstrapChannelEndpointNoWait(0, ep0);
507
508 scoped_refptr<ChannelEndpoint> ep1;
509 scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
510
511 // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do
512 // it later, it might already be readable.)
513 waiter.Init();
514 ASSERT_EQ(
515 MOJO_RESULT_OK,
516 mp1->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 123, nullptr));
517
518 BootstrapChannelEndpointNoWait(1, ep1);
519
520 // Wait.
521 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
522 EXPECT_EQ(123u, context);
523 hss = HandleSignalsState();
524 // Note: MP 1, port 1 should definitely should be readable, but it may or may
525 // not appear as writable (there's a race, and it may not have noticed that
526 // the other side was closed yet -- e.g., inserting a sleep here would make it
527 // much more likely to notice that it's no longer writable).
528 mp1->RemoveAwakable(1, &waiter, &hss);
529 EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
530 EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
531
532 // Read from MP 1, port 1.
533 EXPECT_EQ(MOJO_RESULT_OK,
534 mp1->ReadMessage(1, UserPointer<void>(buffer),
535 MakeUserPointer(&buffer_size), nullptr, nullptr,
536 MOJO_READ_MESSAGE_FLAG_NONE));
537 EXPECT_EQ(sizeof(kHello), static_cast<size_t>(buffer_size));
538 EXPECT_STREQ(kHello, buffer);
539
540 // And MP 1, port 1.
541 mp1->Close(1);
542 }
543
544 TEST_F(RemoteMessagePipeTest, CloseBeforeConnect) {
545 static const char kHello[] = "hello";
546 char buffer[100] = {0};
547 uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer));
548 Waiter waiter;
549 HandleSignalsState hss;
550 uint32_t context = 0;
551
552 // Connect message pipes. MP 0, port 1 will be attached to channel 0 and
553 // connected to MP 1, port 0, which will be attached to channel 1. This leaves
554 // MP 0, port 0 and MP 1, port 1 as the "user-facing" endpoints.
555
556 scoped_refptr<ChannelEndpoint> ep0;
557 scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
558
559 // Write to MP 0, port 0.
560 EXPECT_EQ(
561 MOJO_RESULT_OK,
562 mp0->WriteMessage(0, UserPointer<const void>(kHello), sizeof(kHello),
563 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
564
565 BootstrapChannelEndpointNoWait(0, ep0);
566
567 // Close MP 0, port 0 before channel 1 is even connected.
568 mp0->Close(0);
569
570 scoped_refptr<ChannelEndpoint> ep1;
571 scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
572
573 // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do
574 // it later, it might already be readable.)
575 waiter.Init();
576 ASSERT_EQ(
577 MOJO_RESULT_OK,
578 mp1->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 123, nullptr));
579
580 BootstrapChannelEndpointNoWait(1, ep1);
581
582 // Wait.
583 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
584 EXPECT_EQ(123u, context);
585 hss = HandleSignalsState();
586 // Note: MP 1, port 1 should definitely should be readable, but it may or may
587 // not appear as writable (there's a race, and it may not have noticed that
588 // the other side was closed yet -- e.g., inserting a sleep here would make it
589 // much more likely to notice that it's no longer writable).
590 mp1->RemoveAwakable(1, &waiter, &hss);
591 EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
592 EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
593
594 // Read from MP 1, port 1.
595 EXPECT_EQ(MOJO_RESULT_OK,
596 mp1->ReadMessage(1, UserPointer<void>(buffer),
597 MakeUserPointer(&buffer_size), nullptr, nullptr,
598 MOJO_READ_MESSAGE_FLAG_NONE));
599 EXPECT_EQ(sizeof(kHello), static_cast<size_t>(buffer_size));
600 EXPECT_STREQ(kHello, buffer);
601
602 // And MP 1, port 1.
603 mp1->Close(1);
604 }
605
606 TEST_F(RemoteMessagePipeTest, HandlePassing) {
607 static const char kHello[] = "hello";
608 Waiter waiter;
609 HandleSignalsState hss;
610 uint32_t context = 0;
611
612 scoped_refptr<ChannelEndpoint> ep0;
613 scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
614 scoped_refptr<ChannelEndpoint> ep1;
615 scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
616 BootstrapChannelEndpoints(ep0, ep1);
617
618 // We'll try to pass this dispatcher.
619 scoped_refptr<MessagePipeDispatcher> dispatcher(
620 new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions));
621 scoped_refptr<MessagePipe> local_mp(MessagePipe::CreateLocalLocal());
622 dispatcher->Init(local_mp, 0);
623
624 // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do
625 // it later, it might already be readable.)
626 waiter.Init();
627 ASSERT_EQ(
628 MOJO_RESULT_OK,
629 mp1->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 123, nullptr));
630
631 // Write to MP 0, port 0.
632 {
633 DispatcherTransport transport(
634 test::DispatcherTryStartTransport(dispatcher.get()));
635 EXPECT_TRUE(transport.is_valid());
636
637 std::vector<DispatcherTransport> transports;
638 transports.push_back(transport);
639 EXPECT_EQ(
640 MOJO_RESULT_OK,
641 mp0->WriteMessage(0, UserPointer<const void>(kHello), sizeof(kHello),
642 &transports, MOJO_WRITE_MESSAGE_FLAG_NONE));
643 transport.End();
644
645 // |dispatcher| should have been closed. This is |DCHECK()|ed when the
646 // |dispatcher| is destroyed.
647 EXPECT_TRUE(dispatcher->HasOneRef());
648 dispatcher = nullptr;
649 }
650
651 // Wait.
652 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
653 EXPECT_EQ(123u, context);
654 hss = HandleSignalsState();
655 mp1->RemoveAwakable(1, &waiter, &hss);
656 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
657 hss.satisfied_signals);
658 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
659
660 // Read from MP 1, port 1.
661 char read_buffer[100] = {0};
662 uint32_t read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
663 DispatcherVector read_dispatchers;
664 uint32_t read_num_dispatchers = 10; // Maximum to get.
665 EXPECT_EQ(
666 MOJO_RESULT_OK,
667 mp1->ReadMessage(1, UserPointer<void>(read_buffer),
668 MakeUserPointer(&read_buffer_size), &read_dispatchers,
669 &read_num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE));
670 EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
671 EXPECT_STREQ(kHello, read_buffer);
672 EXPECT_EQ(1u, read_dispatchers.size());
673 EXPECT_EQ(1u, read_num_dispatchers);
674 ASSERT_TRUE(read_dispatchers[0]);
675 EXPECT_TRUE(read_dispatchers[0]->HasOneRef());
676
677 EXPECT_EQ(Dispatcher::kTypeMessagePipe, read_dispatchers[0]->GetType());
678 dispatcher = static_cast<MessagePipeDispatcher*>(read_dispatchers[0].get());
679
680 // Add the waiter now, before it becomes readable to avoid a race.
681 waiter.Init();
682 ASSERT_EQ(MOJO_RESULT_OK,
683 dispatcher->AddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 456,
684 nullptr));
685
686 // Write to "local_mp", port 1.
687 EXPECT_EQ(
688 MOJO_RESULT_OK,
689 local_mp->WriteMessage(1, UserPointer<const void>(kHello), sizeof(kHello),
690 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
691
692 // TODO(vtl): FIXME -- We (racily) crash if I close |dispatcher| immediately
693 // here. (We don't crash if I sleep and then close.)
694
695 // Wait for the dispatcher to become readable.
696 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
697 EXPECT_EQ(456u, context);
698 hss = HandleSignalsState();
699 dispatcher->RemoveAwakable(&waiter, &hss);
700 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
701 hss.satisfied_signals);
702 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
703
704 // Read from the dispatcher.
705 memset(read_buffer, 0, sizeof(read_buffer));
706 read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
707 EXPECT_EQ(MOJO_RESULT_OK,
708 dispatcher->ReadMessage(UserPointer<void>(read_buffer),
709 MakeUserPointer(&read_buffer_size), 0,
710 nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
711 EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
712 EXPECT_STREQ(kHello, read_buffer);
713
714 // Prepare to wait on "local_mp", port 1.
715 waiter.Init();
716 ASSERT_EQ(MOJO_RESULT_OK,
717 local_mp->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 789,
718 nullptr));
719
720 // Write to the dispatcher.
721 EXPECT_EQ(MOJO_RESULT_OK, dispatcher->WriteMessage(
722 UserPointer<const void>(kHello), sizeof(kHello),
723 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
724
725 // Wait.
726 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
727 EXPECT_EQ(789u, context);
728 hss = HandleSignalsState();
729 local_mp->RemoveAwakable(1, &waiter, &hss);
730 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
731 hss.satisfied_signals);
732 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
733
734 // Read from "local_mp", port 1.
735 memset(read_buffer, 0, sizeof(read_buffer));
736 read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
737 EXPECT_EQ(MOJO_RESULT_OK,
738 local_mp->ReadMessage(1, UserPointer<void>(read_buffer),
739 MakeUserPointer(&read_buffer_size), nullptr,
740 nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
741 EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
742 EXPECT_STREQ(kHello, read_buffer);
743
744 // TODO(vtl): Also test that messages queued up before the handle was sent are
745 // delivered properly.
746
747 // Close everything that belongs to us.
748 mp0->Close(0);
749 mp1->Close(1);
750 EXPECT_EQ(MOJO_RESULT_OK, dispatcher->Close());
751 // Note that |local_mp|'s port 0 belong to |dispatcher|, which was closed.
752 local_mp->Close(1);
753 }
754
755 TEST_F(RemoteMessagePipeTest, HandlePassingHalfClosed) {
756 static const char kHello[] = "hello";
757 static const char kWorld[] = "world!";
758 Waiter waiter;
759 HandleSignalsState hss;
760 uint32_t context = 0;
761
762 // We'll try to pass this dispatcher.
763 scoped_refptr<MessagePipeDispatcher> dispatcher(
764 new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions));
765 scoped_refptr<MessagePipe> local_mp(MessagePipe::CreateLocalLocal());
766 dispatcher->Init(local_mp, 0);
767
768 hss = local_mp->GetHandleSignalsState(0);
769 EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
770 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
771 // Write to the other end (|local_mp|, port 1), and then close it.
772 EXPECT_EQ(
773 MOJO_RESULT_OK,
774 local_mp->WriteMessage(1, UserPointer<const void>(kHello), sizeof(kHello),
775 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
776 hss = local_mp->GetHandleSignalsState(0);
777 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
778 hss.satisfied_signals);
779 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
780 // Then the second message....
781 EXPECT_EQ(
782 MOJO_RESULT_OK,
783 local_mp->WriteMessage(1, UserPointer<const void>(kWorld), sizeof(kWorld),
784 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
785 hss = local_mp->GetHandleSignalsState(0);
786 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
787 hss.satisfied_signals);
788 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
789 // Then close it.
790 local_mp->Close(1);
791
792 scoped_refptr<ChannelEndpoint> ep0;
793 scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
794 scoped_refptr<ChannelEndpoint> ep1;
795 scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
796 BootstrapChannelEndpoints(ep0, ep1);
797
798 // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do
799 // it later, it might already be readable.)
800 waiter.Init();
801 ASSERT_EQ(
802 MOJO_RESULT_OK,
803 mp1->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 123, nullptr));
804
805 // Write to MP 0, port 0.
806 {
807 DispatcherTransport transport(
808 test::DispatcherTryStartTransport(dispatcher.get()));
809 EXPECT_TRUE(transport.is_valid());
810
811 std::vector<DispatcherTransport> transports;
812 transports.push_back(transport);
813 EXPECT_EQ(
814 MOJO_RESULT_OK,
815 mp0->WriteMessage(0, UserPointer<const void>(kHello), sizeof(kHello),
816 &transports, MOJO_WRITE_MESSAGE_FLAG_NONE));
817 transport.End();
818
819 // |dispatcher| should have been closed. This is |DCHECK()|ed when the
820 // |dispatcher| is destroyed.
821 EXPECT_TRUE(dispatcher->HasOneRef());
822 dispatcher = nullptr;
823 }
824
825 // Wait.
826 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
827 EXPECT_EQ(123u, context);
828 hss = HandleSignalsState();
829 mp1->RemoveAwakable(1, &waiter, &hss);
830 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
831 hss.satisfied_signals);
832 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
833
834 // Read from MP 1, port 1.
835 char read_buffer[100] = {0};
836 uint32_t read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
837 DispatcherVector read_dispatchers;
838 uint32_t read_num_dispatchers = 10; // Maximum to get.
839 EXPECT_EQ(
840 MOJO_RESULT_OK,
841 mp1->ReadMessage(1, UserPointer<void>(read_buffer),
842 MakeUserPointer(&read_buffer_size), &read_dispatchers,
843 &read_num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE));
844 EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
845 EXPECT_STREQ(kHello, read_buffer);
846 EXPECT_EQ(1u, read_dispatchers.size());
847 EXPECT_EQ(1u, read_num_dispatchers);
848 ASSERT_TRUE(read_dispatchers[0]);
849 EXPECT_TRUE(read_dispatchers[0]->HasOneRef());
850
851 EXPECT_EQ(Dispatcher::kTypeMessagePipe, read_dispatchers[0]->GetType());
852 dispatcher = static_cast<MessagePipeDispatcher*>(read_dispatchers[0].get());
853
854 // |dispatcher| should already be readable and not writable.
855 hss = dispatcher->GetHandleSignalsState();
856 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
857 hss.satisfied_signals);
858 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
859 hss.satisfiable_signals);
860 // So read from it.
861 memset(read_buffer, 0, sizeof(read_buffer));
862 read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
863 EXPECT_EQ(MOJO_RESULT_OK,
864 dispatcher->ReadMessage(UserPointer<void>(read_buffer),
865 MakeUserPointer(&read_buffer_size), 0,
866 nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
867 EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
868 EXPECT_STREQ(kHello, read_buffer);
869 // It should still be readable.
870 hss = dispatcher->GetHandleSignalsState();
871 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
872 hss.satisfied_signals);
873 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
874 hss.satisfiable_signals);
875 // So read from it.
876 memset(read_buffer, 0, sizeof(read_buffer));
877 read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
878 EXPECT_EQ(MOJO_RESULT_OK,
879 dispatcher->ReadMessage(UserPointer<void>(read_buffer),
880 MakeUserPointer(&read_buffer_size), 0,
881 nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
882 EXPECT_EQ(sizeof(kWorld), static_cast<size_t>(read_buffer_size));
883 EXPECT_STREQ(kWorld, read_buffer);
884 // Now it should no longer be readable.
885 hss = dispatcher->GetHandleSignalsState();
886 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
887 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
888
889 // Close everything that belongs to us.
890 mp0->Close(0);
891 mp1->Close(1);
892 EXPECT_EQ(MOJO_RESULT_OK, dispatcher->Close());
893 }
894
895 #if defined(OS_POSIX)
896 #define MAYBE_SharedBufferPassing SharedBufferPassing
897 #else
898 // Not yet implemented (on Windows).
899 #define MAYBE_SharedBufferPassing DISABLED_SharedBufferPassing
900 #endif
901 TEST_F(RemoteMessagePipeTest, MAYBE_SharedBufferPassing) {
902 static const char kHello[] = "hello";
903 Waiter waiter;
904 HandleSignalsState hss;
905 uint32_t context = 0;
906
907 scoped_refptr<ChannelEndpoint> ep0;
908 scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
909 scoped_refptr<ChannelEndpoint> ep1;
910 scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
911 BootstrapChannelEndpoints(ep0, ep1);
912
913 // We'll try to pass this dispatcher.
914 scoped_refptr<SharedBufferDispatcher> dispatcher;
915 EXPECT_EQ(MOJO_RESULT_OK, SharedBufferDispatcher::Create(
916 platform_support(),
917 SharedBufferDispatcher::kDefaultCreateOptions,
918 100, &dispatcher));
919 ASSERT_TRUE(dispatcher);
920
921 // Make a mapping.
922 scoped_ptr<embedder::PlatformSharedBufferMapping> mapping0;
923 EXPECT_EQ(MOJO_RESULT_OK, dispatcher->MapBuffer(
924 0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping0));
925 ASSERT_TRUE(mapping0);
926 ASSERT_TRUE(mapping0->GetBase());
927 ASSERT_EQ(100u, mapping0->GetLength());
928 static_cast<char*>(mapping0->GetBase())[0] = 'A';
929 static_cast<char*>(mapping0->GetBase())[50] = 'B';
930 static_cast<char*>(mapping0->GetBase())[99] = 'C';
931
932 // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do
933 // it later, it might already be readable.)
934 waiter.Init();
935 ASSERT_EQ(
936 MOJO_RESULT_OK,
937 mp1->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 123, nullptr));
938
939 // Write to MP 0, port 0.
940 {
941 DispatcherTransport transport(
942 test::DispatcherTryStartTransport(dispatcher.get()));
943 EXPECT_TRUE(transport.is_valid());
944
945 std::vector<DispatcherTransport> transports;
946 transports.push_back(transport);
947 EXPECT_EQ(
948 MOJO_RESULT_OK,
949 mp0->WriteMessage(0, UserPointer<const void>(kHello), sizeof(kHello),
950 &transports, MOJO_WRITE_MESSAGE_FLAG_NONE));
951 transport.End();
952
953 // |dispatcher| should have been closed. This is |DCHECK()|ed when the
954 // |dispatcher| is destroyed.
955 EXPECT_TRUE(dispatcher->HasOneRef());
956 dispatcher = nullptr;
957 }
958
959 // Wait.
960 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
961 EXPECT_EQ(123u, context);
962 hss = HandleSignalsState();
963 mp1->RemoveAwakable(1, &waiter, &hss);
964 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
965 hss.satisfied_signals);
966 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
967
968 // Read from MP 1, port 1.
969 char read_buffer[100] = {0};
970 uint32_t read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
971 DispatcherVector read_dispatchers;
972 uint32_t read_num_dispatchers = 10; // Maximum to get.
973 EXPECT_EQ(
974 MOJO_RESULT_OK,
975 mp1->ReadMessage(1, UserPointer<void>(read_buffer),
976 MakeUserPointer(&read_buffer_size), &read_dispatchers,
977 &read_num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE));
978 EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
979 EXPECT_STREQ(kHello, read_buffer);
980 EXPECT_EQ(1u, read_dispatchers.size());
981 EXPECT_EQ(1u, read_num_dispatchers);
982 ASSERT_TRUE(read_dispatchers[0]);
983 EXPECT_TRUE(read_dispatchers[0]->HasOneRef());
984
985 EXPECT_EQ(Dispatcher::kTypeSharedBuffer, read_dispatchers[0]->GetType());
986 dispatcher = static_cast<SharedBufferDispatcher*>(read_dispatchers[0].get());
987
988 // Make another mapping.
989 scoped_ptr<embedder::PlatformSharedBufferMapping> mapping1;
990 EXPECT_EQ(MOJO_RESULT_OK, dispatcher->MapBuffer(
991 0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping1));
992 ASSERT_TRUE(mapping1);
993 ASSERT_TRUE(mapping1->GetBase());
994 ASSERT_EQ(100u, mapping1->GetLength());
995 EXPECT_NE(mapping1->GetBase(), mapping0->GetBase());
996 EXPECT_EQ('A', static_cast<char*>(mapping1->GetBase())[0]);
997 EXPECT_EQ('B', static_cast<char*>(mapping1->GetBase())[50]);
998 EXPECT_EQ('C', static_cast<char*>(mapping1->GetBase())[99]);
999
1000 // Write stuff either way.
1001 static_cast<char*>(mapping1->GetBase())[1] = 'x';
1002 EXPECT_EQ('x', static_cast<char*>(mapping0->GetBase())[1]);
1003 static_cast<char*>(mapping0->GetBase())[2] = 'y';
1004 EXPECT_EQ('y', static_cast<char*>(mapping1->GetBase())[2]);
1005
1006 // Kill the first mapping; the second should still be valid.
1007 mapping0.reset();
1008 EXPECT_EQ('A', static_cast<char*>(mapping1->GetBase())[0]);
1009
1010 // Close everything that belongs to us.
1011 mp0->Close(0);
1012 mp1->Close(1);
1013 EXPECT_EQ(MOJO_RESULT_OK, dispatcher->Close());
1014
1015 // The second mapping should still be good.
1016 EXPECT_EQ('x', static_cast<char*>(mapping1->GetBase())[1]);
1017 }
1018
1019 #if defined(OS_POSIX)
1020 #define MAYBE_PlatformHandlePassing PlatformHandlePassing
1021 #else
1022 // Not yet implemented (on Windows).
1023 #define MAYBE_PlatformHandlePassing DISABLED_PlatformHandlePassing
1024 #endif
1025 TEST_F(RemoteMessagePipeTest, MAYBE_PlatformHandlePassing) {
1026 base::ScopedTempDir temp_dir;
1027 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1028
1029 static const char kHello[] = "hello";
1030 static const char kWorld[] = "world";
1031 Waiter waiter;
1032 uint32_t context = 0;
1033 HandleSignalsState hss;
1034
1035 scoped_refptr<ChannelEndpoint> ep0;
1036 scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
1037 scoped_refptr<ChannelEndpoint> ep1;
1038 scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
1039 BootstrapChannelEndpoints(ep0, ep1);
1040
1041 base::FilePath unused;
1042 base::ScopedFILE fp(
1043 base::CreateAndOpenTemporaryFileInDir(temp_dir.path(), &unused));
1044 EXPECT_EQ(sizeof(kHello), fwrite(kHello, 1, sizeof(kHello), fp.get()));
1045 // We'll try to pass this dispatcher, which will cause a |PlatformHandle| to
1046 // be passed.
1047 scoped_refptr<PlatformHandleDispatcher> dispatcher(
1048 new PlatformHandleDispatcher(
1049 mojo::test::PlatformHandleFromFILE(fp.Pass())));
1050
1051 // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do
1052 // it later, it might already be readable.)
1053 waiter.Init();
1054 ASSERT_EQ(
1055 MOJO_RESULT_OK,
1056 mp1->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 123, nullptr));
1057
1058 // Write to MP 0, port 0.
1059 {
1060 DispatcherTransport transport(
1061 test::DispatcherTryStartTransport(dispatcher.get()));
1062 EXPECT_TRUE(transport.is_valid());
1063
1064 std::vector<DispatcherTransport> transports;
1065 transports.push_back(transport);
1066 EXPECT_EQ(
1067 MOJO_RESULT_OK,
1068 mp0->WriteMessage(0, UserPointer<const void>(kWorld), sizeof(kWorld),
1069 &transports, MOJO_WRITE_MESSAGE_FLAG_NONE));
1070 transport.End();
1071
1072 // |dispatcher| should have been closed. This is |DCHECK()|ed when the
1073 // |dispatcher| is destroyed.
1074 EXPECT_TRUE(dispatcher->HasOneRef());
1075 dispatcher = nullptr;
1076 }
1077
1078 // Wait.
1079 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
1080 EXPECT_EQ(123u, context);
1081 hss = HandleSignalsState();
1082 mp1->RemoveAwakable(1, &waiter, &hss);
1083 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
1084 hss.satisfied_signals);
1085 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
1086
1087 // Read from MP 1, port 1.
1088 char read_buffer[100] = {0};
1089 uint32_t read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
1090 DispatcherVector read_dispatchers;
1091 uint32_t read_num_dispatchers = 10; // Maximum to get.
1092 EXPECT_EQ(
1093 MOJO_RESULT_OK,
1094 mp1->ReadMessage(1, UserPointer<void>(read_buffer),
1095 MakeUserPointer(&read_buffer_size), &read_dispatchers,
1096 &read_num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE));
1097 EXPECT_EQ(sizeof(kWorld), static_cast<size_t>(read_buffer_size));
1098 EXPECT_STREQ(kWorld, read_buffer);
1099 EXPECT_EQ(1u, read_dispatchers.size());
1100 EXPECT_EQ(1u, read_num_dispatchers);
1101 ASSERT_TRUE(read_dispatchers[0]);
1102 EXPECT_TRUE(read_dispatchers[0]->HasOneRef());
1103
1104 EXPECT_EQ(Dispatcher::kTypePlatformHandle, read_dispatchers[0]->GetType());
1105 dispatcher =
1106 static_cast<PlatformHandleDispatcher*>(read_dispatchers[0].get());
1107
1108 embedder::ScopedPlatformHandle h = dispatcher->PassPlatformHandle().Pass();
1109 EXPECT_TRUE(h.is_valid());
1110
1111 fp = mojo::test::FILEFromPlatformHandle(h.Pass(), "rb").Pass();
1112 EXPECT_FALSE(h.is_valid());
1113 EXPECT_TRUE(fp);
1114
1115 rewind(fp.get());
1116 memset(read_buffer, 0, sizeof(read_buffer));
1117 EXPECT_EQ(sizeof(kHello),
1118 fread(read_buffer, 1, sizeof(read_buffer), fp.get()));
1119 EXPECT_STREQ(kHello, read_buffer);
1120
1121 // Close everything that belongs to us.
1122 mp0->Close(0);
1123 mp1->Close(1);
1124 EXPECT_EQ(MOJO_RESULT_OK, dispatcher->Close());
1125 }
1126
1127 // Test racing closes (on each end).
1128 // Note: A flaky failure would almost certainly indicate a problem in the code
1129 // itself (not in the test). Also, any logged warnings/errors would also
1130 // probably be indicative of bugs.
1131 TEST_F(RemoteMessagePipeTest, RacingClosesStress) {
1132 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(5);
1133
1134 for (unsigned i = 0; i < 256; i++) {
1135 DVLOG(2) << "---------------------------------------- " << i;
1136 scoped_refptr<ChannelEndpoint> ep0;
1137 scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
1138 BootstrapChannelEndpointNoWait(0, ep0);
1139
1140 scoped_refptr<ChannelEndpoint> ep1;
1141 scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
1142 BootstrapChannelEndpointNoWait(1, ep1);
1143
1144 if (i & 1u) {
1145 io_thread()->task_runner()->PostTask(
1146 FROM_HERE, base::Bind(&base::PlatformThread::Sleep, delay));
1147 }
1148 if (i & 2u)
1149 base::PlatformThread::Sleep(delay);
1150
1151 mp0->Close(0);
1152
1153 if (i & 4u) {
1154 io_thread()->task_runner()->PostTask(
1155 FROM_HERE, base::Bind(&base::PlatformThread::Sleep, delay));
1156 }
1157 if (i & 8u)
1158 base::PlatformThread::Sleep(delay);
1159
1160 mp1->Close(1);
1161
1162 RestoreInitialState();
1163 }
1164 }
1165
1166 // Tests passing an end of a message pipe over a remote message pipe, and then
1167 // passing that end back.
1168 // TODO(vtl): Also test passing a message pipe across two remote message pipes.
1169 TEST_F(RemoteMessagePipeTest, PassMessagePipeHandleAcrossAndBack) {
1170 static const char kHello[] = "hello";
1171 static const char kWorld[] = "world";
1172 Waiter waiter;
1173 HandleSignalsState hss;
1174 uint32_t context = 0;
1175
1176 scoped_refptr<ChannelEndpoint> ep0;
1177 scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
1178 scoped_refptr<ChannelEndpoint> ep1;
1179 scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
1180 BootstrapChannelEndpoints(ep0, ep1);
1181
1182 // We'll try to pass this dispatcher.
1183 scoped_refptr<MessagePipeDispatcher> dispatcher(
1184 new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions));
1185 scoped_refptr<MessagePipe> local_mp(MessagePipe::CreateLocalLocal());
1186 dispatcher->Init(local_mp, 0);
1187
1188 // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do
1189 // it later, it might already be readable.)
1190 waiter.Init();
1191 ASSERT_EQ(
1192 MOJO_RESULT_OK,
1193 mp1->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 123, nullptr));
1194
1195 // Write to MP 0, port 0.
1196 {
1197 DispatcherTransport transport(
1198 test::DispatcherTryStartTransport(dispatcher.get()));
1199 EXPECT_TRUE(transport.is_valid());
1200
1201 std::vector<DispatcherTransport> transports;
1202 transports.push_back(transport);
1203 EXPECT_EQ(
1204 MOJO_RESULT_OK,
1205 mp0->WriteMessage(0, UserPointer<const void>(kHello), sizeof(kHello),
1206 &transports, MOJO_WRITE_MESSAGE_FLAG_NONE));
1207 transport.End();
1208
1209 // |dispatcher| should have been closed. This is |DCHECK()|ed when the
1210 // |dispatcher| is destroyed.
1211 EXPECT_TRUE(dispatcher->HasOneRef());
1212 dispatcher = nullptr;
1213 }
1214
1215 // Wait.
1216 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
1217 EXPECT_EQ(123u, context);
1218 hss = HandleSignalsState();
1219 mp1->RemoveAwakable(1, &waiter, &hss);
1220 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
1221 hss.satisfied_signals);
1222 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
1223
1224 // Read from MP 1, port 1.
1225 char read_buffer[100] = {0};
1226 uint32_t read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
1227 DispatcherVector read_dispatchers;
1228 uint32_t read_num_dispatchers = 10; // Maximum to get.
1229 EXPECT_EQ(
1230 MOJO_RESULT_OK,
1231 mp1->ReadMessage(1, UserPointer<void>(read_buffer),
1232 MakeUserPointer(&read_buffer_size), &read_dispatchers,
1233 &read_num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE));
1234 EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
1235 EXPECT_STREQ(kHello, read_buffer);
1236 EXPECT_EQ(1u, read_dispatchers.size());
1237 EXPECT_EQ(1u, read_num_dispatchers);
1238 ASSERT_TRUE(read_dispatchers[0]);
1239 EXPECT_TRUE(read_dispatchers[0]->HasOneRef());
1240
1241 EXPECT_EQ(Dispatcher::kTypeMessagePipe, read_dispatchers[0]->GetType());
1242 dispatcher = static_cast<MessagePipeDispatcher*>(read_dispatchers[0].get());
1243 read_dispatchers.clear();
1244
1245 // Now pass it back.
1246
1247 // Prepare to wait on MP 0, port 0. (Add the waiter now. Otherwise, if we do
1248 // it later, it might already be readable.)
1249 waiter.Init();
1250 ASSERT_EQ(
1251 MOJO_RESULT_OK,
1252 mp0->AddAwakable(0, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 456, nullptr));
1253
1254 // Write to MP 1, port 1.
1255 {
1256 DispatcherTransport transport(
1257 test::DispatcherTryStartTransport(dispatcher.get()));
1258 EXPECT_TRUE(transport.is_valid());
1259
1260 std::vector<DispatcherTransport> transports;
1261 transports.push_back(transport);
1262 EXPECT_EQ(
1263 MOJO_RESULT_OK,
1264 mp1->WriteMessage(1, UserPointer<const void>(kWorld), sizeof(kWorld),
1265 &transports, MOJO_WRITE_MESSAGE_FLAG_NONE));
1266 transport.End();
1267
1268 // |dispatcher| should have been closed. This is |DCHECK()|ed when the
1269 // |dispatcher| is destroyed.
1270 EXPECT_TRUE(dispatcher->HasOneRef());
1271 dispatcher = nullptr;
1272 }
1273
1274 // Wait.
1275 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
1276 EXPECT_EQ(456u, context);
1277 hss = HandleSignalsState();
1278 mp0->RemoveAwakable(0, &waiter, &hss);
1279 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
1280 hss.satisfied_signals);
1281 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
1282
1283 // Read from MP 0, port 0.
1284 read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
1285 read_num_dispatchers = 10; // Maximum to get.
1286 EXPECT_EQ(
1287 MOJO_RESULT_OK,
1288 mp0->ReadMessage(0, UserPointer<void>(read_buffer),
1289 MakeUserPointer(&read_buffer_size), &read_dispatchers,
1290 &read_num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE));
1291 EXPECT_EQ(sizeof(kWorld), static_cast<size_t>(read_buffer_size));
1292 EXPECT_STREQ(kWorld, read_buffer);
1293 EXPECT_EQ(1u, read_dispatchers.size());
1294 EXPECT_EQ(1u, read_num_dispatchers);
1295 ASSERT_TRUE(read_dispatchers[0]);
1296 EXPECT_TRUE(read_dispatchers[0]->HasOneRef());
1297
1298 EXPECT_EQ(Dispatcher::kTypeMessagePipe, read_dispatchers[0]->GetType());
1299 dispatcher = static_cast<MessagePipeDispatcher*>(read_dispatchers[0].get());
1300 read_dispatchers.clear();
1301
1302 // Add the waiter now, before it becomes readable to avoid a race.
1303 waiter.Init();
1304 ASSERT_EQ(MOJO_RESULT_OK,
1305 dispatcher->AddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 789,
1306 nullptr));
1307
1308 // Write to "local_mp", port 1.
1309 EXPECT_EQ(
1310 MOJO_RESULT_OK,
1311 local_mp->WriteMessage(1, UserPointer<const void>(kHello), sizeof(kHello),
1312 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
1313
1314 // Wait for the dispatcher to become readable.
1315 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
1316 EXPECT_EQ(789u, context);
1317 hss = HandleSignalsState();
1318 dispatcher->RemoveAwakable(&waiter, &hss);
1319 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
1320 hss.satisfied_signals);
1321 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
1322
1323 // Read from the dispatcher.
1324 memset(read_buffer, 0, sizeof(read_buffer));
1325 read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
1326 EXPECT_EQ(MOJO_RESULT_OK,
1327 dispatcher->ReadMessage(UserPointer<void>(read_buffer),
1328 MakeUserPointer(&read_buffer_size), 0,
1329 nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
1330 EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
1331 EXPECT_STREQ(kHello, read_buffer);
1332
1333 // Prepare to wait on "local_mp", port 1.
1334 waiter.Init();
1335 ASSERT_EQ(MOJO_RESULT_OK,
1336 local_mp->AddAwakable(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 789,
1337 nullptr));
1338
1339 // Write to the dispatcher.
1340 EXPECT_EQ(MOJO_RESULT_OK, dispatcher->WriteMessage(
1341 UserPointer<const void>(kHello), sizeof(kHello),
1342 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
1343
1344 // Wait.
1345 EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
1346 EXPECT_EQ(789u, context);
1347 hss = HandleSignalsState();
1348 local_mp->RemoveAwakable(1, &waiter, &hss);
1349 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
1350 hss.satisfied_signals);
1351 EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
1352
1353 // Read from "local_mp", port 1.
1354 memset(read_buffer, 0, sizeof(read_buffer));
1355 read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
1356 EXPECT_EQ(MOJO_RESULT_OK,
1357 local_mp->ReadMessage(1, UserPointer<void>(read_buffer),
1358 MakeUserPointer(&read_buffer_size), nullptr,
1359 nullptr, MOJO_READ_MESSAGE_FLAG_NONE));
1360 EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
1361 EXPECT_STREQ(kHello, read_buffer);
1362
1363 // TODO(vtl): Also test the cases where messages are written and read (at
1364 // various points) on the message pipe being passed around.
1365
1366 // Close everything that belongs to us.
1367 mp0->Close(0);
1368 mp1->Close(1);
1369 EXPECT_EQ(MOJO_RESULT_OK, dispatcher->Close());
1370 // Note that |local_mp|'s port 0 belong to |dispatcher|, which was closed.
1371 local_mp->Close(1);
1372 }
1373
1374 } // namespace
1375 } // namespace system
1376 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/raw_channel_win.cc ('k') | mojo/edk/system/run_all_unittests.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698