summaryrefslogtreecommitdiffstats
path: root/mojo
diff options
context:
space:
mode:
authoramistry <amistry@chromium.org>2016-02-11 04:07:00 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-11 12:08:26 +0000
commit78ceecffbe6dd93b0f27e7b35342fd576bbc66e7 (patch)
treebe9877567dad835a2d8b32d877e86b500d62e17f /mojo
parent014d75d0a8a332d391b230b917be7592693c5204 (diff)
downloadchromium_src-78ceecffbe6dd93b0f27e7b35342fd576bbc66e7.zip
chromium_src-78ceecffbe6dd93b0f27e7b35342fd576bbc66e7.tar.gz
chromium_src-78ceecffbe6dd93b0f27e7b35342fd576bbc66e7.tar.bz2
Add a Mojo embedder API that wraps a base::SharedMemoryHandle into a Mojo shared buffer handle.
BUG=582993 Review URL: https://codereview.chromium.org/1689063002 Cr-Commit-Position: refs/heads/master@{#374885}
Diffstat (limited to 'mojo')
-rw-r--r--mojo/edk/embedder/embedder.cc9
-rw-r--r--mojo/edk/embedder/embedder.h14
-rw-r--r--mojo/edk/embedder/embedder_unittest.cc85
-rw-r--r--mojo/edk/embedder/platform_support.h5
-rw-r--r--mojo/edk/embedder/simple_platform_shared_buffer.cc28
-rw-r--r--mojo/edk/embedder/simple_platform_shared_buffer.h8
-rw-r--r--mojo/edk/embedder/simple_platform_shared_buffer_unittest.cc34
-rw-r--r--mojo/edk/embedder/simple_platform_support.cc9
-rw-r--r--mojo/edk/embedder/simple_platform_support.h4
-rw-r--r--mojo/edk/system/core.cc25
-rw-r--r--mojo/edk/system/core.h8
-rw-r--r--mojo/edk/system/shared_buffer_dispatcher.cc11
-rw-r--r--mojo/edk/system/shared_buffer_dispatcher.h5
-rw-r--r--mojo/edk/system/shared_buffer_dispatcher_unittest.cc37
14 files changed, 281 insertions, 1 deletions
diff --git a/mojo/edk/embedder/embedder.cc b/mojo/edk/embedder/embedder.cc
index 37c3ddc..0ed4b4c 100644
--- a/mojo/edk/embedder/embedder.cc
+++ b/mojo/edk/embedder/embedder.cc
@@ -81,6 +81,15 @@ MojoResult PassWrappedPlatformHandle(MojoHandle platform_handle_wrapper_handle,
platform_handle_wrapper_handle, platform_handle);
}
+MojoResult CreateSharedBufferWrapper(
+ base::SharedMemoryHandle shared_memory_handle,
+ size_t num_bytes,
+ bool read_only,
+ MojoHandle* mojo_wrapper_handle) {
+ return internal::g_core->CreateSharedBufferWrapper(
+ shared_memory_handle, num_bytes, read_only, mojo_wrapper_handle);
+}
+
void InitIPCSupport(ProcessDelegate* process_delegate,
scoped_refptr<base::TaskRunner> io_thread_task_runner) {
CHECK(internal::g_core);
diff --git a/mojo/edk/embedder/embedder.h b/mojo/edk/embedder/embedder.h
index 1adbc79..6c010f4 100644
--- a/mojo/edk/embedder/embedder.h
+++ b/mojo/edk/embedder/embedder.h
@@ -13,6 +13,7 @@
#include "base/command_line.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/shared_memory_handle.h"
#include "base/process/process_handle.h"
#include "base/task_runner.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
@@ -80,6 +81,19 @@ MOJO_SYSTEM_IMPL_EXPORT MojoResult
PassWrappedPlatformHandle(MojoHandle platform_handle_wrapper_handle,
ScopedPlatformHandle* platform_handle);
+// Creates a |MojoHandle| that wraps the given |SharedMemoryHandle| (taking
+// ownership of it). |num_bytes| is the size of the shared memory object, and
+// |read_only| is whether the handle is a read-only handle to shared memory.
+// This |MojoHandle| is a Mojo shared buffer and can be manipulated using the
+// shared buffer functions and transferred over a message pipe.
+// TODO(crbug.com/556587): Support read-only handles. Currently, |read_only|
+// must be false.
+MOJO_SYSTEM_IMPL_EXPORT MojoResult
+CreateSharedBufferWrapper(base::SharedMemoryHandle shared_memory_handle,
+ size_t num_bytes,
+ bool read_only,
+ MojoHandle* mojo_wrapper_handle);
+
// Initialialization/shutdown for interprocess communication (IPC) -------------
// |InitIPCSupport()| sets up the subsystem for interprocess communication,
diff --git a/mojo/edk/embedder/embedder_unittest.cc b/mojo/edk/embedder/embedder_unittest.cc
index 86cfc5b..10d3677b 100644
--- a/mojo/edk/embedder/embedder_unittest.cc
+++ b/mojo/edk/embedder/embedder_unittest.cc
@@ -6,16 +6,17 @@
#include <stddef.h>
#include <stdint.h>
+#include <string.h>
#include <utility>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
+#include "base/memory/shared_memory.h"
#include "base/message_loop/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/test_timeouts.h"
-#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/embedder/platform_channel_pair.h"
#include "mojo/edk/embedder/simple_platform_support.h"
#include "mojo/edk/embedder/test_embedder.h"
@@ -39,6 +40,12 @@ const MojoHandleSignals kSignalAll = MOJO_HANDLE_SIGNAL_READABLE |
MOJO_HANDLE_SIGNAL_WRITABLE |
MOJO_HANDLE_SIGNAL_PEER_CLOSED;
+// The multiprocess tests that use these don't compile on iOS.
+#if !defined(OS_IOS)
+const char kHelloWorld[] = "hello world";
+const char kByeWorld[] = "bye world";
+#endif
+
using EmbedderTest = test::MojoTestBase;
TEST_F(EmbedderTest, ChannelBasic) {
@@ -284,6 +291,82 @@ DEFINE_TEST_CLIENT_TEST_WITH_PIPE(MultiprocessChannelsClient, EmbedderTest,
ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp1));
}
+#if defined(OS_ANDROID)
+// Android multi-process tests are not executing the new process. This is flaky.
+#define MAYBE_MultiprocessBaseSharedMemory DISABLED_MultiprocessBaseSharedMemory
+#else
+#define MAYBE_MultiprocessBaseSharedMemory MultiprocessBaseSharedMemory
+#endif // defined(OS_ANDROID)
+TEST_F(EmbedderTest, MAYBE_MultiprocessBaseSharedMemory) {
+ RUN_CHILD_ON_PIPE(MultiprocessSharedMemoryClient, server_mp)
+ // 1. Create a base::SharedMemory object and create a mojo shared buffer
+ // from it.
+ base::SharedMemoryCreateOptions options;
+ options.size = 123;
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ options.type = base::SharedMemoryHandle::POSIX;
+#endif
+ base::SharedMemory shared_memory;
+ ASSERT_TRUE(shared_memory.Create(options));
+ base::SharedMemoryHandle shm_handle = base::SharedMemory::DuplicateHandle(
+ shared_memory.handle());
+ MojoHandle sb1;
+ ASSERT_EQ(MOJO_RESULT_OK,
+ CreateSharedBufferWrapper(shm_handle, 123, false, &sb1));
+
+ // 2. Map |sb1| and write something into it.
+ char* buffer = nullptr;
+ ASSERT_EQ(MOJO_RESULT_OK,
+ MojoMapBuffer(sb1, 0, 123, reinterpret_cast<void**>(&buffer), 0));
+ ASSERT_TRUE(buffer);
+ memcpy(buffer, kHelloWorld, sizeof(kHelloWorld));
+
+ // 3. Duplicate |sb1| into |sb2| and pass to |server_mp|.
+ MojoHandle sb2 = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_OK, MojoDuplicateBufferHandle(sb1, 0, &sb2));
+ EXPECT_NE(MOJO_HANDLE_INVALID, sb2);
+ WriteMessageWithHandles(server_mp, "hello", &sb2, 1);
+
+ // 4. Read a message from |server_mp|.
+ EXPECT_EQ("bye", ReadMessage(server_mp));
+
+ // 5. Expect that the contents of the shared buffer have changed.
+ EXPECT_EQ(kByeWorld, std::string(buffer));
+
+ // 6. Map the original base::SharedMemory and expect it contains the
+ // expected value.
+ ASSERT_TRUE(shared_memory.Map(123));
+ EXPECT_EQ(kByeWorld,
+ std::string(static_cast<char*>(shared_memory.memory())));
+
+ ASSERT_EQ(MOJO_RESULT_OK, MojoClose(sb1));
+ END_CHILD()
+}
+
+DEFINE_TEST_CLIENT_TEST_WITH_PIPE(MultiprocessSharedMemoryClient, EmbedderTest,
+ client_mp) {
+ // 1. Read the first message from |client_mp|, which should have |sb1| which
+ // should be a shared buffer handle.
+ MojoHandle sb1;
+ EXPECT_EQ("hello", ReadMessageWithHandles(client_mp, &sb1, 1));
+
+ // 2. Map |sb1|.
+ char* buffer = nullptr;
+ ASSERT_EQ(MOJO_RESULT_OK,
+ MojoMapBuffer(sb1, 0, 123, reinterpret_cast<void**>(&buffer), 0));
+ ASSERT_TRUE(buffer);
+
+ // 3. Ensure |buffer| contains the values we expect.
+ EXPECT_EQ(kHelloWorld, std::string(buffer));
+
+ // 4. Write into |buffer| and send a message back.
+ memcpy(buffer, kByeWorld, sizeof(kByeWorld));
+ WriteMessage(client_mp, "bye");
+
+ // 5. Close |sb1|.
+ EXPECT_EQ(MOJO_RESULT_OK, MojoClose(sb1));
+}
+
// TODO(vtl): Test immediate write & close.
// TODO(vtl): Test broken-connection cases.
diff --git a/mojo/edk/embedder/platform_support.h b/mojo/edk/embedder/platform_support.h
index 160ba79..bc11289 100644
--- a/mojo/edk/embedder/platform_support.h
+++ b/mojo/edk/embedder/platform_support.h
@@ -7,6 +7,7 @@
#include <stddef.h>
+#include "base/memory/shared_memory_handle.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
#include "mojo/edk/system/system_impl_export.h"
#include "mojo/public/cpp/system/macros.h"
@@ -29,6 +30,10 @@ class MOJO_SYSTEM_IMPL_EXPORT PlatformSupport {
virtual PlatformSharedBuffer* CreateSharedBufferFromHandle(
size_t num_bytes,
ScopedPlatformHandle platform_handle) = 0;
+ virtual PlatformSharedBuffer* CreateSharedBufferFromSharedMemoryHandle(
+ size_t num_bytes,
+ bool read_only,
+ base::SharedMemoryHandle handle) = 0;
protected:
PlatformSupport() {}
diff --git a/mojo/edk/embedder/simple_platform_shared_buffer.cc b/mojo/edk/embedder/simple_platform_shared_buffer.cc
index caa926c..5a18131 100644
--- a/mojo/edk/embedder/simple_platform_shared_buffer.cc
+++ b/mojo/edk/embedder/simple_platform_shared_buffer.cc
@@ -69,6 +69,21 @@ SimplePlatformSharedBuffer::CreateFromPlatformHandle(
return rv;
}
+// static
+SimplePlatformSharedBuffer*
+SimplePlatformSharedBuffer::CreateFromSharedMemoryHandle(
+ size_t num_bytes,
+ bool read_only,
+ base::SharedMemoryHandle handle) {
+ DCHECK_GT(num_bytes, 0u);
+ DCHECK(!read_only);
+
+ SimplePlatformSharedBuffer* rv = new SimplePlatformSharedBuffer(num_bytes);
+ rv->InitFromSharedMemoryHandle(handle);
+
+ return rv;
+}
+
size_t SimplePlatformSharedBuffer::GetNumBytes() const {
return num_bytes_;
}
@@ -176,6 +191,19 @@ bool SimplePlatformSharedBuffer::InitFromPlatformHandle(
return true;
}
+void SimplePlatformSharedBuffer::InitFromSharedMemoryHandle(
+ base::SharedMemoryHandle handle) {
+ DCHECK(!shared_memory_);
+
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ // TODO(crbug.com/582468): Support Mach shared memory.
+ CHECK(handle.GetType() == base::SharedMemoryHandle::POSIX);
+#endif
+
+ // TODO(crbug.com/556587): Support read-only handles.
+ shared_memory_.reset(new base::SharedMemory(handle, false));
+}
+
SimplePlatformSharedBufferMapping::~SimplePlatformSharedBufferMapping() {
Unmap();
}
diff --git a/mojo/edk/embedder/simple_platform_shared_buffer.h b/mojo/edk/embedder/simple_platform_shared_buffer.h
index 068f668..0f68bc2 100644
--- a/mojo/edk/embedder/simple_platform_shared_buffer.h
+++ b/mojo/edk/embedder/simple_platform_shared_buffer.h
@@ -9,6 +9,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/shared_memory.h"
+#include "base/memory/shared_memory_handle.h"
#include "base/synchronization/lock.h"
#include "mojo/edk/embedder/platform_shared_buffer.h"
#include "mojo/edk/system/system_impl_export.h"
@@ -30,6 +31,11 @@ class MOJO_SYSTEM_IMPL_EXPORT SimplePlatformSharedBuffer final
size_t num_bytes,
ScopedPlatformHandle platform_handle);
+ static SimplePlatformSharedBuffer* CreateFromSharedMemoryHandle(
+ size_t num_bytes,
+ bool read_only,
+ base::SharedMemoryHandle handle);
+
// |PlatformSharedBuffer| implementation:
size_t GetNumBytes() const override;
scoped_ptr<PlatformSharedBufferMapping> Map(size_t offset,
@@ -52,6 +58,8 @@ class MOJO_SYSTEM_IMPL_EXPORT SimplePlatformSharedBuffer final
// claimed |num_bytes_|.)
bool InitFromPlatformHandle(ScopedPlatformHandle platform_handle);
+ void InitFromSharedMemoryHandle(base::SharedMemoryHandle handle);
+
const size_t num_bytes_;
base::Lock lock_;
diff --git a/mojo/edk/embedder/simple_platform_shared_buffer_unittest.cc b/mojo/edk/embedder/simple_platform_shared_buffer_unittest.cc
index 4924372..99bfa6e 100644
--- a/mojo/edk/embedder/simple_platform_shared_buffer_unittest.cc
+++ b/mojo/edk/embedder/simple_platform_shared_buffer_unittest.cc
@@ -10,6 +10,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/shared_memory.h"
#include "base/sys_info.h"
#include "mojo/public/cpp/system/macros.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -192,6 +193,39 @@ TEST(SimplePlatformSharedBufferTest, MappingsOutliveBuffer) {
EXPECT_EQ('y', static_cast<char*>(mapping1->GetBase())[51]);
}
+TEST(SimplePlatformSharedBufferTest, FromSharedMemoryHandle) {
+ const size_t kBufferSize = 1234;
+ base::SharedMemoryCreateOptions options;
+ options.size = kBufferSize;
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ options.type = base::SharedMemoryHandle::POSIX;
+#endif
+ base::SharedMemory shared_memory;
+ ASSERT_TRUE(shared_memory.Create(options));
+ ASSERT_TRUE(shared_memory.Map(kBufferSize));
+
+ base::SharedMemoryHandle shm_handle =
+ base::SharedMemory::DuplicateHandle(shared_memory.handle());
+ scoped_refptr<SimplePlatformSharedBuffer> simple_buffer(
+ SimplePlatformSharedBuffer::CreateFromSharedMemoryHandle(
+ kBufferSize, false /* read_only */, shm_handle));
+ ASSERT_TRUE(simple_buffer);
+
+ scoped_ptr<PlatformSharedBufferMapping> mapping =
+ simple_buffer->Map(0, kBufferSize);
+ ASSERT_TRUE(mapping);
+
+ const int kOffset = 123;
+ char* base_memory = static_cast<char*>(shared_memory.memory());
+ char* mojo_memory = static_cast<char*>(mapping->GetBase());
+ base_memory[kOffset] = 0;
+ EXPECT_EQ(0, mojo_memory[kOffset]);
+ base_memory[kOffset] = 'a';
+ EXPECT_EQ('a', mojo_memory[kOffset]);
+ mojo_memory[kOffset] = 'z';
+ EXPECT_EQ('z', base_memory[kOffset]);
+}
+
} // namespace
} // namespace edk
} // namespace mojo
diff --git a/mojo/edk/embedder/simple_platform_support.cc b/mojo/edk/embedder/simple_platform_support.cc
index b377bf2..6c2de1a 100644
--- a/mojo/edk/embedder/simple_platform_support.cc
+++ b/mojo/edk/embedder/simple_platform_support.cc
@@ -31,5 +31,14 @@ PlatformSharedBuffer* SimplePlatformSupport::CreateSharedBufferFromHandle(
num_bytes, std::move(platform_handle));
}
+PlatformSharedBuffer*
+SimplePlatformSupport::CreateSharedBufferFromSharedMemoryHandle(
+ size_t num_bytes,
+ bool read_only,
+ base::SharedMemoryHandle handle) {
+ return SimplePlatformSharedBuffer::CreateFromSharedMemoryHandle(
+ num_bytes, read_only, handle);
+}
+
} // namespace edk
} // namespace mojo
diff --git a/mojo/edk/embedder/simple_platform_support.h b/mojo/edk/embedder/simple_platform_support.h
index 0c00098..d79e8ff 100644
--- a/mojo/edk/embedder/simple_platform_support.h
+++ b/mojo/edk/embedder/simple_platform_support.h
@@ -30,6 +30,10 @@ class MOJO_SYSTEM_IMPL_EXPORT SimplePlatformSupport final
PlatformSharedBuffer* CreateSharedBufferFromHandle(
size_t num_bytes,
ScopedPlatformHandle platform_handle) override;
+ PlatformSharedBuffer* CreateSharedBufferFromSharedMemoryHandle(
+ size_t num_bytes,
+ bool read_only,
+ base::SharedMemoryHandle handle) override;
private:
MOJO_DISALLOW_COPY_AND_ASSIGN(SimplePlatformSupport);
diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc
index d0b7b67..079faec 100644
--- a/mojo/edk/system/core.cc
+++ b/mojo/edk/system/core.cc
@@ -138,6 +138,31 @@ MojoResult Core::PassWrappedPlatformHandle(
return MOJO_RESULT_OK;
}
+MojoResult Core::CreateSharedBufferWrapper(
+ base::SharedMemoryHandle shared_memory_handle,
+ size_t num_bytes,
+ bool read_only,
+ MojoHandle* mojo_wrapper_handle) {
+ DCHECK(num_bytes);
+ CHECK(!read_only);
+ scoped_refptr<PlatformSharedBuffer> platform_buffer =
+ internal::g_platform_support->CreateSharedBufferFromSharedMemoryHandle(
+ num_bytes, read_only, shared_memory_handle);
+ if (!platform_buffer)
+ return MOJO_RESULT_UNKNOWN;
+
+ scoped_refptr<SharedBufferDispatcher> dispatcher;
+ MojoResult result = SharedBufferDispatcher::CreateFromPlatformSharedBuffer(
+ platform_buffer, &dispatcher);
+ if (result != MOJO_RESULT_OK)
+ return result;
+ MojoHandle h = AddDispatcher(dispatcher);
+ if (h == MOJO_HANDLE_INVALID)
+ return MOJO_RESULT_RESOURCE_EXHAUSTED;
+ *mojo_wrapper_handle = h;
+ return MOJO_RESULT_OK;
+}
+
void Core::RequestShutdown(const base::Closure& callback) {
base::Closure on_shutdown;
if (base::ThreadTaskRunnerHandle::IsSet()) {
diff --git a/mojo/edk/system/core.h b/mojo/edk/system/core.h
index 603cba9..0e08a8c 100644
--- a/mojo/edk/system/core.h
+++ b/mojo/edk/system/core.h
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/shared_memory_handle.h"
#include "base/synchronization/lock.h"
#include "base/task_runner.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
@@ -74,12 +75,19 @@ class MOJO_SYSTEM_IMPL_EXPORT Core {
const std::vector<Dispatcher::DispatcherInTransit>& dispatchers,
MojoHandle* handles);
+ // See "mojo/edk/embedder/embedder.h" for more information on these functions.
MojoResult CreatePlatformHandleWrapper(ScopedPlatformHandle platform_handle,
MojoHandle* wrapper_handle);
MojoResult PassWrappedPlatformHandle(MojoHandle wrapper_handle,
ScopedPlatformHandle* platform_handle);
+ MojoResult CreateSharedBufferWrapper(
+ base::SharedMemoryHandle shared_memory_handle,
+ size_t num_bytes,
+ bool read_only,
+ MojoHandle* mojo_wrapper_handle);
+
// Requests that the EDK tear itself down. |callback| will be called once
// the shutdown process is complete. Note that |callback| is always called
// asynchronously on the calling thread if said thread is running a message
diff --git a/mojo/edk/system/shared_buffer_dispatcher.cc b/mojo/edk/system/shared_buffer_dispatcher.cc
index 94b3d28..8b3971f 100644
--- a/mojo/edk/system/shared_buffer_dispatcher.cc
+++ b/mojo/edk/system/shared_buffer_dispatcher.cc
@@ -84,6 +84,17 @@ MojoResult SharedBufferDispatcher::Create(
}
// static
+MojoResult SharedBufferDispatcher::CreateFromPlatformSharedBuffer(
+ const scoped_refptr<PlatformSharedBuffer>& shared_buffer,
+ scoped_refptr<SharedBufferDispatcher>* result) {
+ if (!shared_buffer)
+ return MOJO_RESULT_INVALID_ARGUMENT;
+
+ *result = CreateInternal(shared_buffer);
+ return MOJO_RESULT_OK;
+}
+
+// static
scoped_refptr<SharedBufferDispatcher> SharedBufferDispatcher::Deserialize(
const void* bytes,
size_t num_bytes,
diff --git a/mojo/edk/system/shared_buffer_dispatcher.h b/mojo/edk/system/shared_buffer_dispatcher.h
index e8b6420..75c31b8 100644
--- a/mojo/edk/system/shared_buffer_dispatcher.h
+++ b/mojo/edk/system/shared_buffer_dispatcher.h
@@ -48,6 +48,11 @@ class MOJO_SYSTEM_IMPL_EXPORT SharedBufferDispatcher final : public Dispatcher {
uint64_t num_bytes,
scoped_refptr<SharedBufferDispatcher>* result);
+ // Create a |SharedBufferDispatcher| from |shared_buffer|.
+ static MojoResult CreateFromPlatformSharedBuffer(
+ const scoped_refptr<PlatformSharedBuffer>& shared_buffer,
+ scoped_refptr<SharedBufferDispatcher>* result);
+
// The "opposite" of SerializeAndClose(). Called by Dispatcher::Deserialize().
static scoped_refptr<SharedBufferDispatcher> Deserialize(
const void* bytes,
diff --git a/mojo/edk/system/shared_buffer_dispatcher_unittest.cc b/mojo/edk/system/shared_buffer_dispatcher_unittest.cc
index 7ce119c..f3774fa 100644
--- a/mojo/edk/system/shared_buffer_dispatcher_unittest.cc
+++ b/mojo/edk/system/shared_buffer_dispatcher_unittest.cc
@@ -150,6 +150,43 @@ TEST_F(SharedBufferDispatcherTest, CreateAndMapBuffer) {
EXPECT_EQ('y', static_cast<char*>(mapping1->GetBase())[51]);
}
+TEST_F(SharedBufferDispatcherTest, CreateAndMapBufferFromPlatformBuffer) {
+ scoped_refptr<PlatformSharedBuffer> platform_shared_buffer =
+ platform_support()->CreateSharedBuffer(100);
+ ASSERT_TRUE(platform_shared_buffer);
+ scoped_refptr<SharedBufferDispatcher> dispatcher;
+ EXPECT_EQ(MOJO_RESULT_OK,
+ SharedBufferDispatcher::CreateFromPlatformSharedBuffer(
+ platform_shared_buffer, &dispatcher));
+ ASSERT_TRUE(dispatcher);
+ EXPECT_EQ(Dispatcher::Type::SHARED_BUFFER, dispatcher->GetType());
+
+ // Make a couple of mappings.
+ scoped_ptr<PlatformSharedBufferMapping> mapping1;
+ EXPECT_EQ(MOJO_RESULT_OK, dispatcher->MapBuffer(
+ 0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping1));
+ ASSERT_TRUE(mapping1);
+ ASSERT_TRUE(mapping1->GetBase());
+ EXPECT_EQ(100u, mapping1->GetLength());
+ // Write something.
+ static_cast<char*>(mapping1->GetBase())[50] = 'x';
+
+ scoped_ptr<PlatformSharedBufferMapping> mapping2;
+ EXPECT_EQ(MOJO_RESULT_OK, dispatcher->MapBuffer(
+ 50, 50, MOJO_MAP_BUFFER_FLAG_NONE, &mapping2));
+ ASSERT_TRUE(mapping2);
+ ASSERT_TRUE(mapping2->GetBase());
+ EXPECT_EQ(50u, mapping2->GetLength());
+ EXPECT_EQ('x', static_cast<char*>(mapping2->GetBase())[0]);
+
+ EXPECT_EQ(MOJO_RESULT_OK, dispatcher->Close());
+
+ // Check that we can still read/write to mappings after the dispatcher has
+ // gone away.
+ static_cast<char*>(mapping2->GetBase())[1] = 'y';
+ EXPECT_EQ('y', static_cast<char*>(mapping1->GetBase())[51]);
+}
+
TEST_F(SharedBufferDispatcherTest, DuplicateBufferHandle) {
scoped_refptr<SharedBufferDispatcher> dispatcher1;
EXPECT_EQ(MOJO_RESULT_OK, SharedBufferDispatcher::Create(