summaryrefslogtreecommitdiffstats
path: root/mojo/edk
diff options
context:
space:
mode:
authoramistry <amistry@chromium.org>2016-02-21 18:54:03 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-22 02:55:26 +0000
commitaf22d8630a5ded9cd9ce5f1cdc4a66132ec507ed (patch)
tree9d3337b3419b0b58f954055adf8d6b05e5721f73 /mojo/edk
parent05bb3a24ac49d7fbfff7eb6885a1d96b83e40064 (diff)
downloadchromium_src-af22d8630a5ded9cd9ce5f1cdc4a66132ec507ed.zip
chromium_src-af22d8630a5ded9cd9ce5f1cdc4a66132ec507ed.tar.gz
chromium_src-af22d8630a5ded9cd9ce5f1cdc4a66132ec507ed.tar.bz2
[mojo-edk] Embedder API for MojoHandle to base::SharedMemoryHandle.
Add an embedder function that retrieves a base::SharedMemoryHandle from a shared buffer MojoHandle. The MojoHandle is closed as a result. BUG=588268,582993 Review URL: https://codereview.chromium.org/1718963002 Cr-Commit-Position: refs/heads/master@{#376679}
Diffstat (limited to 'mojo/edk')
-rw-r--r--mojo/edk/embedder/embedder.cc9
-rw-r--r--mojo/edk/embedder/embedder.h15
-rw-r--r--mojo/edk/embedder/embedder_unittest.cc15
-rw-r--r--mojo/edk/embedder/platform_shared_buffer.cc7
-rw-r--r--mojo/edk/embedder/platform_shared_buffer.h3
-rw-r--r--mojo/edk/system/core.cc42
-rw-r--r--mojo/edk/system/core.h6
-rw-r--r--mojo/edk/system/shared_buffer_dispatcher.cc13
-rw-r--r--mojo/edk/system/shared_buffer_dispatcher.h4
9 files changed, 111 insertions, 3 deletions
diff --git a/mojo/edk/embedder/embedder.cc b/mojo/edk/embedder/embedder.cc
index 1feadda..62702af 100644
--- a/mojo/edk/embedder/embedder.cc
+++ b/mojo/edk/embedder/embedder.cc
@@ -87,6 +87,15 @@ MojoResult CreateSharedBufferWrapper(
shared_memory_handle, num_bytes, read_only, mojo_wrapper_handle);
}
+MojoResult PassSharedMemoryHandle(
+ MojoHandle mojo_handle,
+ base::SharedMemoryHandle* shared_memory_handle,
+ size_t* num_bytes,
+ bool* read_only) {
+ return internal::g_core->PassSharedMemoryHandle(
+ mojo_handle, shared_memory_handle, num_bytes, read_only);
+}
+
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 e34ef5c..95b3b21 100644
--- a/mojo/edk/embedder/embedder.h
+++ b/mojo/edk/embedder/embedder.h
@@ -94,6 +94,21 @@ CreateSharedBufferWrapper(base::SharedMemoryHandle shared_memory_handle,
bool read_only,
MojoHandle* mojo_wrapper_handle);
+// Retrieves the underlying |SharedMemoryHandle| from a shared buffer
+// |MojoHandle| and closes the handle. If successful, |num_bytes| will contain
+// the size of the shared memory buffer and |read_only| will contain whether the
+// buffer handle is read-only. Both |num_bytes| and |read_only| may be null.
+// Note: The value of |shared_memory_handle| may be
+// base::SharedMemory::NULLHandle(), even if this function returns success.
+// Callers should perform appropriate checks.
+// TODO(crbug.com/556587): Support read-only handles. Currently, |read_only|
+// will always return |false|.
+MOJO_SYSTEM_IMPL_EXPORT MojoResult
+PassSharedMemoryHandle(MojoHandle mojo_handle,
+ base::SharedMemoryHandle* shared_memory_handle,
+ size_t* num_bytes,
+ bool* read_only);
+
// 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 1a36378..9b96c1f 100644
--- a/mojo/edk/embedder/embedder_unittest.cc
+++ b/mojo/edk/embedder/embedder_unittest.cc
@@ -362,8 +362,19 @@ DEFINE_TEST_CLIENT_TEST_WITH_PIPE(MultiprocessSharedMemoryClient, EmbedderTest,
memcpy(buffer, kByeWorld, sizeof(kByeWorld));
WriteMessage(client_mp, "bye");
- // 5. Close |sb1|.
- EXPECT_EQ(MOJO_RESULT_OK, MojoClose(sb1));
+ // 5. Extract the shared memory handle and ensure we can map it and read the
+ // contents.
+ base::SharedMemoryHandle shm_handle;
+ ASSERT_EQ(MOJO_RESULT_OK,
+ PassSharedMemoryHandle(sb1, &shm_handle, nullptr, nullptr));
+ base::SharedMemory shared_memory(shm_handle, false);
+ ASSERT_TRUE(shared_memory.Map(123));
+ EXPECT_NE(buffer, shared_memory.memory());
+ EXPECT_EQ(kByeWorld, std::string(static_cast<char*>(shared_memory.memory())));
+
+ // 6. Close |sb1|. Should fail because |PassSharedMemoryHandle()| should have
+ // closed the handle.
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(sb1));
}
// TODO(vtl): Test immediate write & close.
diff --git a/mojo/edk/embedder/platform_shared_buffer.cc b/mojo/edk/embedder/platform_shared_buffer.cc
index 9dce8d5..bbcf15d 100644
--- a/mojo/edk/embedder/platform_shared_buffer.cc
+++ b/mojo/edk/embedder/platform_shared_buffer.cc
@@ -152,6 +152,13 @@ ScopedPlatformHandle PlatformSharedBuffer::PassPlatformHandle() {
return handle;
}
+base::SharedMemoryHandle PlatformSharedBuffer::DuplicateSharedMemoryHandle() {
+ DCHECK(shared_memory_);
+
+ base::AutoLock locker(lock_);
+ return base::SharedMemory::DuplicateHandle(shared_memory_->handle());
+}
+
PlatformSharedBuffer::PlatformSharedBuffer(size_t num_bytes)
: num_bytes_(num_bytes) {}
diff --git a/mojo/edk/embedder/platform_shared_buffer.h b/mojo/edk/embedder/platform_shared_buffer.h
index 623fb9e..5494122 100644
--- a/mojo/edk/embedder/platform_shared_buffer.h
+++ b/mojo/edk/embedder/platform_shared_buffer.h
@@ -74,6 +74,9 @@ class MOJO_SYSTEM_IMPL_EXPORT PlatformSharedBuffer
// TODO(vtl): On POSIX, we'll need two FDs to support sharing read-only.
ScopedPlatformHandle DuplicatePlatformHandle();
+ // Duplicates the underlying shared memory handle and passes it to the caller.
+ base::SharedMemoryHandle DuplicateSharedMemoryHandle();
+
// Passes the underlying platform handle to the caller. This should only be
// called if there's a unique reference to this object (owned by the caller).
// After calling this, this object should no longer be used, but should only
diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc
index 11892be..69c918c 100644
--- a/mojo/edk/system/core.cc
+++ b/mojo/edk/system/core.cc
@@ -163,6 +163,48 @@ MojoResult Core::CreateSharedBufferWrapper(
return MOJO_RESULT_OK;
}
+MojoResult Core::PassSharedMemoryHandle(
+ MojoHandle mojo_handle,
+ base::SharedMemoryHandle* shared_memory_handle,
+ size_t* num_bytes,
+ bool* read_only) {
+ if (!shared_memory_handle)
+ return MOJO_RESULT_INVALID_ARGUMENT;
+
+ scoped_refptr<Dispatcher> dispatcher;
+ MojoResult result = MOJO_RESULT_OK;
+ {
+ base::AutoLock lock(handles_lock_);
+ // Get the dispatcher and check it before removing it from the handle table
+ // to ensure that the dispatcher is of the correct type. This ensures we
+ // don't close and remove the wrong type of dispatcher.
+ dispatcher = handles_.GetDispatcher(mojo_handle);
+ if (!dispatcher || dispatcher->GetType() != Dispatcher::Type::SHARED_BUFFER)
+ return MOJO_RESULT_INVALID_ARGUMENT;
+
+ result = handles_.GetAndRemoveDispatcher(mojo_handle, &dispatcher);
+ if (result != MOJO_RESULT_OK)
+ return result;
+ }
+
+ SharedBufferDispatcher* shm_dispatcher =
+ static_cast<SharedBufferDispatcher*>(dispatcher.get());
+ scoped_refptr<PlatformSharedBuffer> platform_shared_buffer =
+ shm_dispatcher->PassPlatformSharedBuffer();
+
+ if (!platform_shared_buffer)
+ return MOJO_RESULT_INVALID_ARGUMENT;
+
+ if (num_bytes)
+ *num_bytes = platform_shared_buffer->GetNumBytes();
+ if (read_only)
+ *read_only = false;
+ *shared_memory_handle = platform_shared_buffer->DuplicateSharedMemoryHandle();
+
+ shm_dispatcher->Close();
+ return result;
+}
+
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 938726a..e2a22b0 100644
--- a/mojo/edk/system/core.h
+++ b/mojo/edk/system/core.h
@@ -88,6 +88,12 @@ class MOJO_SYSTEM_IMPL_EXPORT Core {
bool read_only,
MojoHandle* mojo_wrapper_handle);
+ MojoResult PassSharedMemoryHandle(
+ MojoHandle mojo_handle,
+ base::SharedMemoryHandle* shared_memory_handle,
+ size_t* num_bytes,
+ bool* read_only);
+
// 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 1484166..1805a92 100644
--- a/mojo/edk/system/shared_buffer_dispatcher.cc
+++ b/mojo/edk/system/shared_buffer_dispatcher.cc
@@ -139,13 +139,24 @@ scoped_refptr<SharedBufferDispatcher> SharedBufferDispatcher::Deserialize(
return CreateInternal(std::move(shared_buffer));
}
+scoped_refptr<PlatformSharedBuffer>
+SharedBufferDispatcher::PassPlatformSharedBuffer() {
+ base::AutoLock lock(lock_);
+ if (!shared_buffer_ || in_transit_)
+ return nullptr;
+
+ scoped_refptr<PlatformSharedBuffer> retval = shared_buffer_;
+ shared_buffer_ = nullptr;
+ return retval;
+}
+
Dispatcher::Type SharedBufferDispatcher::GetType() const {
return Type::SHARED_BUFFER;
}
MojoResult SharedBufferDispatcher::Close() {
base::AutoLock lock(lock_);
- if (!shared_buffer_ || in_transit_)
+ if (in_transit_)
return MOJO_RESULT_INVALID_ARGUMENT;
shared_buffer_ = nullptr;
diff --git a/mojo/edk/system/shared_buffer_dispatcher.h b/mojo/edk/system/shared_buffer_dispatcher.h
index 011a43a..a8d5bcd 100644
--- a/mojo/edk/system/shared_buffer_dispatcher.h
+++ b/mojo/edk/system/shared_buffer_dispatcher.h
@@ -61,6 +61,10 @@ class MOJO_SYSTEM_IMPL_EXPORT SharedBufferDispatcher final : public Dispatcher {
PlatformHandle* platform_handles,
size_t num_platform_handles);
+ // Passes the underlying platform shared buffer. This dispatcher must be
+ // closed after calling this function.
+ scoped_refptr<PlatformSharedBuffer> PassPlatformSharedBuffer();
+
// Dispatcher:
Type GetType() const override;
MojoResult Close() override;