Commit 062470b4 authored by Ken Rockot's avatar Ken Rockot Committed by Commit Bot

Add mojo base types for new shared memory APIs

Adds mojom equivalents of {ReadOnly,Writable,Unsafe}SharedMemoryRegion.
These are typemapped to the new base types.

The typemap implementation is currently written by wrapping and
unwrapping generic platform handles rather than relying on Mojo's
shared buffer implementation.

Existing mojom shared buffer handle consumers will be converted to use
these types in place of raw handle<shared_buffer>. The (mojom) types
here will eventually wrap handle<shared_buffer> instead of raw platform
handles.

This is to ease the transition to new shared memory semantics while
also getting us something we want, i.e., stronger shared memory type
safety for common mojom uses.

Bug: 826213
Change-Id: Iba36758b70953492997e744eeecaf7b7403627fc
Reviewed-on: https://chromium-review.googlesource.com/982577Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Ken Rockot <rockot@chromium.org>
Cr-Commit-Position: refs/heads/master@{#547104}
parent df5b1e1f
......@@ -79,7 +79,7 @@ ReadOnlySharedMemoryMapping ReadOnlySharedMemoryRegion::MapAt(off_t offset,
return ReadOnlySharedMemoryMapping(memory, mapped_size, handle_.GetGUID());
}
bool ReadOnlySharedMemoryRegion::IsValid() {
bool ReadOnlySharedMemoryRegion::IsValid() const {
return handle_.IsValid();
}
......
......@@ -78,10 +78,10 @@ class BASE_EXPORT ReadOnlySharedMemoryRegion {
ReadOnlySharedMemoryMapping MapAt(off_t offset, size_t size);
// Whether the underlying platform handle is valid.
bool IsValid();
bool IsValid() const;
// Returns the maximum mapping size that can be created from this region.
size_t GetSize() {
size_t GetSize() const {
DCHECK(IsValid());
return handle_.GetSize();
}
......
......@@ -59,7 +59,7 @@ WritableSharedMemoryMapping UnsafeSharedMemoryRegion::MapAt(off_t offset,
return WritableSharedMemoryMapping(memory, mapped_size, handle_.GetGUID());
}
bool UnsafeSharedMemoryRegion::IsValid() {
bool UnsafeSharedMemoryRegion::IsValid() const {
return handle_.IsValid();
}
......
......@@ -79,10 +79,10 @@ class BASE_EXPORT UnsafeSharedMemoryRegion {
WritableSharedMemoryMapping MapAt(off_t offset, size_t size);
// Whether the underlying platform handle is valid.
bool IsValid();
bool IsValid() const;
// Returns the maximum mapping size that can be created from this region.
size_t GetSize() {
size_t GetSize() const {
DCHECK(IsValid());
return handle_.GetSize();
}
......
......@@ -66,7 +66,7 @@ WritableSharedMemoryMapping WritableSharedMemoryRegion::MapAt(off_t offset,
return WritableSharedMemoryMapping(memory, mapped_size, handle_.GetGUID());
}
bool WritableSharedMemoryRegion::IsValid() {
bool WritableSharedMemoryRegion::IsValid() const {
return handle_.IsValid();
}
......
......@@ -75,10 +75,10 @@ class BASE_EXPORT WritableSharedMemoryRegion {
WritableSharedMemoryMapping MapAt(off_t offset, size_t size);
// Whether underlying platform handles are valid.
bool IsValid();
bool IsValid() const;
// Returns the maximum mapping size that can be created from this region.
size_t GetSize() {
size_t GetSize() const {
DCHECK(IsValid());
return handle_.GetSize();
}
......
......@@ -55,6 +55,7 @@ source_set("tests") {
"process_id_unittest.cc",
"read_only_buffer_unittest.cc",
"ref_counted_memory_unittest.cc",
"shared_memory_unittest.cc",
"string16_unittest.cc",
"text_direction_unittest.cc",
"thread_priority_unittest.cc",
......
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
mojom = "//mojo/public/mojom/base/shared_memory.mojom"
public_headers = [
"//base/memory/platform_shared_memory_region.h",
"//base/memory/read_only_shared_memory_region.h",
"//base/memory/unsafe_shared_memory_region.h",
"//base/memory/writable_shared_memory_region.h",
]
traits_headers = [ "//mojo/public/cpp/base/shared_memory_mojom_traits.h" ]
sources = [
"//mojo/public/cpp/base/shared_memory_mojom_traits.cc",
"//mojo/public/cpp/base/shared_memory_mojom_traits.h",
]
public_deps = [
"//base",
]
type_mappings = [
"mojo_base.mojom.PlatformSharedMemoryHandle=base::subtle::PlatformSharedMemoryRegion::ScopedPlatformHandle[move_only]",
"mojo_base.mojom.PlatformSharedMemoryRegion=base::subtle::PlatformSharedMemoryRegion[move_only]",
"mojo_base.mojom.PlatformSharedMemoryRegion.Mode=base::subtle::PlatformSharedMemoryRegion::Mode",
"mojo_base.mojom.ReadOnlySharedMemoryRegion=base::ReadOnlySharedMemoryRegion[move_only,nullable_is_same_type]",
"mojo_base.mojom.UnsafeSharedMemoryRegion=base::UnsafeSharedMemoryRegion[move_only,nullable_is_same_type]",
"mojo_base.mojom.WritableSharedMemoryRegion=base::WritableSharedMemoryRegion[move_only,nullable_is_same_type]",
]
This diff is collapsed.
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MOJO_PUBLIC_CPP_BASE_SHARED_MEMORY_MOJOM_TRAITS_H_
#define MOJO_PUBLIC_CPP_BASE_SHARED_MEMORY_MOJOM_TRAITS_H_
#include <cstdint>
#include "base/component_export.h"
#include "base/memory/platform_shared_memory_region.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/unsafe_shared_memory_region.h"
#include "base/memory/writable_shared_memory_region.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "mojo/public/cpp/base/unguessable_token_mojom_traits.h"
#include "mojo/public/cpp/bindings/enum_traits.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "mojo/public/cpp/system/handle.h"
#include "mojo/public/mojom/base/shared_memory.mojom-shared.h"
namespace mojo {
template <>
struct COMPONENT_EXPORT(MOJO_BASE_MOJOM) StructTraits<
mojo_base::mojom::PlatformSharedMemoryHandleDataView,
base::subtle::PlatformSharedMemoryRegion::ScopedPlatformHandle> {
static mojo::ScopedHandle handle_value(
base::subtle::PlatformSharedMemoryRegion::ScopedPlatformHandle& handle);
#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA) && \
(!defined(OS_MACOSX) || defined(OS_IOS))
static mojo::ScopedHandle readonly_fd(
base::subtle::PlatformSharedMemoryRegion::ScopedPlatformHandle& handle);
#endif
static bool Read(
mojo_base::mojom::PlatformSharedMemoryHandleDataView data,
base::subtle::PlatformSharedMemoryRegion::ScopedPlatformHandle* out);
};
template <>
struct COMPONENT_EXPORT(MOJO_BASE_MOJOM)
EnumTraits<mojo_base::mojom::PlatformSharedMemoryRegion_Mode,
base::subtle::PlatformSharedMemoryRegion::Mode> {
static mojo_base::mojom::PlatformSharedMemoryRegion_Mode ToMojom(
base::subtle::PlatformSharedMemoryRegion::Mode input);
static bool FromMojom(mojo_base::mojom::PlatformSharedMemoryRegion_Mode input,
base::subtle::PlatformSharedMemoryRegion::Mode* output);
};
template <>
struct COMPONENT_EXPORT(MOJO_BASE_MOJOM)
StructTraits<mojo_base::mojom::PlatformSharedMemoryRegionDataView,
base::subtle::PlatformSharedMemoryRegion> {
static base::subtle::PlatformSharedMemoryRegion::ScopedPlatformHandle
platform_handle(base::subtle::PlatformSharedMemoryRegion& region);
static base::subtle::PlatformSharedMemoryRegion::Mode mode(
const base::subtle::PlatformSharedMemoryRegion& region);
static uint64_t size(const base::subtle::PlatformSharedMemoryRegion& region);
static base::UnguessableToken guid(
const base::subtle::PlatformSharedMemoryRegion& region);
static bool Read(mojo_base::mojom::PlatformSharedMemoryRegionDataView data,
base::subtle::PlatformSharedMemoryRegion* out);
};
template <>
struct COMPONENT_EXPORT(MOJO_BASE_MOJOM)
StructTraits<mojo_base::mojom::ReadOnlySharedMemoryRegionDataView,
base::ReadOnlySharedMemoryRegion> {
static bool IsNull(const base::ReadOnlySharedMemoryRegion& region);
static void SetToNull(base::ReadOnlySharedMemoryRegion* region);
static base::subtle::PlatformSharedMemoryRegion region(
base::ReadOnlySharedMemoryRegion& in_region);
static bool Read(mojo_base::mojom::ReadOnlySharedMemoryRegionDataView data,
base::ReadOnlySharedMemoryRegion* out);
};
template <>
struct COMPONENT_EXPORT(MOJO_BASE_MOJOM)
StructTraits<mojo_base::mojom::UnsafeSharedMemoryRegionDataView,
base::UnsafeSharedMemoryRegion> {
static bool IsNull(const base::UnsafeSharedMemoryRegion& region);
static void SetToNull(base::UnsafeSharedMemoryRegion* region);
static base::subtle::PlatformSharedMemoryRegion region(
base::UnsafeSharedMemoryRegion& in_region);
static bool Read(mojo_base::mojom::UnsafeSharedMemoryRegionDataView data,
base::UnsafeSharedMemoryRegion* out);
};
template <>
struct COMPONENT_EXPORT(MOJO_BASE_MOJOM)
StructTraits<mojo_base::mojom::WritableSharedMemoryRegionDataView,
base::WritableSharedMemoryRegion> {
static bool IsNull(const base::WritableSharedMemoryRegion& region);
static void SetToNull(base::WritableSharedMemoryRegion* region);
static base::subtle::PlatformSharedMemoryRegion region(
base::WritableSharedMemoryRegion& in_region);
static bool Read(mojo_base::mojom::WritableSharedMemoryRegionDataView data,
base::WritableSharedMemoryRegion* out);
};
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BASE_SHARED_MEMORY_MOJOM_TRAITS_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string>
#include "mojo/public/cpp/base/shared_memory_mojom_traits.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "mojo/public/mojom/base/shared_memory.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
TEST(SharedMemoryMojomTest, ReadOnly) {
auto region = base::ReadOnlySharedMemoryRegion::Create(64);
const std::string kTestData = "Hello, world!";
memcpy(region.mapping.memory(), kTestData.data(), kTestData.size());
base::ReadOnlySharedMemoryRegion read_only_out;
EXPECT_TRUE(mojo::test::SerializeAndDeserialize<
mojo_base::mojom::ReadOnlySharedMemoryRegion>(&region.region,
&read_only_out));
base::ReadOnlySharedMemoryMapping mapping = read_only_out.Map();
EXPECT_EQ(0, memcmp(mapping.memory(), kTestData.data(), kTestData.size()));
}
TEST(SharedMemoryMojomTest, Writable) {
auto region = base::WritableSharedMemoryRegion::Create(64);
auto mapping = region.Map();
const std::string kTestData = "Hello, world!";
memcpy(mapping.memory(), kTestData.data(), kTestData.size());
base::WritableSharedMemoryRegion writable_out;
EXPECT_TRUE(mojo::test::SerializeAndDeserialize<
mojo_base::mojom::WritableSharedMemoryRegion>(&region,
&writable_out));
mapping = writable_out.Map();
EXPECT_EQ(0, memcmp(mapping.memory(), kTestData.data(), kTestData.size()));
}
TEST(SharedMemoryMojomTest, Unsafe) {
auto region = base::UnsafeSharedMemoryRegion::Create(64);
auto mapping = region.Map();
const std::string kTestData = "Hello, world!";
memcpy(mapping.memory(), kTestData.data(), kTestData.size());
base::UnsafeSharedMemoryRegion unsafe_out;
EXPECT_TRUE(
mojo::test::SerializeAndDeserialize<
mojo_base::mojom::UnsafeSharedMemoryRegion>(&region, &unsafe_out));
mapping = unsafe_out.Map();
EXPECT_EQ(0, memcmp(mapping.memory(), kTestData.data(), kTestData.size()));
}
......@@ -13,6 +13,7 @@ typemaps = [
"//mojo/public/cpp/base/memory_allocator_dump_cross_process_uid.typemap",
"//mojo/public/cpp/base/process_id.typemap",
"//mojo/public/cpp/base/ref_counted_memory.typemap",
"//mojo/public/cpp/base/shared_memory.typemap",
"//mojo/public/cpp/base/string16.typemap",
"//mojo/public/cpp/base/logfont_win.typemap",
"//mojo/public/cpp/base/text_direction.typemap",
......
......@@ -15,6 +15,7 @@ mojom_component("base") {
"memory_allocator_dump_cross_process_uid.mojom",
"process_id.mojom",
"ref_counted_memory.mojom",
"shared_memory.mojom",
"string16.mojom",
"text_direction.mojom",
"thread_priority.mojom",
......@@ -27,6 +28,10 @@ mojom_component("base") {
sources += [ "logfont_win.mojom" ]
}
if (is_posix && !is_android && !is_fuchsia && !is_mac) {
enabled_features = [ "shared_memory_region_uses_fd_pair" ]
}
output_prefix = "mojo_base_mojom"
macro_prefix = "MOJO_BASE_MOJOM"
}
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module mojo_base.mojom;
import "mojo/public/mojom/base/unguessable_token.mojom";
// Mirrors the base::subtle::PlatformSharedMemoryRegion::ScopedPlatformHandle
// type.
//
// TODO(https://crbug.com/826213): Remove this once Mojo shared buffers are
// properly backed by base::subtle::PlatformSharedMemoryRegion.
struct PlatformSharedMemoryHandle {
handle handle_value;
[EnableIf=shared_memory_region_uses_fd_pair]
handle? readonly_fd;
};
// Mirrors the base::subtle::PlatformSharedMemoryRegion type.
//
// This should not be used directly. Use one of the specific region types below
// instead.
//
// TODO(https://crbug.com/826213): Remove this once Mojo shared buffers are
// properly backed by base::subtle::PlatformSharedMemoryRegion.
struct PlatformSharedMemoryRegion {
enum Mode {
kReadOnly,
kWritable,
kUnsafe,
};
PlatformSharedMemoryHandle platform_handle;
Mode mode;
uint64 size;
UnguessableToken guid;
};
// Wraps a shared memory handle with additional type information to convey that
// the handle is only mappable to read-only memory.
struct ReadOnlySharedMemoryRegion {
PlatformSharedMemoryRegion region;
};
// Wraps a shared memory handle with additional type information to convey that
// the handle is mappable to writable memory but can also be converted to
// a ReadOnlySharedMemoryRegion for sharing with other clients.
struct WritableSharedMemoryRegion {
PlatformSharedMemoryRegion region;
};
// Wraps a shared memory handle with additional type information to convey that
// the handle is always mappable to writable memory by any client which obtains
// a handle duplicated from this one.
struct UnsafeSharedMemoryRegion {
PlatformSharedMemoryRegion region;
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment