| Index: mojo/system/remote_message_pipe_unittest.cc
|
| diff --git a/mojo/system/remote_message_pipe_unittest.cc b/mojo/system/remote_message_pipe_unittest.cc
|
| index 4b3991f4333ea3064b2d09112fbe25e4a9ef4b94..d3bb09049249d7263b15d75bd253a728d4ee7da4 100644
|
| --- a/mojo/system/remote_message_pipe_unittest.cc
|
| +++ b/mojo/system/remote_message_pipe_unittest.cc
|
| @@ -28,6 +28,7 @@
|
| #include "mojo/system/platform_handle_dispatcher.h"
|
| #include "mojo/system/proxy_message_pipe_endpoint.h"
|
| #include "mojo/system/raw_channel.h"
|
| +#include "mojo/system/shared_buffer_dispatcher.h"
|
| #include "mojo/system/test_utils.h"
|
| #include "mojo/system/waiter.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| @@ -563,6 +564,127 @@ TEST_F(RemoteMessagePipeTest, HandlePassing) {
|
| }
|
|
|
| #if defined(OS_POSIX)
|
| +#define MAYBE_SharedBufferPassing SharedBufferPassing
|
| +#else
|
| +// Not yet implemented (on Windows).
|
| +#define MAYBE_SharedBufferPassing DISABLED_SharedBufferPassing
|
| +#endif
|
| +TEST_F(RemoteMessagePipeTest, MAYBE_SharedBufferPassing) {
|
| + static const char kHello[] = "hello";
|
| + Waiter waiter;
|
| +
|
| + scoped_refptr<MessagePipe> mp0(new MessagePipe(
|
| + scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()),
|
| + scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint())));
|
| + scoped_refptr<MessagePipe> mp1(new MessagePipe(
|
| + scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()),
|
| + scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint())));
|
| + ConnectMessagePipes(mp0, mp1);
|
| +
|
| + // We'll try to pass this dispatcher.
|
| + scoped_refptr<SharedBufferDispatcher> dispatcher;
|
| + MojoCreateSharedBufferOptions validated_options = {};
|
| + EXPECT_EQ(MOJO_RESULT_OK,
|
| + SharedBufferDispatcher::ValidateOptions(NULL, &validated_options));
|
| + EXPECT_EQ(MOJO_RESULT_OK,
|
| + SharedBufferDispatcher::Create(validated_options, 100,
|
| + &dispatcher));
|
| + ASSERT_TRUE(dispatcher);
|
| +
|
| + // Make a mapping.
|
| + scoped_ptr<RawSharedBufferMapping> mapping0;
|
| + EXPECT_EQ(MOJO_RESULT_OK,
|
| + dispatcher->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE,
|
| + &mapping0));
|
| + ASSERT_TRUE(mapping0);
|
| + ASSERT_TRUE(mapping0->base());
|
| + ASSERT_EQ(100u, mapping0->length());
|
| + static_cast<char*>(mapping0->base())[0] = 'A';
|
| + static_cast<char*>(mapping0->base())[50] = 'B';
|
| + static_cast<char*>(mapping0->base())[99] = 'C';
|
| +
|
| + // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do
|
| + // it later, it might already be readable.)
|
| + waiter.Init();
|
| + EXPECT_EQ(MOJO_RESULT_OK,
|
| + mp1->AddWaiter(1, &waiter, MOJO_WAIT_FLAG_READABLE, 123));
|
| +
|
| + // Write to MP 0, port 0.
|
| + {
|
| + DispatcherTransport
|
| + transport(test::DispatcherTryStartTransport(dispatcher.get()));
|
| + EXPECT_TRUE(transport.is_valid());
|
| +
|
| + std::vector<DispatcherTransport> transports;
|
| + transports.push_back(transport);
|
| + EXPECT_EQ(MOJO_RESULT_OK,
|
| + mp0->WriteMessage(0, kHello, sizeof(kHello), &transports,
|
| + MOJO_WRITE_MESSAGE_FLAG_NONE));
|
| + transport.End();
|
| +
|
| + // |dispatcher| should have been closed. This is |DCHECK()|ed when the
|
| + // |dispatcher| is destroyed.
|
| + EXPECT_TRUE(dispatcher->HasOneRef());
|
| + dispatcher = NULL;
|
| + }
|
| +
|
| + // Wait.
|
| + EXPECT_EQ(123, waiter.Wait(MOJO_DEADLINE_INDEFINITE));
|
| + mp1->RemoveWaiter(1, &waiter);
|
| +
|
| + // Read from MP 1, port 1.
|
| + char read_buffer[100] = { 0 };
|
| + uint32_t read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
|
| + DispatcherVector read_dispatchers;
|
| + uint32_t read_num_dispatchers = 10; // Maximum to get.
|
| + EXPECT_EQ(MOJO_RESULT_OK,
|
| + mp1->ReadMessage(1, read_buffer, &read_buffer_size,
|
| + &read_dispatchers, &read_num_dispatchers,
|
| + MOJO_READ_MESSAGE_FLAG_NONE));
|
| + EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
|
| + EXPECT_STREQ(kHello, read_buffer);
|
| + EXPECT_EQ(1u, read_dispatchers.size());
|
| + EXPECT_EQ(1u, read_num_dispatchers);
|
| + ASSERT_TRUE(read_dispatchers[0]);
|
| + EXPECT_TRUE(read_dispatchers[0]->HasOneRef());
|
| +
|
| + EXPECT_EQ(Dispatcher::kTypeSharedBuffer, read_dispatchers[0]->GetType());
|
| + dispatcher =
|
| + static_cast<SharedBufferDispatcher*>(read_dispatchers[0].get());
|
| +
|
| + // Make another mapping.
|
| + scoped_ptr<RawSharedBufferMapping> mapping1;
|
| + EXPECT_EQ(MOJO_RESULT_OK,
|
| + dispatcher->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE,
|
| + &mapping1));
|
| + ASSERT_TRUE(mapping1);
|
| + ASSERT_TRUE(mapping1->base());
|
| + ASSERT_EQ(100u, mapping1->length());
|
| + EXPECT_NE(mapping1->base(), mapping0->base());
|
| + EXPECT_EQ('A', static_cast<char*>(mapping1->base())[0]);
|
| + EXPECT_EQ('B', static_cast<char*>(mapping1->base())[50]);
|
| + EXPECT_EQ('C', static_cast<char*>(mapping1->base())[99]);
|
| +
|
| + // Write stuff either way.
|
| + static_cast<char*>(mapping1->base())[1] = 'x';
|
| + EXPECT_EQ('x', static_cast<char*>(mapping0->base())[1]);
|
| + static_cast<char*>(mapping0->base())[2] = 'y';
|
| + EXPECT_EQ('y', static_cast<char*>(mapping1->base())[2]);
|
| +
|
| + // Kill the first mapping; the second should still be valid.
|
| + mapping0.reset();
|
| + EXPECT_EQ('A', static_cast<char*>(mapping1->base())[0]);
|
| +
|
| + // Close everything that belongs to us.
|
| + mp0->Close(0);
|
| + mp1->Close(1);
|
| + EXPECT_EQ(MOJO_RESULT_OK, dispatcher->Close());
|
| +
|
| + // The second mapping should still be good.
|
| + EXPECT_EQ('x', static_cast<char*>(mapping1->base())[1]);
|
| +}
|
| +
|
| +#if defined(OS_POSIX)
|
| #define MAYBE_PlatformHandlePassing PlatformHandlePassing
|
| #else
|
| // Not yet implemented (on Windows).
|
|
|