summaryrefslogtreecommitdiff
path: root/chromium/mojo/public/cpp/bindings
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/mojo/public/cpp/bindings')
-rw-r--r--chromium/mojo/public/cpp/bindings/BUILD.gn49
-rw-r--r--chromium/mojo/public/cpp/bindings/array.h6
-rw-r--r--chromium/mojo/public/cpp/bindings/array_traits.h41
-rw-r--r--chromium/mojo/public/cpp/bindings/array_traits_standard.h40
-rw-r--r--chromium/mojo/public/cpp/bindings/array_traits_stl.h50
-rw-r--r--chromium/mojo/public/cpp/bindings/array_traits_wtf.h37
-rw-r--r--chromium/mojo/public/cpp/bindings/array_traits_wtf_vector.h44
-rw-r--r--chromium/mojo/public/cpp/bindings/associated_binding.h50
-rw-r--r--chromium/mojo/public/cpp/bindings/associated_group.h24
-rw-r--r--chromium/mojo/public/cpp/bindings/associated_interface_ptr.h23
-rw-r--r--chromium/mojo/public/cpp/bindings/associated_interface_ptr_info.h49
-rw-r--r--chromium/mojo/public/cpp/bindings/associated_interface_request.h51
-rw-r--r--chromium/mojo/public/cpp/bindings/binding.h61
-rw-r--r--chromium/mojo/public/cpp/bindings/callback.h4
-rw-r--r--chromium/mojo/public/cpp/bindings/interface_ptr.h21
-rw-r--r--chromium/mojo/public/cpp/bindings/interface_request.h10
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/TODO4
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/array_internal.cc18
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/array_internal.h162
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/array_serialization.h407
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/array_serialization_traits.h456
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/associated_group.cc4
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h26
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/binding_state.h25
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/bindings_internal.h99
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/bindings_serialization.cc101
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/bindings_serialization.h136
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/bounds_checker.cc6
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/bounds_checker.h3
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/buffer.h6
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/connector.cc21
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/connector.h17
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/control_message_handler.cc15
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/control_message_handler.h2
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/control_message_proxy.cc31
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/control_message_proxy.h2
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/fixed_buffer.cc4
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/fixed_buffer.h2
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc46
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/interface_endpoint_client.h24
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/interface_ptr_state.h31
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/macros.h33
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/map_data_internal.h16
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/map_serialization.h256
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/message.cc76
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/message_buffer.cc65
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/message_buffer.h52
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/message_builder.cc2
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/multiplex_router.cc102
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/multiplex_router.h35
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/native_serialization.h124
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/native_struct.cc30
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/native_struct_data.cc22
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/native_struct_data.h41
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/native_struct_serialization.cc59
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/native_struct_serialization.h132
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/pickle_buffer.cc98
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/pickle_buffer.h55
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/pipe_control_message_handler.cc6
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/pipe_control_message_handler.h2
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/pipe_control_message_proxy.cc17
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/pipe_control_message_proxy.h2
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/router.cc58
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/router.h16
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc25
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/serialization.h8
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/serialization_context.cc62
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/serialization_context.h75
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/serialization_forward.h145
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/serialization_util.cc53
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/serialization_util.h233
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/string_serialization.cc46
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/string_serialization.h61
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/string_traits_string16.cc42
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/string_traits_wtf.cc85
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/sync_handle_registry.cc28
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/sync_handle_registry.h15
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/sync_handle_watcher.cc12
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/sync_handle_watcher.h2
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/validate_params.h18
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/validation_util.cc29
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/validation_util.h45
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/wtf_array_serialization.h43
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/wtf_serialization.h5
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/wtf_string_serialization.cc118
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/wtf_string_serialization.h28
-rw-r--r--chromium/mojo/public/cpp/bindings/map.h11
-rw-r--r--chromium/mojo/public/cpp/bindings/message.h29
-rw-r--r--chromium/mojo/public/cpp/bindings/native_struct.h47
-rw-r--r--chromium/mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h (renamed from chromium/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h)45
-rw-r--r--chromium/mojo/public/cpp/bindings/string_traits.h69
-rw-r--r--chromium/mojo/public/cpp/bindings/string_traits_standard.h31
-rw-r--r--chromium/mojo/public/cpp/bindings/string_traits_stl.h38
-rw-r--r--chromium/mojo/public/cpp/bindings/string_traits_string16.h36
-rw-r--r--chromium/mojo/public/cpp/bindings/string_traits_string_piece.h43
-rw-r--r--chromium/mojo/public/cpp/bindings/string_traits_wtf.h31
-rw-r--r--chromium/mojo/public/cpp/bindings/struct_traits.h91
-rw-r--r--chromium/mojo/public/cpp/bindings/wtf_array.h6
98 files changed, 2930 insertions, 2232 deletions
diff --git a/chromium/mojo/public/cpp/bindings/BUILD.gn b/chromium/mojo/public/cpp/bindings/BUILD.gn
index c8d2883d0c7..c66853cf8e5 100644
--- a/chromium/mojo/public/cpp/bindings/BUILD.gn
+++ b/chromium/mojo/public/cpp/bindings/BUILD.gn
@@ -5,6 +5,9 @@
source_set("bindings") {
sources = [
"array.h",
+ "array_traits.h",
+ "array_traits_standard.h",
+ "array_traits_stl.h",
"associated_binding.h",
"associated_group.h",
"associated_interface_ptr.h",
@@ -19,13 +22,10 @@ source_set("bindings") {
"lib/array_internal.cc",
"lib/array_internal.h",
"lib/array_serialization.h",
- "lib/array_serialization_traits.h",
"lib/associated_group.cc",
"lib/associated_interface_ptr_state.h",
"lib/binding_state.h",
"lib/bindings_internal.h",
- "lib/bindings_serialization.cc",
- "lib/bindings_serialization.h",
"lib/bounds_checker.cc",
"lib/bounds_checker.h",
"lib/buffer.h",
@@ -44,11 +44,12 @@ source_set("bindings") {
"lib/interface_endpoint_controller.h",
"lib/interface_id.h",
"lib/interface_ptr_state.h",
- "lib/macros.h",
"lib/map_data_internal.h",
"lib/map_internal.h",
"lib/map_serialization.h",
"lib/message.cc",
+ "lib/message_buffer.cc",
+ "lib/message_buffer.h",
"lib/message_builder.cc",
"lib/message_builder.h",
"lib/message_filter.cc",
@@ -57,9 +58,12 @@ source_set("bindings") {
"lib/message_internal.h",
"lib/multiplex_router.cc",
"lib/multiplex_router.h",
+ "lib/native_struct.cc",
+ "lib/native_struct_data.cc",
+ "lib/native_struct_data.h",
+ "lib/native_struct_serialization.cc",
+ "lib/native_struct_serialization.h",
"lib/no_interface.cc",
- "lib/pickle_buffer.cc",
- "lib/pickle_buffer.h",
"lib/pipe_control_message_handler.cc",
"lib/pipe_control_message_handler.h",
"lib/pipe_control_message_handler_delegate.h",
@@ -68,11 +72,14 @@ source_set("bindings") {
"lib/router.cc",
"lib/router.h",
"lib/scoped_interface_endpoint_handle.cc",
- "lib/scoped_interface_endpoint_handle.h",
"lib/serialization.h",
+ "lib/serialization_context.cc",
+ "lib/serialization_context.h",
"lib/serialization_forward.h",
- "lib/string_serialization.cc",
+ "lib/serialization_util.cc",
+ "lib/serialization_util.h",
"lib/string_serialization.h",
+ "lib/string_traits_string16.cc",
"lib/sync_handle_registry.cc",
"lib/sync_handle_registry.h",
"lib/sync_handle_watcher.cc",
@@ -84,24 +91,27 @@ source_set("bindings") {
"lib/validation_util.cc",
"lib/validation_util.h",
"lib/value_traits.h",
-
- # Include the .h but not the .cc file. The .h file is used by
- # serialization_forward.h.
- "lib/wtf_string_serialization.h",
"map.h",
"message.h",
"message_filter.h",
+ "native_struct.h",
"no_interface.h",
+ "scoped_interface_endpoint_handle.h",
"stl_converters.h",
"string.h",
+ "string_traits.h",
+ "string_traits_standard.h",
+ "string_traits_stl.h",
+ "string_traits_string16.h",
+ "string_traits_string_piece.h",
"strong_binding.h",
"struct_ptr.h",
- "struct_traits.h",
"type_converter.h",
]
public_deps = [
":callback",
+ ":struct_traits",
"//base",
"//ipc:param_traits",
"//mojo/public/cpp/system",
@@ -128,12 +138,19 @@ source_set("callback") {
]
}
+source_set("struct_traits") {
+ sources = [
+ "struct_traits.h",
+ ]
+}
+
source_set("wtf_support") {
sources = [
- "lib/wtf_array_serialization.h",
+ "array_traits_wtf.h",
+ "array_traits_wtf_vector.h",
+ "lib/string_traits_wtf.cc",
"lib/wtf_serialization.h",
- "lib/wtf_string_serialization.cc",
- "lib/wtf_string_serialization.h",
+ "string_traits_wtf.h",
"wtf_array.h",
]
diff --git a/chromium/mojo/public/cpp/bindings/array.h b/chromium/mojo/public/cpp/bindings/array.h
index e9bd6838412..d94feb0768c 100644
--- a/chromium/mojo/public/cpp/bindings/array.h
+++ b/chromium/mojo/public/cpp/bindings/array.h
@@ -30,10 +30,10 @@ class Array {
public:
using ConstRefType = typename std::vector<T>::const_reference;
using RefType = typename std::vector<T>::reference;
- using ElementType = T;
- using Data_ =
- internal::Array_Data<typename internal::WrapperTraits<T>::DataType>;
+ using Element = T;
+ using Data_ = internal::Array_Data<
+ typename internal::GetDataTypeAsArrayElement<T>::Data>;
using iterator = typename std::vector<T>::iterator;
using const_iterator = typename std::vector<T>::const_iterator;
diff --git a/chromium/mojo/public/cpp/bindings/array_traits.h b/chromium/mojo/public/cpp/bindings/array_traits.h
new file mode 100644
index 00000000000..c9512fbfd51
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/array_traits.h
@@ -0,0 +1,41 @@
+// Copyright 2016 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_BINDINGS_ARRAY_TRAITS_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_H_
+
+namespace mojo {
+
+// This must be specialized for any type |T| to be serialized/deserialized as
+// a mojom array.
+//
+// Usually you would like to do a partial specialization for an array/vector
+// template. Imagine you want to specialize it for CustomArray<>, you need to
+// implement:
+//
+// template <typename T>
+// struct ArrayTraits<CustomArray<T>> {
+// using Element = T;
+//
+// // These two methods are optional. Please see comments in struct_traits.h
+// static bool IsNull(const CustomArray<T>& input);
+// static void SetToNull(CustomArray<T>* output);
+//
+// static size_t GetSize(const CustomArray<T>& input);
+//
+// static T* GetData(CustomArray<T>& input);
+// static const T* GetData(const CustomArray<T>& input);
+//
+// static T& GetAt(CustomArray<T>& input, size_t index);
+// static const T& GetAt(const CustomArray<T>& input, size_t index);
+//
+// static void Resize(CustomArray<T>& input, size_t size);
+// };
+//
+template <typename T>
+struct ArrayTraits;
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_H_
diff --git a/chromium/mojo/public/cpp/bindings/array_traits_standard.h b/chromium/mojo/public/cpp/bindings/array_traits_standard.h
new file mode 100644
index 00000000000..7ee4bd2661a
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/array_traits_standard.h
@@ -0,0 +1,40 @@
+// Copyright 2016 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_BINDINGS_ARRAY_TRAITS_STANDARD_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_STANDARD_H_
+
+#include "mojo/public/cpp/bindings/array.h"
+#include "mojo/public/cpp/bindings/array_traits.h"
+
+namespace mojo {
+
+template <typename T>
+struct ArrayTraits<Array<T>> {
+ using Element = T;
+
+ static bool IsNull(const Array<T>& input) { return input.is_null(); }
+ static void SetToNull(Array<T>* output) { *output = nullptr; }
+
+ static size_t GetSize(const Array<T>& input) { return input.size(); }
+
+ static T* GetData(Array<T>& input) { return &input.front(); }
+
+ static const T* GetData(const Array<T>& input) { return &input.front(); }
+
+ static typename Array<T>::RefType GetAt(Array<T>& input, size_t index) {
+ return input[index];
+ }
+
+ static typename Array<T>::ConstRefType GetAt(const Array<T>& input,
+ size_t index) {
+ return input[index];
+ }
+
+ static void Resize(Array<T>& input, size_t size) { input.resize(size); }
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_STANDARD_H_
diff --git a/chromium/mojo/public/cpp/bindings/array_traits_stl.h b/chromium/mojo/public/cpp/bindings/array_traits_stl.h
new file mode 100644
index 00000000000..f78ae2f84cb
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/array_traits_stl.h
@@ -0,0 +1,50 @@
+// Copyright 2016 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_BINDINGS_ARRAY_TRAITS_STL_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_STL_H_
+
+#include <vector>
+
+#include "mojo/public/cpp/bindings/array_traits.h"
+
+namespace mojo {
+
+template <typename T>
+struct ArrayTraits<std::vector<T>> {
+ using Element = T;
+
+ static bool IsNull(const std::vector<T>& input) {
+ // std::vector<> is always converted to non-null mojom array.
+ return false;
+ }
+
+ static void SetToNull(std::vector<T>* output) {
+ // std::vector<> doesn't support null state. Set it to empty instead.
+ output->clear();
+ }
+
+ static size_t GetSize(const std::vector<T>& input) { return input.size(); }
+
+ static T* GetData(std::vector<T>& input) { return input.data(); }
+
+ static const T* GetData(const std::vector<T>& input) { return input.data(); }
+
+ static typename std::vector<T>::reference GetAt(std::vector<T>& input,
+ size_t index) {
+ return input[index];
+ }
+
+ static typename std::vector<T>::const_reference GetAt(
+ const std::vector<T>& input,
+ size_t index) {
+ return input[index];
+ }
+
+ static void Resize(std::vector<T>& input, size_t size) { input.resize(size); }
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_STL_H_
diff --git a/chromium/mojo/public/cpp/bindings/array_traits_wtf.h b/chromium/mojo/public/cpp/bindings/array_traits_wtf.h
new file mode 100644
index 00000000000..71f1da1116a
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/array_traits_wtf.h
@@ -0,0 +1,37 @@
+// Copyright 2016 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_BINDINGS_ARRAY_TRAITS_WTF_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_WTF_H_
+
+#include "mojo/public/cpp/bindings/array_traits.h"
+#include "mojo/public/cpp/bindings/wtf_array.h"
+
+namespace mojo {
+
+template <typename U>
+struct ArrayTraits<WTFArray<U>> {
+ using Element = U;
+
+ static bool IsNull(const WTFArray<U>& input) { return input.is_null(); }
+ static void SetToNull(WTFArray<U>* output) { *output = nullptr; }
+
+ static size_t GetSize(const WTFArray<U>& input) { return input.size(); }
+
+ static U* GetData(WTFArray<U>& input) { return &input.front(); }
+
+ static const U* GetData(const WTFArray<U>& input) { return &input.front(); }
+
+ static U& GetAt(WTFArray<U>& input, size_t index) { return input[index]; }
+
+ static const U& GetAt(const WTFArray<U>& input, size_t index) {
+ return input[index];
+ }
+
+ static void Resize(WTFArray<U>& input, size_t size) { input.resize(size); }
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_WTF_H_
diff --git a/chromium/mojo/public/cpp/bindings/array_traits_wtf_vector.h b/chromium/mojo/public/cpp/bindings/array_traits_wtf_vector.h
new file mode 100644
index 00000000000..9b3755ad4f1
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/array_traits_wtf_vector.h
@@ -0,0 +1,44 @@
+// Copyright 2016 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_BINDINGS_ARRAY_TRAITS_WTF_VECTOR_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_WTF_VECTOR_H_
+
+#include "mojo/public/cpp/bindings/array_traits.h"
+#include "third_party/WebKit/Source/wtf/Vector.h"
+
+namespace mojo {
+
+template <typename U>
+struct ArrayTraits<WTF::Vector<U>> {
+ using Element = U;
+
+ static bool IsNull(const WTF::Vector<U>& input) {
+ // WTF::Vector<> is always converted to non-null mojom array.
+ return false;
+ }
+
+ static void SetToNull(WTF::Vector<U>* output) {
+ // WTF::Vector<> doesn't support null state. Set it to empty instead.
+ output->clear();
+ }
+
+ static size_t GetSize(const WTF::Vector<U>& input) { return input.size(); }
+
+ static U* GetData(WTF::Vector<U>& input) { return input.data(); }
+
+ static const U* GetData(const WTF::Vector<U>& input) { return input.data(); }
+
+ static U& GetAt(WTF::Vector<U>& input, size_t index) { return input[index]; }
+
+ static const U& GetAt(const WTF::Vector<U>& input, size_t index) {
+ return input[index];
+ }
+
+ static void Resize(WTF::Vector<U>& input, size_t size) { input.resize(size); }
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_ARRAY_TRAITS_WTF_VECTOR_H_
diff --git a/chromium/mojo/public/cpp/bindings/associated_binding.h b/chromium/mojo/public/cpp/bindings/associated_binding.h
index a7263635fef..2d4e3392230 100644
--- a/chromium/mojo/public/cpp/bindings/associated_binding.h
+++ b/chromium/mojo/public/cpp/bindings/associated_binding.h
@@ -5,21 +5,33 @@
#ifndef MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_
#define MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_BINDING_H_
+#include <memory>
#include <utility>
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/ptr_util.h"
+#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "mojo/public/cpp/bindings/associated_group.h"
#include "mojo/public/cpp/bindings/associated_interface_request.h"
#include "mojo/public/cpp/bindings/callback.h"
#include "mojo/public/cpp/bindings/lib/interface_endpoint_client.h"
#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
-#include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h"
+#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
namespace mojo {
// Represents the implementation side of an associated interface. It is similar
// to Binding, except that it doesn't own a message pipe handle.
+//
+// When you bind this class to a request, optionally you can specify a
+// base::SingleThreadTaskRunner. This task runner must belong to the same
+// thread. It will be used to dispatch incoming method calls and connection
+// error notification. It is useful when you attach multiple task runners to a
+// single thread for the purposes of task scheduling. Please note that incoming
+// synchrounous method calls may not be run from this task runner, when they
+// reenter outgoing synchrounous calls on the same thread.
template <typename Interface>
class AssociatedBinding {
public:
@@ -37,17 +49,21 @@ class AssociatedBinding {
// pointer. |impl| must outlive this object.
AssociatedBinding(Interface* impl,
AssociatedInterfacePtrInfo<Interface>* ptr_info,
- AssociatedGroup* associated_group)
+ AssociatedGroup* associated_group,
+ scoped_refptr<base::SingleThreadTaskRunner> runner =
+ base::ThreadTaskRunnerHandle::Get())
: AssociatedBinding(impl) {
- Bind(ptr_info, associated_group);
+ Bind(ptr_info, associated_group, std::move(runner));
}
// Constructs a completed associated binding of |impl|. |impl| must outlive
// the binding.
AssociatedBinding(Interface* impl,
- AssociatedInterfaceRequest<Interface> request)
+ AssociatedInterfaceRequest<Interface> request,
+ scoped_refptr<base::SingleThreadTaskRunner> runner =
+ base::ThreadTaskRunnerHandle::Get())
: AssociatedBinding(impl) {
- Bind(std::move(request));
+ Bind(std::move(request), std::move(runner));
}
~AssociatedBinding() {}
@@ -57,17 +73,20 @@ class AssociatedBinding {
// message pipe endpoint referred to by |associated_group| to setup the
// corresponding asssociated interface pointer.
void Bind(AssociatedInterfacePtrInfo<Interface>* ptr_info,
- AssociatedGroup* associated_group) {
+ AssociatedGroup* associated_group,
+ scoped_refptr<base::SingleThreadTaskRunner> runner =
+ base::ThreadTaskRunnerHandle::Get()) {
AssociatedInterfaceRequest<Interface> request;
associated_group->CreateAssociatedInterface(AssociatedGroup::WILL_PASS_PTR,
ptr_info, &request);
- Bind(std::move(request));
+ Bind(std::move(request), std::move(runner));
}
// Sets up this object as the implementation side of an associated interface.
- void Bind(AssociatedInterfaceRequest<Interface> request) {
- internal::ScopedInterfaceEndpointHandle handle =
- internal::AssociatedInterfaceRequestHelper::PassHandle(&request);
+ void Bind(AssociatedInterfaceRequest<Interface> request,
+ scoped_refptr<base::SingleThreadTaskRunner> runner =
+ base::ThreadTaskRunnerHandle::Get()) {
+ ScopedInterfaceEndpointHandle handle = request.PassHandle();
DCHECK(handle.is_local())
<< "The AssociatedInterfaceRequest is supposed to be used at the "
@@ -80,8 +99,8 @@ class AssociatedBinding {
endpoint_client_.reset(new internal::InterfaceEndpointClient(
std::move(handle), &stub_,
- make_scoped_ptr(new typename Interface::RequestValidator_()),
- Interface::HasSyncMethods_));
+ base::WrapUnique(new typename Interface::RequestValidator_()),
+ Interface::HasSyncMethods_, std::move(runner)));
endpoint_client_->set_connection_error_handler(
[this]() { connection_error_handler_.Run(); });
@@ -103,8 +122,7 @@ class AssociatedBinding {
DCHECK(endpoint_client_);
AssociatedInterfaceRequest<Interface> request;
- internal::AssociatedInterfaceRequestHelper::SetHandle(
- &request, endpoint_client_->PassHandle());
+ request.Bind(endpoint_client_->PassHandle());
endpoint_client_.reset();
connection_error_handler_.reset();
@@ -135,7 +153,7 @@ class AssociatedBinding {
}
private:
- scoped_ptr<internal::InterfaceEndpointClient> endpoint_client_;
+ std::unique_ptr<internal::InterfaceEndpointClient> endpoint_client_;
typename Interface::Stub_ stub_;
Interface* impl_;
diff --git a/chromium/mojo/public/cpp/bindings/associated_group.h b/chromium/mojo/public/cpp/bindings/associated_group.h
index ea3b5a16265..5f7a39632a4 100644
--- a/chromium/mojo/public/cpp/bindings/associated_group.h
+++ b/chromium/mojo/public/cpp/bindings/associated_group.h
@@ -10,7 +10,7 @@
#include "base/memory/ref_counted.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
#include "mojo/public/cpp/bindings/associated_interface_request.h"
-#include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h"
+#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
namespace mojo {
@@ -50,8 +50,8 @@ class AssociatedGroup {
AssociatedInterfaceConfig config,
AssociatedInterfacePtrInfo<T>* ptr_info,
AssociatedInterfaceRequest<T>* request) {
- internal::ScopedInterfaceEndpointHandle local;
- internal::ScopedInterfaceEndpointHandle remote;
+ ScopedInterfaceEndpointHandle local;
+ ScopedInterfaceEndpointHandle remote;
CreateEndpointHandlePair(&local, &remote);
if (!local.is_valid() || !remote.is_valid()) {
@@ -61,21 +61,19 @@ class AssociatedGroup {
}
if (config == WILL_PASS_PTR) {
- internal::AssociatedInterfacePtrInfoHelper::SetHandle(ptr_info,
- std::move(remote));
+ ptr_info->set_handle(std::move(remote));
+
// The implementation is local, therefore set the version according to
// the interface definition that this code is built against.
ptr_info->set_version(T::Version_);
- internal::AssociatedInterfaceRequestHelper::SetHandle(request,
- std::move(local));
+ request->Bind(std::move(local));
} else {
- internal::AssociatedInterfacePtrInfoHelper::SetHandle(ptr_info,
- std::move(local));
+ ptr_info->set_handle(std::move(local));
+
// The implementation is remote, we don't know about its actual version
// yet.
ptr_info->set_version(0u);
- internal::AssociatedInterfaceRequestHelper::SetHandle(request,
- std::move(remote));
+ request->Bind(std::move(remote));
}
}
@@ -83,8 +81,8 @@ class AssociatedGroup {
friend class internal::MultiplexRouter;
void CreateEndpointHandlePair(
- internal::ScopedInterfaceEndpointHandle* local_endpoint,
- internal::ScopedInterfaceEndpointHandle* remote_endpoint);
+ ScopedInterfaceEndpointHandle* local_endpoint,
+ ScopedInterfaceEndpointHandle* remote_endpoint);
scoped_refptr<internal::MultiplexRouter> router_;
};
diff --git a/chromium/mojo/public/cpp/bindings/associated_interface_ptr.h b/chromium/mojo/public/cpp/bindings/associated_interface_ptr.h
index 48caad654e3..c4435ee599b 100644
--- a/chromium/mojo/public/cpp/bindings/associated_interface_ptr.h
+++ b/chromium/mojo/public/cpp/bindings/associated_interface_ptr.h
@@ -10,6 +10,9 @@
#include "base/logging.h"
#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "mojo/public/cpp/bindings/associated_group.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
#include "mojo/public/cpp/bindings/associated_interface_request.h"
@@ -52,20 +55,26 @@ class AssociatedInterfacePtr {
// Calling with an invalid |info| has the same effect as reset(). In this
// case, the AssociatedInterfacePtr is not considered as bound.
//
+ // |runner| must belong to the same thread. It will be used to dispatch all
+ // callbacks and connection error notification. It is useful when you attach
+ // multiple task runners to a single thread for the purposes of task
+ // scheduling.
+ //
// NOTE: Please see the comments of
// AssociatedGroup.CreateAssociatedInterface() about when you can use this
// object to make calls.
- void Bind(AssociatedInterfacePtrInfo<Interface> info) {
+ void Bind(AssociatedInterfacePtrInfo<Interface> info,
+ scoped_refptr<base::SingleThreadTaskRunner> runner =
+ base::ThreadTaskRunnerHandle::Get()) {
reset();
- bool is_local =
- internal::AssociatedInterfacePtrInfoHelper::GetHandle(&info).is_local();
+ bool is_local = info.handle().is_local();
DCHECK(is_local) << "The AssociatedInterfacePtrInfo is supposed to be used "
"at the other side of the message pipe.";
if (info.is_valid() && is_local)
- internal_state_.Bind(std::move(info));
+ internal_state_.Bind(std::move(info), std::move(runner));
}
bool is_bound() const { return internal_state_.is_bound(); }
@@ -181,13 +190,15 @@ class AssociatedInterfacePtr {
template <typename Interface>
AssociatedInterfaceRequest<Interface> GetProxy(
AssociatedInterfacePtr<Interface>* ptr,
- AssociatedGroup* group) {
+ AssociatedGroup* group,
+ scoped_refptr<base::SingleThreadTaskRunner> runner =
+ base::ThreadTaskRunnerHandle::Get()) {
AssociatedInterfaceRequest<Interface> request;
AssociatedInterfacePtrInfo<Interface> ptr_info;
group->CreateAssociatedInterface(AssociatedGroup::WILL_PASS_REQUEST,
&ptr_info, &request);
- ptr->Bind(std::move(ptr_info));
+ ptr->Bind(std::move(ptr_info), std::move(runner));
return request;
}
diff --git a/chromium/mojo/public/cpp/bindings/associated_interface_ptr_info.h b/chromium/mojo/public/cpp/bindings/associated_interface_ptr_info.h
index 8340eeade62..a393bcea1d7 100644
--- a/chromium/mojo/public/cpp/bindings/associated_interface_ptr_info.h
+++ b/chromium/mojo/public/cpp/bindings/associated_interface_ptr_info.h
@@ -9,14 +9,10 @@
#include <utility>
#include "base/macros.h"
-#include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h"
+#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
namespace mojo {
-namespace internal {
-class AssociatedInterfacePtrInfoHelper;
-}
-
// AssociatedInterfacePtrInfo stores necessary information to construct an
// associated interface pointer. It is similar to InterfacePtrInfo except that
// it doesn't own a message pipe handle.
@@ -32,6 +28,10 @@ class AssociatedInterfacePtrInfo {
other.version_ = 0u;
}
+ AssociatedInterfacePtrInfo(ScopedInterfaceEndpointHandle handle,
+ uint32_t version)
+ : handle_(std::move(handle)), version_(version) {}
+
~AssociatedInterfacePtrInfo() {}
AssociatedInterfacePtrInfo& operator=(AssociatedInterfacePtrInfo&& other) {
@@ -46,43 +46,22 @@ class AssociatedInterfacePtrInfo {
bool is_valid() const { return handle_.is_valid(); }
+ ScopedInterfaceEndpointHandle PassHandle() {
+ return std::move(handle_);
+ }
+ const ScopedInterfaceEndpointHandle& handle() const { return handle_; }
+ void set_handle(ScopedInterfaceEndpointHandle handle) {
+ handle_ = std::move(handle);
+ }
+
uint32_t version() const { return version_; }
void set_version(uint32_t version) { version_ = version; }
private:
- friend class internal::AssociatedInterfacePtrInfoHelper;
-
- internal::ScopedInterfaceEndpointHandle handle_;
+ ScopedInterfaceEndpointHandle handle_;
uint32_t version_;
};
-namespace internal {
-
-// With this helper, AssociatedInterfacePtrInfo doesn't have to expose any
-// operations related to ScopedInterfaceEndpointHandle, which is an internal
-// class.
-class AssociatedInterfacePtrInfoHelper {
- public:
- template <typename Interface>
- static ScopedInterfaceEndpointHandle PassHandle(
- AssociatedInterfacePtrInfo<Interface>* info) {
- return std::move(info->handle_);
- }
-
- template <typename Interface>
- static const ScopedInterfaceEndpointHandle& GetHandle(
- AssociatedInterfacePtrInfo<Interface>* info) {
- return info->handle_;
- }
-
- template <typename Interface>
- static void SetHandle(AssociatedInterfacePtrInfo<Interface>* info,
- ScopedInterfaceEndpointHandle handle) {
- info->handle_ = std::move(handle);
- }
-};
-
-} // namespace internal
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_INTERFACE_PTR_INFO_H_
diff --git a/chromium/mojo/public/cpp/bindings/associated_interface_request.h b/chromium/mojo/public/cpp/bindings/associated_interface_request.h
index 36cbe3eb48c..a7a7f662166 100644
--- a/chromium/mojo/public/cpp/bindings/associated_interface_request.h
+++ b/chromium/mojo/public/cpp/bindings/associated_interface_request.h
@@ -8,14 +8,10 @@
#include <utility>
#include "base/macros.h"
-#include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h"
+#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
namespace mojo {
-namespace internal {
-class AssociatedInterfaceRequestHelper;
-}
-
// AssociatedInterfaceRequest represents an associated interface request. It is
// similar to InterfaceRequest except that it doesn't own a message pipe handle.
template <typename Interface>
@@ -51,39 +47,30 @@ class AssociatedInterfaceRequest {
// handle.
bool is_pending() const { return handle_.is_valid(); }
- private:
- friend class internal::AssociatedInterfaceRequestHelper;
-
- internal::ScopedInterfaceEndpointHandle handle_;
-};
-
-namespace internal {
-
-// With this helper, AssociatedInterfaceRequest doesn't have to expose any
-// operations related to ScopedInterfaceEndpointHandle, which is an internal
-// class.
-class AssociatedInterfaceRequestHelper {
- public:
- template <typename Interface>
- static ScopedInterfaceEndpointHandle PassHandle(
- AssociatedInterfaceRequest<Interface>* request) {
- return std::move(request->handle_);
+ void Bind(ScopedInterfaceEndpointHandle handle) {
+ handle_ = std::move(handle);
}
- template <typename Interface>
- static const ScopedInterfaceEndpointHandle& GetHandle(
- AssociatedInterfaceRequest<Interface>* request) {
- return request->handle_;
+ ScopedInterfaceEndpointHandle PassHandle() {
+ return std::move(handle_);
}
- template <typename Interface>
- static void SetHandle(AssociatedInterfaceRequest<Interface>* request,
- ScopedInterfaceEndpointHandle handle) {
- request->handle_ = std::move(handle);
- }
+ const ScopedInterfaceEndpointHandle& handle() const { return handle_; }
+
+ private:
+ ScopedInterfaceEndpointHandle handle_;
};
-} // namespace internal
+// Makes an AssociatedInterfaceRequest bound to the specified associated
+// endpoint.
+template <typename Interface>
+AssociatedInterfaceRequest<Interface> MakeAssociatedRequest(
+ ScopedInterfaceEndpointHandle handle) {
+ AssociatedInterfaceRequest<Interface> request;
+ request.Bind(std::move(handle));
+ return request;
+}
+
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_INTERFACE_REQUEST_H_
diff --git a/chromium/mojo/public/cpp/bindings/binding.h b/chromium/mojo/public/cpp/bindings/binding.h
index 68dd32239c4..84b4f90d62d 100644
--- a/chromium/mojo/public/cpp/bindings/binding.h
+++ b/chromium/mojo/public/cpp/bindings/binding.h
@@ -8,6 +8,9 @@
#include <utility>
#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "mojo/public/cpp/bindings/callback.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
#include "mojo/public/cpp/bindings/interface_ptr_info.h"
@@ -52,6 +55,14 @@ class AssociatedGroup;
// class must be from the thread that bound it. The interface implementation's
// methods will be called from the thread that bound this. If a Binding is not
// bound to a message pipe, it may be bound or destroyed on any thread.
+//
+// When you bind this class to a message pipe, optionally you can specify a
+// base::SingleThreadTaskRunner. This task runner must belong to the same
+// thread. It will be used to dispatch incoming method calls and connection
+// error notification. It is useful when you attach multiple task runners to a
+// single thread for the purposes of task scheduling. Please note that incoming
+// synchrounous method calls may not be run from this task runner, when they
+// reenter outgoing synchrounous calls on the same thread.
template <typename Interface>
class Binding {
public:
@@ -62,8 +73,12 @@ class Binding {
// Constructs a completed binding of message pipe |handle| to implementation
// |impl|. Does not take ownership of |impl|, which must outlive the binding.
- Binding(Interface* impl, ScopedMessagePipeHandle handle) : Binding(impl) {
- Bind(std::move(handle));
+ Binding(Interface* impl,
+ ScopedMessagePipeHandle handle,
+ scoped_refptr<base::SingleThreadTaskRunner> runner =
+ base::ThreadTaskRunnerHandle::Get())
+ : Binding(impl) {
+ Bind(std::move(handle), std::move(runner));
}
// Constructs a completed binding of |impl| to a new message pipe, passing the
@@ -71,16 +86,23 @@ class Binding {
// pass |ptr| on to the client of the service. Does not take ownership of any
// of the parameters. |impl| must outlive the binding. |ptr| only needs to
// last until the constructor returns.
- Binding(Interface* impl, InterfacePtr<Interface>* ptr) : Binding(impl) {
- Bind(ptr);
+ Binding(Interface* impl,
+ InterfacePtr<Interface>* ptr,
+ scoped_refptr<base::SingleThreadTaskRunner> runner =
+ base::ThreadTaskRunnerHandle::Get())
+ : Binding(impl) {
+ Bind(ptr, std::move(runner));
}
// Constructs a completed binding of |impl| to the message pipe endpoint in
// |request|, taking ownership of the endpoint. Does not take ownership of
// |impl|, which must outlive the binding.
- Binding(Interface* impl, InterfaceRequest<Interface> request)
+ Binding(Interface* impl,
+ InterfaceRequest<Interface> request,
+ scoped_refptr<base::SingleThreadTaskRunner> runner =
+ base::ThreadTaskRunnerHandle::Get())
: Binding(impl) {
- Bind(request.PassMessagePipe());
+ Bind(request.PassMessagePipe(), std::move(runner));
}
// Tears down the binding, closing the message pipe and leaving the interface
@@ -89,17 +111,21 @@ class Binding {
// Returns an InterfacePtr bound to one end of a pipe whose other end is
// bound to |this|.
- InterfacePtr<Interface> CreateInterfacePtrAndBind() {
+ InterfacePtr<Interface> CreateInterfacePtrAndBind(
+ scoped_refptr<base::SingleThreadTaskRunner> runner =
+ base::ThreadTaskRunnerHandle::Get()) {
InterfacePtr<Interface> interface_ptr;
- Bind(&interface_ptr);
+ Bind(&interface_ptr, std::move(runner));
return interface_ptr;
}
// Completes a binding that was constructed with only an interface
// implementation. Takes ownership of |handle| and binds it to the previously
// specified implementation.
- void Bind(ScopedMessagePipeHandle handle) {
- internal_state_.Bind(std::move(handle));
+ void Bind(ScopedMessagePipeHandle handle,
+ scoped_refptr<base::SingleThreadTaskRunner> runner =
+ base::ThreadTaskRunnerHandle::Get()) {
+ internal_state_.Bind(std::move(handle), std::move(runner));
}
// Completes a binding that was constructed with only an interface
@@ -107,18 +133,23 @@ class Binding {
// previously specified implementation, and passing the other to |ptr|, which
// takes ownership of it. The caller is expected to pass |ptr| on to the
// eventual client of the service. Does not take ownership of |ptr|.
- void Bind(InterfacePtr<Interface>* ptr) {
+ void Bind(InterfacePtr<Interface>* ptr,
+ scoped_refptr<base::SingleThreadTaskRunner> runner =
+ base::ThreadTaskRunnerHandle::Get()) {
MessagePipe pipe;
ptr->Bind(InterfacePtrInfo<Interface>(std::move(pipe.handle0),
- Interface::Version_));
- Bind(std::move(pipe.handle1));
+ Interface::Version_),
+ runner);
+ Bind(std::move(pipe.handle1), std::move(runner));
}
// Completes a binding that was constructed with only an interface
// implementation by removing the message pipe endpoint from |request| and
// binding it to the previously specified implementation.
- void Bind(InterfaceRequest<Interface> request) {
- Bind(request.PassMessagePipe());
+ void Bind(InterfaceRequest<Interface> request,
+ scoped_refptr<base::SingleThreadTaskRunner> runner =
+ base::ThreadTaskRunnerHandle::Get()) {
+ Bind(request.PassMessagePipe(), std::move(runner));
}
// Whether there are any associated interfaces running on the pipe currently.
diff --git a/chromium/mojo/public/cpp/bindings/callback.h b/chromium/mojo/public/cpp/bindings/callback.h
index 91f37d03fef..c5e328927f4 100644
--- a/chromium/mojo/public/cpp/bindings/callback.h
+++ b/chromium/mojo/public/cpp/bindings/callback.h
@@ -5,11 +5,11 @@
#ifndef MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_
#define MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_
+#include <memory>
#include <type_traits>
#include <utility>
#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
#include "mojo/public/cpp/bindings/lib/callback_internal.h"
#include "mojo/public/cpp/bindings/lib/template_util.h"
@@ -143,7 +143,7 @@ class Callback<void(Args...)> {
struct RunnableHolder : public base::RefCountedThreadSafe<RunnableHolder> {
explicit RunnableHolder(Runnable* runnable) : runnable(runnable) {}
- scoped_ptr<Runnable> runnable;
+ std::unique_ptr<Runnable> runnable;
private:
friend class base::RefCountedThreadSafe<RunnableHolder>;
diff --git a/chromium/mojo/public/cpp/bindings/interface_ptr.h b/chromium/mojo/public/cpp/bindings/interface_ptr.h
index 9b005eee815..e427dc4668d 100644
--- a/chromium/mojo/public/cpp/bindings/interface_ptr.h
+++ b/chromium/mojo/public/cpp/bindings/interface_ptr.h
@@ -10,6 +10,9 @@
#include "base/logging.h"
#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "mojo/public/cpp/bindings/callback.h"
#include "mojo/public/cpp/bindings/interface_ptr_info.h"
#include "mojo/public/cpp/bindings/lib/interface_ptr_state.h"
@@ -68,10 +71,17 @@ class InterfacePtr {
// Calling with an invalid |info| (containing an invalid message pipe handle)
// has the same effect as reset(). In this case, the InterfacePtr is not
// considered as bound.
- void Bind(InterfacePtrInfo<Interface> info) {
+ //
+ // |runner| must belong to the same thread. It will be used to dispatch all
+ // callbacks and connection error notification. It is useful when you attach
+ // multiple task runners to a single thread for the purposes of task
+ // scheduling.
+ void Bind(InterfacePtrInfo<Interface> info,
+ scoped_refptr<base::SingleThreadTaskRunner> runner =
+ base::ThreadTaskRunnerHandle::Get()) {
reset();
if (info.is_valid())
- internal_state_.Bind(std::move(info));
+ internal_state_.Bind(std::move(info), std::move(runner));
}
// Returns whether or not this InterfacePtr is bound to a message pipe.
@@ -208,10 +218,13 @@ class InterfacePtr {
// If |info| is valid (containing a valid message pipe handle), returns an
// InterfacePtr bound to it. Otherwise, returns an unbound InterfacePtr.
template <typename Interface>
-InterfacePtr<Interface> MakeProxy(InterfacePtrInfo<Interface> info) {
+InterfacePtr<Interface> MakeProxy(
+ InterfacePtrInfo<Interface> info,
+ scoped_refptr<base::SingleThreadTaskRunner> runner =
+ base::ThreadTaskRunnerHandle::Get()) {
InterfacePtr<Interface> ptr;
if (info.is_valid())
- ptr.Bind(std::move(info));
+ ptr.Bind(std::move(info), std::move(runner));
return std::move(ptr);
}
diff --git a/chromium/mojo/public/cpp/bindings/interface_request.h b/chromium/mojo/public/cpp/bindings/interface_request.h
index 807cd5dc94c..3d6b27c0a0e 100644
--- a/chromium/mojo/public/cpp/bindings/interface_request.h
+++ b/chromium/mojo/public/cpp/bindings/interface_request.h
@@ -7,6 +7,8 @@
#include <utility>
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
namespace mojo {
@@ -111,9 +113,13 @@ InterfaceRequest<Interface> MakeRequest(ScopedMessagePipeHandle handle) {
// CreateSource(std::move(source_request)); // Create implementation locally.
//
template <typename Interface>
-InterfaceRequest<Interface> GetProxy(InterfacePtr<Interface>* ptr) {
+InterfaceRequest<Interface> GetProxy(
+ InterfacePtr<Interface>* ptr,
+ scoped_refptr<base::SingleThreadTaskRunner> runner =
+ base::ThreadTaskRunnerHandle::Get()) {
MessagePipe pipe;
- ptr->Bind(InterfacePtrInfo<Interface>(std::move(pipe.handle0), 0u));
+ ptr->Bind(InterfacePtrInfo<Interface>(std::move(pipe.handle0), 0u),
+ std::move(runner));
return MakeRequest<Interface>(std::move(pipe.handle1));
}
diff --git a/chromium/mojo/public/cpp/bindings/lib/TODO b/chromium/mojo/public/cpp/bindings/lib/TODO
deleted file mode 100644
index ea4ce81a2f4..00000000000
--- a/chromium/mojo/public/cpp/bindings/lib/TODO
+++ /dev/null
@@ -1,4 +0,0 @@
-TODOs:
- - Optimize Buffer classes?
- - Add compile-time asserts to verify object packing and padding.
- - Investigate making arrays of objects not be arrays of pointers.
diff --git a/chromium/mojo/public/cpp/bindings/lib/array_internal.cc b/chromium/mojo/public/cpp/bindings/lib/array_internal.cc
index 542ab3d71e9..dd24eac4702 100644
--- a/chromium/mojo/public/cpp/bindings/lib/array_internal.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/array_internal.cc
@@ -55,23 +55,5 @@ ArrayDataTraits<bool>::BitRef::operator bool() const {
return (*storage_ & mask_) != 0;
}
-// static
-void ArraySerializationHelper<Handle, true, false>::EncodePointersAndHandles(
- const ArrayHeader* header,
- ElementType* elements,
- std::vector<Handle>* handles) {
- for (uint32_t i = 0; i < header->num_elements; ++i)
- EncodeHandle(&elements[i], handles);
-}
-
-// static
-void ArraySerializationHelper<Handle, true, false>::DecodePointersAndHandles(
- const ArrayHeader* header,
- ElementType* elements,
- std::vector<Handle>* handles) {
- for (uint32_t i = 0; i < header->num_elements; ++i)
- DecodeHandle(&elements[i], handles);
-}
-
} // namespace internal
} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/array_internal.h b/chromium/mojo/public/cpp/bindings/lib/array_internal.h
index d01484e2a1c..00ae00b7011 100644
--- a/chromium/mojo/public/cpp/bindings/lib/array_internal.h
+++ b/chromium/mojo/public/cpp/bindings/lib/array_internal.h
@@ -14,10 +14,10 @@
#include "base/logging.h"
#include "mojo/public/c/system/macros.h"
#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
-#include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
#include "mojo/public/cpp/bindings/lib/bounds_checker.h"
#include "mojo/public/cpp/bindings/lib/buffer.h"
#include "mojo/public/cpp/bindings/lib/map_data_internal.h"
+#include "mojo/public/cpp/bindings/lib/serialization_util.h"
#include "mojo/public/cpp/bindings/lib/template_util.h"
#include "mojo/public/cpp/bindings/lib/validate_params.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
@@ -60,7 +60,7 @@ struct ArrayDataTraits {
template <typename P>
struct ArrayDataTraits<P*> {
- typedef StructPointer<P> StorageType;
+ typedef Pointer<P> StorageType;
typedef P*& Ref;
typedef P* const& ConstRef;
@@ -79,27 +79,6 @@ struct ArrayDataTraits<P*> {
}
};
-template <typename T>
-struct ArrayDataTraits<Array_Data<T>*> {
- typedef ArrayPointer<T> StorageType;
- typedef Array_Data<T>*& Ref;
- typedef Array_Data<T>* const& ConstRef;
-
- static const uint32_t kMaxNumElements =
- (kMaxUint32 - sizeof(ArrayHeader)) / sizeof(StorageType);
-
- static uint32_t GetStorageSize(uint32_t num_elements) {
- DCHECK(num_elements <= kMaxNumElements);
- return sizeof(ArrayHeader) + sizeof(StorageType) * num_elements;
- }
- static Ref ToRef(StorageType* storage, size_t offset) {
- return storage[offset].ptr;
- }
- static ConstRef ToConstRef(const StorageType* storage, size_t offset) {
- return storage[offset].ptr;
- }
-};
-
// Specialization of Arrays for bools, optimized for space. It has the
// following differences from a generalized Array:
// * Each element takes up a single bit of memory.
@@ -149,20 +128,18 @@ struct ArrayDataTraits<bool> {
// of unions are inlined so they are not pointers, but comparing with primitives
// they require more work for serialization/validation.
-template <typename T, bool is_handle, bool is_union>
+template <typename T, bool is_union>
struct ArraySerializationHelper;
template <typename T>
-struct ArraySerializationHelper<T, false, false> {
+struct ArraySerializationHelper<T, false> {
typedef typename ArrayDataTraits<T>::StorageType ElementType;
- static void EncodePointersAndHandles(const ArrayHeader* header,
- ElementType* elements,
- std::vector<Handle>* handles) {}
+ static void EncodePointers(const ArrayHeader* header,
+ ElementType* elements) {}
- static void DecodePointersAndHandles(const ArrayHeader* header,
- ElementType* elements,
- std::vector<Handle>* handles) {}
+ static void DecodePointers(const ArrayHeader* header,
+ ElementType* elements) {}
static bool ValidateElements(const ArrayHeader* header,
const ElementType* elements,
@@ -173,43 +150,27 @@ struct ArraySerializationHelper<T, false, false> {
DCHECK(!validate_params->element_validate_params)
<< "Primitive type should not have array validate params";
- return ValidateCaller<ElementType>::Run(header, elements);
- }
-
- private:
- template <typename U, bool is_enum = IsEnumDataType<U>::value>
- struct ValidateCaller {};
-
- template <typename U>
- struct ValidateCaller<U, false> {
- static bool Run(const ArrayHeader* header, const ElementType* elements) {
+ if (!validate_params->validate_enum_func)
return true;
- }
- };
- template <typename U>
- struct ValidateCaller<U, true> {
- static bool Run(const ArrayHeader* header, const ElementType* elements) {
- for (uint32_t i = 0; i < header->num_elements; ++i) {
- if (!ValidateEnum(elements[i]))
- return false;
- }
- return true;
+ // Enum validation.
+ for (uint32_t i = 0; i < header->num_elements; ++i) {
+ if (!validate_params->validate_enum_func(elements[i]))
+ return false;
}
- };
+ return true;
+ }
};
template <>
-struct ArraySerializationHelper<Handle, true, false> {
- typedef ArrayDataTraits<Handle>::StorageType ElementType;
+struct ArraySerializationHelper<Handle_Data, false> {
+ typedef ArrayDataTraits<Handle_Data>::StorageType ElementType;
- static void EncodePointersAndHandles(const ArrayHeader* header,
- ElementType* elements,
- std::vector<Handle>* handles);
+ static void EncodePointers(const ArrayHeader* header,
+ ElementType* elements) {}
- static void DecodePointersAndHandles(const ArrayHeader* header,
- ElementType* elements,
- std::vector<Handle>* handles);
+ static void DecodePointers(const ArrayHeader* header,
+ ElementType* elements) {}
static bool ValidateElements(const ArrayHeader* header,
const ElementType* elements,
@@ -219,8 +180,7 @@ struct ArraySerializationHelper<Handle, true, false> {
<< "Handle type should not have array validate params";
for (uint32_t i = 0; i < header->num_elements; ++i) {
- if (!validate_params->element_is_nullable &&
- elements[i].value() == kEncodedInvalidHandleValue) {
+ if (!validate_params->element_is_nullable && !elements[i].is_valid()) {
ReportValidationError(
VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
MakeMessageWithArrayIndex(
@@ -238,49 +198,18 @@ struct ArraySerializationHelper<Handle, true, false> {
}
};
-template <typename H>
-struct ArraySerializationHelper<H, true, false> {
- typedef typename ArrayDataTraits<H>::StorageType ElementType;
-
- static void EncodePointersAndHandles(const ArrayHeader* header,
- ElementType* elements,
- std::vector<Handle>* handles) {
- ArraySerializationHelper<Handle, true, false>::EncodePointersAndHandles(
- header, elements, handles);
- }
-
- static void DecodePointersAndHandles(const ArrayHeader* header,
- ElementType* elements,
- std::vector<Handle>* handles) {
- ArraySerializationHelper<Handle, true, false>::DecodePointersAndHandles(
- header, elements, handles);
- }
-
- static bool ValidateElements(const ArrayHeader* header,
- const ElementType* elements,
- BoundsChecker* bounds_checker,
- const ArrayValidateParams* validate_params) {
- return ArraySerializationHelper<Handle, true, false>::ValidateElements(
- header, elements, bounds_checker, validate_params);
- }
-};
-
template <typename P>
-struct ArraySerializationHelper<P*, false, false> {
+struct ArraySerializationHelper<P*, false> {
typedef typename ArrayDataTraits<P*>::StorageType ElementType;
- static void EncodePointersAndHandles(const ArrayHeader* header,
- ElementType* elements,
- std::vector<Handle>* handles) {
+ static void EncodePointers(const ArrayHeader* header, ElementType* elements) {
for (uint32_t i = 0; i < header->num_elements; ++i)
- Encode(&elements[i], handles);
+ Encode(&elements[i]);
}
- static void DecodePointersAndHandles(const ArrayHeader* header,
- ElementType* elements,
- std::vector<Handle>* handles) {
+ static void DecodePointers(const ArrayHeader* header, ElementType* elements) {
for (uint32_t i = 0; i < header->num_elements; ++i)
- Decode(&elements[i], handles);
+ Decode(&elements[i]);
}
static bool ValidateElements(const ArrayHeader* header,
@@ -343,21 +272,17 @@ struct ArraySerializationHelper<P*, false, false> {
};
template <typename U>
-struct ArraySerializationHelper<U, false, true> {
+struct ArraySerializationHelper<U, true> {
typedef typename ArrayDataTraits<U>::StorageType ElementType;
- static void EncodePointersAndHandles(const ArrayHeader* header,
- ElementType* elements,
- std::vector<Handle>* handles) {
+ static void EncodePointers(const ArrayHeader* header, ElementType* elements) {
for (uint32_t i = 0; i < header->num_elements; ++i)
- elements[i].EncodePointersAndHandles(handles);
+ elements[i].EncodePointers();
}
- static void DecodePointersAndHandles(const ArrayHeader* header,
- ElementType* elements,
- std::vector<Handle>* handles) {
+ static void DecodePointers(const ArrayHeader* header, ElementType* elements) {
for (uint32_t i = 0; i < header->num_elements; ++i)
- elements[i].DecodePointersAndHandles(handles);
+ elements[i].DecodePointers();
}
static bool ValidateElements(const ArrayHeader* header,
@@ -383,14 +308,12 @@ struct ArraySerializationHelper<U, false, true> {
template <typename T>
class Array_Data {
public:
- typedef ArrayDataTraits<T> Traits;
- typedef typename Traits::StorageType StorageType;
- typedef typename Traits::Ref Ref;
- typedef typename Traits::ConstRef ConstRef;
- typedef ArraySerializationHelper<T,
- IsHandle<T>::value,
- IsUnionDataType<T>::value>
- Helper;
+ using Traits = ArrayDataTraits<T>;
+ using StorageType = typename Traits::StorageType;
+ using Ref = typename Traits::Ref;
+ using ConstRef = typename Traits::ConstRef;
+ using Helper = ArraySerializationHelper<T, IsUnionDataType<T>::value>;
+ using Element = T;
// Returns null if |num_elements| or the corresponding storage size cannot be
// stored in uint32_t.
@@ -465,13 +388,8 @@ class Array_Data {
reinterpret_cast<const char*>(this) + sizeof(*this));
}
- void EncodePointersAndHandles(std::vector<Handle>* handles) {
- Helper::EncodePointersAndHandles(&header_, storage(), handles);
- }
-
- void DecodePointersAndHandles(std::vector<Handle>* handles) {
- Helper::DecodePointersAndHandles(&header_, storage(), handles);
- }
+ void EncodePointers() { Helper::EncodePointers(&header_, storage()); }
+ void DecodePointers() { Helper::DecodePointers(&header_, storage()); }
private:
Array_Data(uint32_t num_bytes, uint32_t num_elements) {
diff --git a/chromium/mojo/public/cpp/bindings/lib/array_serialization.h b/chromium/mojo/public/cpp/bindings/lib/array_serialization.h
index d5a59af2c19..3b4033b4fdf 100644
--- a/chromium/mojo/public/cpp/bindings/lib/array_serialization.h
+++ b/chromium/mojo/public/cpp/bindings/lib/array_serialization.h
@@ -6,38 +6,397 @@
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
#include <stddef.h>
+#include <string.h> // For |memcpy()|.
+#include <limits>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "base/logging.h"
#include "mojo/public/cpp/bindings/array.h"
-#include "mojo/public/cpp/bindings/lib/array_serialization_traits.h"
+#include "mojo/public/cpp/bindings/lib/array_internal.h"
+#include "mojo/public/cpp/bindings/lib/serialization_forward.h"
+#include "mojo/public/cpp/bindings/lib/template_util.h"
+#include "mojo/public/cpp/bindings/lib/validation_errors.h"
+
+namespace WTF {
+class String;
+}
namespace mojo {
+namespace internal {
-template <typename E>
-inline size_t GetSerializedSize_(const Array<E>& input,
- internal::SerializationContext* context) {
- return internal::ArraySerializationImpl<Array<E>>::GetSerializedSize(input,
- context);
-}
+enum class ArraySerializerType {
+ BOOLEAN,
+ // Except boolean.
+ POD,
+ HANDLE,
+ // String, array, map and struct.
+ POINTER,
+ UNION
+};
-template <typename E, typename F>
-inline void SerializeArray_(
- Array<E> input,
- internal::Buffer* buf,
- internal::Array_Data<F>** output,
- const internal::ArrayValidateParams* validate_params,
- internal::SerializationContext* context) {
- return internal::ArraySerializationImpl<Array<E>>::template Serialize<F>(
- std::move(input), buf, output, validate_params, context);
-}
+template <typename T>
+struct GetArraySerializerType {
+ static const ArraySerializerType value =
+ IsUnionDataType<T>::value
+ ? ArraySerializerType::UNION
+ : (std::is_pointer<T>::value
+ ? ArraySerializerType::POINTER
+ : (IsHandle<T>::value ? ArraySerializerType::HANDLE
+ : (std::is_same<T, bool>::value
+ ? ArraySerializerType::BOOLEAN
+ : ArraySerializerType::POD)));
+};
-template <typename E, typename F>
-inline bool Deserialize_(internal::Array_Data<F>* input,
- Array<E>* output,
- internal::SerializationContext* context) {
- return internal::ArraySerializationImpl<Array<E>>::template Deserialize<F>(
- input, output, context);
-}
+template <typename MojomType,
+ typename MaybeConstUserType,
+ ArraySerializerType type =
+ GetArraySerializerType<typename MojomType::Data_::Element>::value>
+struct ArraySerializer;
+
+// Handles serialization and deserialization of arrays of pod types.
+template <typename MojomType, typename MaybeConstUserType>
+struct ArraySerializer<MojomType,
+ MaybeConstUserType,
+ ArraySerializerType::POD> {
+ using UserType = typename std::remove_const<MaybeConstUserType>::type;
+ using Data = typename MojomType::Data_;
+ using DataElement = typename Data::Element;
+ using Element = typename MojomType::Element;
+ using Traits = ArrayTraits<UserType>;
+
+ static_assert(sizeof(Element) == sizeof(DataElement),
+ "Incorrect array serializer");
+ static_assert(std::is_same<Element, typename Traits::Element>::value,
+ "Incorrect array serializer");
+
+ static size_t GetSerializedSize(MaybeConstUserType& input,
+ SerializationContext* context) {
+ return sizeof(Data) + Align(Traits::GetSize(input) * sizeof(DataElement));
+ }
+
+ static void SerializeElements(MaybeConstUserType& input,
+ Buffer* buf,
+ Data* output,
+ const ArrayValidateParams* validate_params,
+ SerializationContext* context) {
+ DCHECK(!validate_params->element_is_nullable)
+ << "Primitive type should be non-nullable";
+ DCHECK(!validate_params->element_validate_params)
+ << "Primitive type should not have array validate params";
+
+ if (Traits::GetSize(input)) {
+ memcpy(output->storage(), Traits::GetData(input),
+ Traits::GetSize(input) * sizeof(DataElement));
+ }
+ }
+
+ static bool DeserializeElements(Data* input,
+ UserType* output,
+ SerializationContext* context) {
+ Traits::Resize(*output, input->size());
+ if (input->size()) {
+ memcpy(Traits::GetData(*output), input->storage(),
+ input->size() * sizeof(DataElement));
+ }
+ return true;
+ }
+};
+
+// Serializes and deserializes arrays of bools.
+template <typename MojomType, typename MaybeConstUserType>
+struct ArraySerializer<MojomType,
+ MaybeConstUserType,
+ ArraySerializerType::BOOLEAN> {
+ using UserType = typename std::remove_const<MaybeConstUserType>::type;
+ using Traits = ArrayTraits<UserType>;
+ using Data = typename MojomType::Data_;
+
+ static_assert(std::is_same<bool, typename UserType::Element>::value,
+ "Incorrect array serializer");
+
+ static size_t GetSerializedSize(MaybeConstUserType& input,
+ SerializationContext* context) {
+ return sizeof(Data) + Align((Traits::GetSize(input) + 7) / 8);
+ }
+
+ static void SerializeElements(MaybeConstUserType& input,
+ Buffer* buf,
+ Data* output,
+ const ArrayValidateParams* validate_params,
+ SerializationContext* context) {
+ DCHECK(!validate_params->element_is_nullable)
+ << "Primitive type should be non-nullable";
+ DCHECK(!validate_params->element_validate_params)
+ << "Primitive type should not have array validate params";
+
+ // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
+ size_t size = Traits::GetSize(input);
+ for (size_t i = 0; i < size; ++i)
+ output->at(i) = Traits::GetAt(input, i);
+ }
+ static bool DeserializeElements(Data* input,
+ UserType* output,
+ SerializationContext* context) {
+ Traits::Resize(*output, input->size());
+ // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
+ for (size_t i = 0; i < input->size(); ++i)
+ Traits::GetAt(*output, i) = input->at(i);
+ return true;
+ }
+};
+
+// Serializes and deserializes arrays of handles.
+template <typename MojomType, typename MaybeConstUserType>
+struct ArraySerializer<MojomType,
+ MaybeConstUserType,
+ ArraySerializerType::HANDLE> {
+ using UserType = typename std::remove_const<MaybeConstUserType>::type;
+ using Data = typename MojomType::Data_;
+ using Element = typename MojomType::Element;
+ using Traits = ArrayTraits<UserType>;
+
+ static_assert(std::is_same<Element, typename Traits::Element>::value,
+ "Incorrect array serializer");
+
+ static size_t GetSerializedSize(MaybeConstUserType& input,
+ SerializationContext* context) {
+ return sizeof(Data) +
+ Align(Traits::GetSize(input) * sizeof(typename Data::Element));
+ }
+
+ static void SerializeElements(MaybeConstUserType& input,
+ Buffer* buf,
+ Data* output,
+ const ArrayValidateParams* validate_params,
+ SerializationContext* context) {
+ DCHECK(!validate_params->element_validate_params)
+ << "Handle type should not have array validate params";
+
+ size_t size = Traits::GetSize(input);
+ for (size_t i = 0; i < size; ++i) {
+ // Transfer ownership of the handle.
+ output->at(i) =
+ context->handles.AddHandle(Traits::GetAt(input, i).release());
+ MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
+ !validate_params->element_is_nullable && !output->at(i).is_valid(),
+ VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
+ MakeMessageWithArrayIndex(
+ "invalid handle in array expecting valid handles", size, i));
+ }
+ }
+ static bool DeserializeElements(Data* input,
+ UserType* output,
+ SerializationContext* context) {
+ using HandleType = typename Element::RawHandleType;
+ Traits::Resize(*output, input->size());
+ for (size_t i = 0; i < input->size(); ++i) {
+ Traits::GetAt(*output, i) = MakeScopedHandle(
+ HandleType(context->handles.TakeHandle(input->at(i)).value()));
+ }
+ return true;
+ }
+};
+
+// This template must only apply to pointer mojo entity (strings, structs,
+// arrays and maps).
+template <typename MojomType, typename MaybeConstUserType>
+struct ArraySerializer<MojomType,
+ MaybeConstUserType,
+ ArraySerializerType::POINTER> {
+ using UserType = typename std::remove_const<MaybeConstUserType>::type;
+ using Data = typename MojomType::Data_;
+ using DataElement = typename Data::Element;
+ using Element = typename MojomType::Element;
+ using Traits = ArrayTraits<UserType>;
+
+ static size_t GetSerializedSize(MaybeConstUserType& input,
+ SerializationContext* context) {
+ size_t element_count = Traits::GetSize(input);
+ size_t size =
+ sizeof(Data) +
+ element_count *
+ sizeof(Pointer<typename std::remove_pointer<DataElement>::type>);
+ for (size_t i = 0; i < element_count; ++i)
+ size += PrepareToSerialize<Element>(Traits::GetAt(input, i), context);
+ return size;
+ }
+
+ static void SerializeElements(MaybeConstUserType& input,
+ Buffer* buf,
+ Data* output,
+ const ArrayValidateParams* validate_params,
+ SerializationContext* context) {
+ size_t size = Traits::GetSize(input);
+ for (size_t i = 0; i < size; ++i) {
+ DataElement element;
+ SerializeCaller<Element>::Run(Traits::GetAt(input, i), buf, &element,
+ validate_params->element_validate_params,
+ context);
+ output->at(i) = element;
+ MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
+ !validate_params->element_is_nullable && !element,
+ VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
+ MakeMessageWithArrayIndex("null in array expecting valid pointers",
+ size, i));
+ }
+ }
+ static bool DeserializeElements(Data* input,
+ UserType* output,
+ SerializationContext* context) {
+ bool success = true;
+ Traits::Resize(*output, input->size());
+ for (size_t i = 0; i < input->size(); ++i) {
+ // Note that we rely on complete deserialization taking place in order to
+ // transfer ownership of all encoded handles. Therefore we don't
+ // short-circuit on failure here.
+ if (!Deserialize<Element>(input->at(i), &Traits::GetAt(*output, i),
+ context)) {
+ success = false;
+ }
+ }
+ return success;
+ }
+
+ private:
+ template <typename T,
+ bool is_array_or_map = IsSpecializationOf<Array, T>::value ||
+ IsSpecializationOf<Map, T>::value>
+ struct SerializeCaller {
+ template <typename InputElementType>
+ static void Run(InputElementType&& input,
+ Buffer* buf,
+ DataElement* output,
+ const ArrayValidateParams* validate_params,
+ SerializationContext* context) {
+ Serialize<T>(std::forward<InputElementType>(input), buf, output, context);
+ }
+ };
+
+ template <typename T>
+ struct SerializeCaller<T, true> {
+ template <typename InputElementType>
+ static void Run(InputElementType&& input,
+ Buffer* buf,
+ DataElement* output,
+ const ArrayValidateParams* validate_params,
+ SerializationContext* context) {
+ Serialize<T>(std::forward<InputElementType>(input), buf, output,
+ validate_params, context);
+ }
+ };
+};
+
+// Handles serialization and deserialization of arrays of unions.
+template <typename MojomType, typename MaybeConstUserType>
+struct ArraySerializer<MojomType,
+ MaybeConstUserType,
+ ArraySerializerType::UNION> {
+ using UserType = typename std::remove_const<MaybeConstUserType>::type;
+ using Data = typename MojomType::Data_;
+ using Element = typename MojomType::Element;
+ using Traits = ArrayTraits<UserType>;
+
+ static_assert(std::is_same<typename MojomType::Element,
+ typename Traits::Element>::value,
+ "Incorrect array serializer");
+
+ static size_t GetSerializedSize(MaybeConstUserType& input,
+ SerializationContext* context) {
+ size_t element_count = Traits::GetSize(input);
+ size_t size = sizeof(Data);
+ for (size_t i = 0; i < element_count; ++i) {
+ // Call with |inlined| set to false, so that it will account for both the
+ // data in the union and the space in the array used to hold the union.
+ size +=
+ PrepareToSerialize<Element>(Traits::GetAt(input, i), false, context);
+ }
+ return size;
+ }
+
+ static void SerializeElements(MaybeConstUserType& input,
+ Buffer* buf,
+ Data* output,
+ const ArrayValidateParams* validate_params,
+ SerializationContext* context) {
+ size_t size = Traits::GetSize(input);
+ for (size_t i = 0; i < size; ++i) {
+ typename Data::Element* result = output->storage() + i;
+ Serialize<Element>(Traits::GetAt(input, i), buf, &result, true, context);
+ MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
+ !validate_params->element_is_nullable && output->at(i).is_null(),
+ VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
+ MakeMessageWithArrayIndex("null in array expecting valid unions",
+ size, i));
+ }
+ }
+
+ static bool DeserializeElements(Data* input,
+ UserType* output,
+ SerializationContext* context) {
+ bool success = true;
+ Traits::Resize(*output, input->size());
+ for (size_t i = 0; i < input->size(); ++i) {
+ // Note that we rely on complete deserialization taking place in order to
+ // transfer ownership of all encoded handles. Therefore we don't
+ // short-circuit on failure here.
+ if (!Deserialize<Element>(&input->at(i), &Traits::GetAt(*output, i),
+ context)) {
+ success = false;
+ }
+ }
+ return success;
+ }
+};
+
+template <typename Element, typename MaybeConstUserType>
+struct Serializer<Array<Element>, MaybeConstUserType> {
+ using UserType = typename std::remove_const<MaybeConstUserType>::type;
+ using Impl = ArraySerializer<Array<Element>, MaybeConstUserType>;
+ using Traits = ArrayTraits<UserType>;
+ using Data = typename Array<Element>::Data_;
+
+ static size_t PrepareToSerialize(MaybeConstUserType& input,
+ SerializationContext* context) {
+ if (CallIsNullIfExists<Traits>(input))
+ return 0;
+ return Impl::GetSerializedSize(input, context);
+ }
+
+ static void Serialize(MaybeConstUserType& input,
+ Buffer* buf,
+ Data** output,
+ const ArrayValidateParams* validate_params,
+ SerializationContext* context) {
+ if (!CallIsNullIfExists<Traits>(input)) {
+ MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
+ validate_params->expected_num_elements != 0 &&
+ Traits::GetSize(input) != validate_params->expected_num_elements,
+ internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
+ internal::MakeMessageWithExpectedArraySize(
+ "fixed-size array has wrong number of elements",
+ Traits::GetSize(input), validate_params->expected_num_elements));
+ Data* result = Data::New(Traits::GetSize(input), buf);
+ if (result)
+ Impl::SerializeElements(input, buf, result, validate_params, context);
+ *output = result;
+ } else {
+ *output = nullptr;
+ }
+ }
+
+ static bool Deserialize(Data* input,
+ UserType* output,
+ SerializationContext* context) {
+ if (!input)
+ return CallSetToNullIfExists<Traits>(output);
+ return Impl::DeserializeElements(input, output, context);
+ }
+};
+} // namespace internal
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/array_serialization_traits.h b/chromium/mojo/public/cpp/bindings/lib/array_serialization_traits.h
deleted file mode 100644
index 17817e01951..00000000000
--- a/chromium/mojo/public/cpp/bindings/lib/array_serialization_traits.h
+++ /dev/null
@@ -1,456 +0,0 @@
-// Copyright 2016 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_BINDINGS_LIB_ARRAY_SERIALIZATION_TRAITS_H_
-#define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_TRAITS_H_
-
-#include <stddef.h>
-#include <string.h> // For |memcpy()|.
-
-#include <limits>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-#include "base/logging.h"
-#include "mojo/public/cpp/bindings/lib/array_internal.h"
-#include "mojo/public/cpp/bindings/lib/serialization_forward.h"
-#include "mojo/public/cpp/bindings/lib/template_util.h"
-#include "mojo/public/cpp/bindings/lib/validation_errors.h"
-
-namespace WTF {
-class String;
-}
-
-namespace mojo {
-namespace internal {
-
-template <typename ArrayType,
- typename ElementType,
- typename ElementDataType,
- bool is_union = IsUnionDataType<
- typename RemovePointer<ElementDataType>::type>::value>
-struct ArraySerializer;
-
-// Handles serialization and deserialization of arrays of pod types.
-template <typename ArrayType, typename E, typename F>
-struct ArraySerializer<ArrayType, E, F, false> {
- static_assert(sizeof(E) == sizeof(F), "Incorrect array serializer");
- static size_t GetSerializedSize(const ArrayType& input,
- SerializationContext* context) {
- return sizeof(Array_Data<F>) + Align(input.size() * sizeof(E));
- }
-
- static void SerializeElements(ArrayType input,
- Buffer* buf,
- Array_Data<F>* output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- DCHECK(!validate_params->element_is_nullable)
- << "Primitive type should be non-nullable";
- DCHECK(!validate_params->element_validate_params)
- << "Primitive type should not have array validate params";
-
- if (input.size())
- memcpy(output->storage(), &input.storage()[0], input.size() * sizeof(E));
- }
- static bool DeserializeElements(Array_Data<F>* input,
- ArrayType* output,
- SerializationContext* context) {
- ArrayType result(input->size());
- if (input->size())
- memcpy(&result.front(), input->storage(), input->size() * sizeof(E));
- output->Swap(&result);
- return true;
- }
-};
-
-// Serializes and deserializes arrays of bools.
-template <typename ArrayType>
-struct ArraySerializer<ArrayType, bool, bool, false> {
- static size_t GetSerializedSize(const ArrayType& input,
- SerializationContext* context) {
- return sizeof(Array_Data<bool>) + Align((input.size() + 7) / 8);
- }
-
- static void SerializeElements(ArrayType input,
- Buffer* buf,
- Array_Data<bool>* output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- DCHECK(!validate_params->element_is_nullable)
- << "Primitive type should be non-nullable";
- DCHECK(!validate_params->element_validate_params)
- << "Primitive type should not have array validate params";
-
- // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
- for (size_t i = 0; i < input.size(); ++i)
- output->at(i) = input[i];
- }
- static bool DeserializeElements(Array_Data<bool>* input,
- ArrayType* output,
- SerializationContext* context) {
- ArrayType result(input->size());
- // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
- for (size_t i = 0; i < input->size(); ++i)
- result.at(i) = input->at(i);
- output->Swap(&result);
- return true;
- }
-};
-
-// Serializes and deserializes arrays of handles.
-template <typename ArrayType, typename H>
-struct ArraySerializer<ArrayType, ScopedHandleBase<H>, H, false> {
- static size_t GetSerializedSize(const ArrayType& input,
- SerializationContext* context) {
- return sizeof(Array_Data<H>) + Align(input.size() * sizeof(H));
- }
-
- static void SerializeElements(ArrayType input,
- Buffer* buf,
- Array_Data<H>* output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- DCHECK(!validate_params->element_validate_params)
- << "Handle type should not have array validate params";
-
- for (size_t i = 0; i < input.size(); ++i) {
- output->at(i) = input[i].release(); // Transfer ownership of the handle.
- MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
- !validate_params->element_is_nullable && !output->at(i).is_valid(),
- VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
- MakeMessageWithArrayIndex(
- "invalid handle in array expecting valid handles", input.size(),
- i));
- }
- }
- static bool DeserializeElements(Array_Data<H>* input,
- ArrayType* output,
- SerializationContext* context) {
- ArrayType result(input->size());
- for (size_t i = 0; i < input->size(); ++i)
- result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i)));
- output->Swap(&result);
- return true;
- }
-};
-
-// This template must only apply to pointer mojo entity (strings, structs,
-// arrays and maps). This is done by ensuring that WrapperTraits<S>::DataType is
-// a pointer.
-template <typename ArrayType, typename S>
-struct ArraySerializer<
- ArrayType,
- S,
- typename EnableIf<IsPointer<typename WrapperTraits<S>::DataType>::value,
- typename WrapperTraits<S>::DataType>::type,
- false> {
- typedef
- typename RemovePointer<typename WrapperTraits<S>::DataType>::type S_Data;
- static size_t GetSerializedSize(const ArrayType& input,
- SerializationContext* context) {
- size_t size = sizeof(Array_Data<S_Data*>) +
- input.size() * sizeof(StructPointer<S_Data>);
- for (size_t i = 0; i < input.size(); ++i)
- size += GetSerializedSize_(input[i], context);
- return size;
- }
-
- static void SerializeElements(ArrayType input,
- Buffer* buf,
- Array_Data<S_Data*>* output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- for (size_t i = 0; i < input.size(); ++i) {
- S_Data* element;
- SerializeCaller<S>::Run(std::move(input[i]), buf, &element,
- validate_params->element_validate_params,
- context);
- output->at(i) = element;
- MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
- !validate_params->element_is_nullable && !element,
- VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
- MakeMessageWithArrayIndex("null in array expecting valid pointers",
- input.size(), i));
- }
- }
- static bool DeserializeElements(Array_Data<S_Data*>* input,
- ArrayType* output,
- SerializationContext* context) {
- bool success = true;
- ArrayType result(input->size());
- for (size_t i = 0; i < input->size(); ++i) {
- // Note that we rely on complete deserialization taking place in order to
- // transfer ownership of all encoded handles. Therefore we don't
- // short-circuit on failure here.
- if (!Deserialize_(input->at(i), &result[i], context))
- success = false;
- }
- output->Swap(&result);
- return success;
- }
-
- private:
- template <typename T,
- bool is_array = IsSpecializationOf<Array, T>::value ||
- IsSpecializationOf<WTFArray, T>::value,
- bool is_string = std::is_same<T, String>::value ||
- std::is_same<T, WTF::String>::value>
- struct SerializeCaller {
- static void Run(T input,
- Buffer* buf,
- typename WrapperTraits<T>::DataType* output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- DCHECK(!validate_params)
- << "Struct type should not have array validate params";
-
- Serialize_(std::move(input), buf, output, context);
- }
- };
-
- template <typename T>
- struct SerializeCaller<T, true, false> {
- static void Run(T input,
- Buffer* buf,
- typename T::Data_** output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- SerializeArray_(std::move(input), buf, output, validate_params, context);
- }
- };
-
- template <typename T, typename U>
- struct SerializeCaller<Map<T, U>, false, false> {
- static void Run(Map<T, U> input,
- Buffer* buf,
- typename Map<T, U>::Data_** output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- SerializeMap_(std::move(input), buf, output, validate_params, context);
- }
- };
-
- template <typename T>
- struct SerializeCaller<T, false, true> {
- static void Run(const T& input,
- Buffer* buf,
- String_Data** output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- DCHECK(validate_params && !validate_params->element_validate_params &&
- !validate_params->element_is_nullable &&
- validate_params->expected_num_elements == 0)
- << "String type has unexpected array validate params";
-
- Serialize_(input, buf, output, context);
- }
- };
-};
-
-// Handles serialization and deserialization of arrays of unions.
-template <typename ArrayType, typename U, typename U_Data>
-struct ArraySerializer<ArrayType, U, U_Data, true> {
- static size_t GetSerializedSize(const ArrayType& input,
- SerializationContext* context) {
- size_t size = sizeof(Array_Data<U_Data>);
- for (size_t i = 0; i < input.size(); ++i) {
- // GetSerializedSize_ will account for both the data in the union and the
- // space in the array used to hold the union.
- size += GetSerializedSize_(input[i], false, context);
- }
- return size;
- }
-
- static void SerializeElements(ArrayType input,
- Buffer* buf,
- Array_Data<U_Data>* output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- for (size_t i = 0; i < input.size(); ++i) {
- U_Data* result = output->storage() + i;
- SerializeUnion_(std::move(input[i]), buf, &result, true, context);
- MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
- !validate_params->element_is_nullable && output->at(i).is_null(),
- VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
- MakeMessageWithArrayIndex("null in array expecting valid unions",
- input.size(), i));
- }
- }
-
- static bool DeserializeElements(Array_Data<U_Data>* input,
- ArrayType* output,
- SerializationContext* context) {
- bool success = true;
- ArrayType result(input->size());
- for (size_t i = 0; i < input->size(); ++i) {
- // Note that we rely on complete deserialization taking place in order to
- // transfer ownership of all encoded handles. Therefore we don't
- // short-circuit on failure here.
- if (!Deserialize_(&input->at(i), &result[i], context))
- success = false;
- }
- output->Swap(&result);
- return success;
- }
-};
-
-// Another layer of abstraction to switch between standard mojom type
-// serializers and native-only serializers.
-template <typename ArrayType,
- bool use_native =
- ShouldUseNativeSerializer<typename ArrayType::ElementType>::value>
-struct ArraySerializationStrategy;
-
-// Serialization strategy for standard mojom types. This branches further
-// by choosing an ArraySerializer specialization from above.
-template <typename ArrayType>
-struct ArraySerializationStrategy<ArrayType, false> {
- template <class DataType>
- using Serializer =
- ArraySerializer<ArrayType, typename ArrayType::ElementType, DataType>;
-
- static size_t GetSerializedSize(const ArrayType& input,
- SerializationContext* context) {
- DCHECK(input);
- return Serializer<typename WrapperTraits<
- typename ArrayType::ElementType>::DataType>::GetSerializedSize(input,
- context);
- }
-
- template <typename F>
- static void Serialize(ArrayType input,
- Buffer* buf,
- Array_Data<F>** output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- DCHECK(input);
- Array_Data<F>* result = Array_Data<F>::New(input.size(), buf);
- if (result) {
- Serializer<F>::SerializeElements(std::move(input), buf, result,
- validate_params, context);
- }
- *output = result;
- }
-
- template <typename F>
- static bool Deserialize(Array_Data<F>* input,
- ArrayType* output,
- SerializationContext* context) {
- DCHECK(input);
- return Serializer<F>::DeserializeElements(input, output, context);
- }
-};
-
-// Serialization for arrays of native-only types, which are opaquely serialized
-// as arrays of uint8_t arrays.
-template <typename ArrayType>
-struct ArraySerializationStrategy<ArrayType, true> {
- static size_t GetSerializedSize(const ArrayType& input,
- SerializationContext* context) {
- DCHECK(input);
- DCHECK_LE(input.size(), std::numeric_limits<uint32_t>::max());
- size_t size = ArrayDataTraits<Array_Data<uint8_t>*>::GetStorageSize(
- static_cast<uint32_t>(input.size()));
- for (size_t i = 0; i < input.size(); ++i) {
- size_t element_size = GetSerializedSizeNative_(input[i], context);
- DCHECK_LT(element_size, std::numeric_limits<uint32_t>::max());
- size += ArrayDataTraits<uint8_t>::GetStorageSize(
- static_cast<uint32_t>(element_size));
- }
- return size;
- }
-
- template <typename F>
- static void Serialize(ArrayType input,
- Buffer* buf,
- Array_Data<F>** output,
- const ArrayValidateParams* validate_params,
- SerializationContext* context) {
- static_assert(
- std::is_same<F, Array_Data<uint8_t>*>::value,
- "Native-only type array must serialize to array of byte arrays.");
- DCHECK(input);
- DCHECK(validate_params);
- // TODO(rockot): We may want to support nullable (i.e. scoped_ptr<T>)
- // elements here.
- DCHECK(!validate_params->element_is_nullable);
- Array_Data<Array_Data<uint8_t>*>* result =
- Array_Data<Array_Data<uint8_t>*>::New(input.size(), buf);
- for (size_t i = 0; i < input.size(); ++i)
- SerializeNative_(input[i], buf, &result->at(i), context);
- *output = result;
- }
-
- template <typename F>
- static bool Deserialize(Array_Data<F>* input,
- ArrayType* output,
- SerializationContext* context) {
- static_assert(
- std::is_same<F, Array_Data<uint8_t>*>::value,
- "Native-only type array must deserialize from array of byte arrays.");
- DCHECK(input);
-
- ArrayType result(input->size());
- bool success = true;
- for (size_t i = 0; i < input->size(); ++i) {
- // We don't short-circuit on failure since we can't know what the native
- // type's ParamTraits' expectations are.
- if (!DeserializeNative_(input->at(i), &result[i], context))
- success = false;
- }
- output->Swap(&result);
- return success;
- }
-};
-
-template <typename ArrayType>
-struct ArraySerializationImpl {
- using Strategy = ArraySerializationStrategy<ArrayType>;
-
- static size_t GetSerializedSize(const ArrayType& input,
- SerializationContext* context) {
- if (!input)
- return 0;
- return Strategy::GetSerializedSize(input, context);
- }
-
- template <typename F>
- static void Serialize(ArrayType input,
- internal::Buffer* buf,
- internal::Array_Data<F>** output,
- const internal::ArrayValidateParams* validate_params,
- SerializationContext* context) {
- if (input) {
- MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
- validate_params->expected_num_elements != 0 &&
- input.size() != validate_params->expected_num_elements,
- internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
- internal::MakeMessageWithExpectedArraySize(
- "fixed-size array has wrong number of elements", input.size(),
- validate_params->expected_num_elements));
- Strategy::template Serialize<F>(std::move(input), buf, output,
- validate_params, context);
- } else {
- *output = nullptr;
- }
- }
-
- template <typename F>
- static bool Deserialize(internal::Array_Data<F>* input,
- ArrayType* output,
- internal::SerializationContext* context) {
- if (input)
- return Strategy::template Deserialize<F>(input, output, context);
- *output = nullptr;
- return true;
- }
-};
-
-} // namespace internal
-
-} // namespace mojo
-
-#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_TRAITS_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/associated_group.cc b/chromium/mojo/public/cpp/bindings/lib/associated_group.cc
index 0bdf809d1ed..c3bde6f1b47 100644
--- a/chromium/mojo/public/cpp/bindings/lib/associated_group.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/associated_group.cc
@@ -24,8 +24,8 @@ AssociatedGroup& AssociatedGroup::operator=(const AssociatedGroup& other) {
}
void AssociatedGroup::CreateEndpointHandlePair(
- internal::ScopedInterfaceEndpointHandle* local_endpoint,
- internal::ScopedInterfaceEndpointHandle* remote_endpoint) {
+ ScopedInterfaceEndpointHandle* local_endpoint,
+ ScopedInterfaceEndpointHandle* remote_endpoint) {
if (!router_)
return;
diff --git a/chromium/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h b/chromium/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h
index 6f5f830d629..e214335a9ea 100644
--- a/chromium/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h
+++ b/chromium/mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h
@@ -6,11 +6,15 @@
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_ASSOCIATED_INTERFACE_PTR_STATE_H_
#include <stdint.h>
+
#include <algorithm> // For |std::swap()|.
+#include <memory>
#include <utility>
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/ptr_util.h"
+#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
#include "mojo/public/cpp/bindings/associated_group.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
#include "mojo/public/cpp/bindings/callback.h"
@@ -18,7 +22,7 @@
#include "mojo/public/cpp/bindings/lib/interface_endpoint_client.h"
#include "mojo/public/cpp/bindings/lib/interface_id.h"
#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
-#include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h"
+#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
#include "mojo/public/cpp/system/message_pipe.h"
namespace mojo {
@@ -77,7 +81,8 @@ class AssociatedInterfacePtrState {
swap(other->version_, version_);
}
- void Bind(AssociatedInterfacePtrInfo<Interface> info) {
+ void Bind(AssociatedInterfacePtrInfo<Interface> info,
+ scoped_refptr<base::SingleThreadTaskRunner> runner) {
DCHECK(!endpoint_client_);
DCHECK(!proxy_);
DCHECK_EQ(0u, version_);
@@ -85,8 +90,9 @@ class AssociatedInterfacePtrState {
version_ = info.version();
endpoint_client_.reset(new InterfaceEndpointClient(
- AssociatedInterfacePtrInfoHelper::PassHandle(&info), nullptr,
- make_scoped_ptr(new typename Interface::ResponseValidator_()), false));
+ info.PassHandle(), nullptr,
+ base::WrapUnique(new typename Interface::ResponseValidator_()), false,
+ std::move(runner)));
proxy_.reset(new Proxy(endpoint_client_.get()));
proxy_->serialization_context()->router = endpoint_client_->router();
}
@@ -97,11 +103,7 @@ class AssociatedInterfacePtrState {
ScopedInterfaceEndpointHandle handle = endpoint_client_->PassHandle();
endpoint_client_.reset();
proxy_.reset();
-
- AssociatedInterfacePtrInfo<Interface> result;
- result.set_version(version_);
- AssociatedInterfacePtrInfoHelper::SetHandle(&result, std::move(handle));
- return result;
+ return AssociatedInterfacePtrInfo<Interface>(std::move(handle), version_);
}
bool is_bound() const { return !!endpoint_client_; }
@@ -127,8 +129,8 @@ class AssociatedInterfacePtrState {
private:
using Proxy = typename Interface::Proxy_;
- scoped_ptr<InterfaceEndpointClient> endpoint_client_;
- scoped_ptr<Proxy> proxy_;
+ std::unique_ptr<InterfaceEndpointClient> endpoint_client_;
+ std::unique_ptr<Proxy> proxy_;
uint32_t version_;
diff --git a/chromium/mojo/public/cpp/bindings/lib/binding_state.h b/chromium/mojo/public/cpp/bindings/lib/binding_state.h
index b3588da724e..77a59f5d0ed 100644
--- a/chromium/mojo/public/cpp/bindings/lib/binding_state.h
+++ b/chromium/mojo/public/cpp/bindings/lib/binding_state.h
@@ -5,12 +5,14 @@
#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_H_
+#include <memory>
#include <utility>
#include "base/logging.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/single_thread_task_runner.h"
#include "mojo/public/cpp/bindings/associated_group.h"
#include "mojo/public/cpp/bindings/callback.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
@@ -22,7 +24,7 @@
#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
#include "mojo/public/cpp/bindings/lib/router.h"
-#include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h"
+#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
#include "mojo/public/cpp/system/core.h"
namespace mojo {
@@ -47,14 +49,16 @@ class BindingState<Interface, false> {
Close();
}
- void Bind(ScopedMessagePipeHandle handle) {
+ void Bind(ScopedMessagePipeHandle handle,
+ scoped_refptr<base::SingleThreadTaskRunner> runner) {
DCHECK(!router_);
internal::FilterChain filters;
filters.Append<internal::MessageHeaderValidator>();
filters.Append<typename Interface::RequestValidator_>();
- router_ = new internal::Router(std::move(handle), std::move(filters),
- Interface::HasSyncMethods_);
+ router_ =
+ new internal::Router(std::move(handle), std::move(filters),
+ Interface::HasSyncMethods_, std::move(runner));
router_->set_incoming_receiver(&stub_);
router_->set_connection_error_handler(
[this]() { connection_error_handler_.Run(); });
@@ -141,16 +145,17 @@ class BindingState<Interface, true> {
Close();
}
- void Bind(ScopedMessagePipeHandle handle) {
+ void Bind(ScopedMessagePipeHandle handle,
+ scoped_refptr<base::SingleThreadTaskRunner> runner) {
DCHECK(!router_);
- router_ = new internal::MultiplexRouter(false, std::move(handle));
+ router_ = new internal::MultiplexRouter(false, std::move(handle), runner);
stub_.serialization_context()->router = router_;
endpoint_client_.reset(new internal::InterfaceEndpointClient(
router_->CreateLocalEndpointHandle(internal::kMasterInterfaceId),
- &stub_, make_scoped_ptr(new typename Interface::RequestValidator_()),
- Interface::HasSyncMethods_));
+ &stub_, base::WrapUnique(new typename Interface::RequestValidator_()),
+ Interface::HasSyncMethods_, std::move(runner)));
endpoint_client_->set_connection_error_handler(
[this]() { connection_error_handler_.Run(); });
@@ -217,7 +222,7 @@ class BindingState<Interface, true> {
private:
scoped_refptr<internal::MultiplexRouter> router_;
- scoped_ptr<internal::InterfaceEndpointClient> endpoint_client_;
+ std::unique_ptr<internal::InterfaceEndpointClient> endpoint_client_;
typename Interface::Stub_ stub_;
Interface* impl_;
diff --git a/chromium/mojo/public/cpp/bindings/lib/bindings_internal.h b/chromium/mojo/public/cpp/bindings/lib/bindings_internal.h
index 8d320823139..f38c7645eb9 100644
--- a/chromium/mojo/public/cpp/bindings/lib/bindings_internal.h
+++ b/chromium/mojo/public/cpp/bindings/lib/bindings_internal.h
@@ -25,6 +25,14 @@ class InlinedStructPtr;
namespace internal {
+// Please note that this is a different value than |mojo::kInvalidHandleValue|,
+// which is the "decoded" invalid handle.
+const uint32_t kEncodedInvalidHandleValue = static_cast<uint32_t>(-1);
+
+// A serialized union always takes 16 bytes:
+// 4-byte size + 4-byte tag + 8-byte payload.
+const uint32_t kUnionDataSize = 16;
+
template <typename T>
class Array_Data;
@@ -45,32 +53,24 @@ struct ArrayHeader {
static_assert(sizeof(ArrayHeader) == 8, "Bad_sizeof(ArrayHeader)");
template <typename T>
-union StructPointer {
+union Pointer {
uint64_t offset;
T* ptr;
};
-static_assert(sizeof(StructPointer<char>) == 8, "Bad_sizeof(StructPointer)");
+static_assert(sizeof(Pointer<char>) == 8, "Bad_sizeof(Pointer)");
-template <typename T>
-union ArrayPointer {
- uint64_t offset;
- Array_Data<T>* ptr;
-};
-static_assert(sizeof(ArrayPointer<char>) == 8, "Bad_sizeof(ArrayPointer)");
-
-using StringPointer = ArrayPointer<char>;
-static_assert(sizeof(StringPointer) == 8, "Bad_sizeof(StringPointer)");
+struct Handle_Data {
+ Handle_Data() = default;
+ explicit Handle_Data(uint32_t value) : value(value) {}
+ bool is_valid() const { return value != kEncodedInvalidHandleValue; }
-template <typename T>
-union UnionPointer {
- uint64_t offset;
- T* ptr;
+ uint32_t value;
};
-static_assert(sizeof(UnionPointer<char>) == 8, "Bad_sizeof(UnionPointer)");
+static_assert(sizeof(Handle_Data) == 4, "Bad_sizeof(Handle_Data)");
struct Interface_Data {
- MessagePipeHandle handle;
+ Handle_Data handle;
uint32_t version;
};
static_assert(sizeof(Interface_Data) == 8, "Bad_sizeof(Interface_Data)");
@@ -101,30 +101,19 @@ T FetchAndReset(T* ptr) {
template <typename H>
struct IsHandle {
- enum { value = IsBaseOf<Handle, H>::value };
+ enum { value = 0 };
};
-template <typename T>
-struct IsUnionDataType {
- private:
- template <typename U>
- static YesType Test(const typename U::MojomUnionDataType*);
-
- template <typename U>
- static NoType Test(...);
-
- EnsureTypeIsComplete<T> check_t_;
-
- public:
- static const bool value =
- sizeof(Test<T>(0)) == sizeof(YesType) && !IsConst<T>::value;
+template <>
+struct IsHandle<Handle_Data> {
+ enum { value = 1 };
};
template <typename T>
-struct IsEnumDataType {
+struct IsUnionDataType {
private:
template <typename U>
- static YesType Test(const typename U::MojomEnumDataType*);
+ static YesType Test(const typename U::MojomUnionDataType*);
template <typename U>
static NoType Test(...);
@@ -136,38 +125,48 @@ struct IsEnumDataType {
sizeof(Test<T>(0)) == sizeof(YesType) && !IsConst<T>::value;
};
-template <typename T, bool move_only = IsMoveOnlyType<T>::value>
-struct WrapperTraits;
+template <typename MojomType, bool move_only = IsMoveOnlyType<MojomType>::value>
+struct GetDataTypeAsArrayElement;
template <typename T>
-struct WrapperTraits<T, false> {
- typedef T DataType;
+struct GetDataTypeAsArrayElement<T, false> {
+ using Data =
+ typename std::conditional<std::is_enum<T>::value, int32_t, T>::type;
};
template <typename H>
-struct WrapperTraits<ScopedHandleBase<H>, true> {
- typedef H DataType;
+struct GetDataTypeAsArrayElement<ScopedHandleBase<H>, true> {
+ using Data = Handle_Data;
};
template <typename S>
-struct WrapperTraits<StructPtr<S>, true> {
- typedef typename S::Data_* DataType;
+struct GetDataTypeAsArrayElement<StructPtr<S>, true> {
+ using Data =
+ typename std::conditional<IsUnionDataType<typename S::Data_>::value,
+ typename S::Data_,
+ typename S::Data_*>::type;
};
template <typename S>
-struct WrapperTraits<InlinedStructPtr<S>, true> {
- typedef typename S::Data_* DataType;
+struct GetDataTypeAsArrayElement<InlinedStructPtr<S>, true> {
+ using Data =
+ typename std::conditional<IsUnionDataType<typename S::Data_>::value,
+ typename S::Data_,
+ typename S::Data_*>::type;
};
template <typename S>
-struct WrapperTraits<S, true> {
- typedef typename S::Data_* DataType;
+struct GetDataTypeAsArrayElement<S, true> {
+ using Data =
+ typename std::conditional<IsUnionDataType<typename S::Data_>::value,
+ typename S::Data_,
+ typename S::Data_*>::type;
};
template <>
-struct WrapperTraits<String, false> {
- typedef String_Data* DataType;
+struct GetDataTypeAsArrayElement<String, false> {
+ using Data = String_Data*;
};
template <>
-struct WrapperTraits<WTF::String, false> {
- typedef String_Data* DataType;
+struct GetDataTypeAsArrayElement<WTF::String, false> {
+ using Data = String_Data*;
};
} // namespace internal
diff --git a/chromium/mojo/public/cpp/bindings/lib/bindings_serialization.cc b/chromium/mojo/public/cpp/bindings/lib/bindings_serialization.cc
deleted file mode 100644
index 48c52ddab5a..00000000000
--- a/chromium/mojo/public/cpp/bindings/lib/bindings_serialization.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2013 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 "mojo/public/cpp/bindings/lib/bindings_serialization.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "base/logging.h"
-
-namespace mojo {
-namespace internal {
-
-namespace {
-
-const size_t kAlignment = 8;
-
-template <typename T>
-T AlignImpl(T t) {
- return t + (kAlignment - (t % kAlignment)) % kAlignment;
-}
-
-} // namespace
-
-size_t Align(size_t size) {
- return AlignImpl(size);
-}
-
-char* AlignPointer(char* ptr) {
- return reinterpret_cast<char*>(AlignImpl(reinterpret_cast<uintptr_t>(ptr)));
-}
-
-bool IsAligned(const void* ptr) {
- return !(reinterpret_cast<uintptr_t>(ptr) % kAlignment);
-}
-
-void EncodePointer(const void* ptr, uint64_t* offset) {
- if (!ptr) {
- *offset = 0;
- return;
- }
-
- const char* p_obj = reinterpret_cast<const char*>(ptr);
- const char* p_slot = reinterpret_cast<const char*>(offset);
- DCHECK(p_obj > p_slot);
-
- *offset = static_cast<uint64_t>(p_obj - p_slot);
-}
-
-const void* DecodePointerRaw(const uint64_t* offset) {
- if (!*offset)
- return nullptr;
- return reinterpret_cast<const char*>(offset) + *offset;
-}
-
-void EncodeHandle(Handle* handle, std::vector<Handle>* handles) {
- if (handle->is_valid()) {
- handles->push_back(*handle);
- handle->set_value(static_cast<MojoHandle>(handles->size() - 1));
- } else {
- handle->set_value(kEncodedInvalidHandleValue);
- }
-}
-
-void EncodeHandle(Interface_Data* data, std::vector<Handle>* handles) {
- EncodeHandle(&data->handle, handles);
-}
-
-void EncodeHandle(MojoHandle* handle, std::vector<Handle>* handles) {
- EncodeHandle(reinterpret_cast<Handle*>(handle), handles);
-}
-
-void DecodeHandle(Handle* handle, std::vector<Handle>* handles) {
- if (handle->value() == kEncodedInvalidHandleValue) {
- *handle = Handle();
- return;
- }
- DCHECK(handle->value() < handles->size());
- // Just leave holes in the vector so we don't screw up other indices.
- *handle = FetchAndReset(&handles->at(handle->value()));
-}
-
-void DecodeHandle(Interface_Data* data, std::vector<Handle>* handles) {
- DecodeHandle(&data->handle, handles);
-}
-
-void DecodeHandle(MojoHandle* handle, std::vector<Handle>* handles) {
- DecodeHandle(reinterpret_cast<Handle*>(handle), handles);
-}
-
-SerializationContext::SerializationContext() {}
-
-SerializationContext::SerializationContext(
- scoped_refptr<MultiplexRouter> in_router)
- : router(std::move(in_router)) {}
-
-SerializationContext::~SerializationContext() {}
-
-} // namespace internal
-} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/bindings_serialization.h b/chromium/mojo/public/cpp/bindings/lib/bindings_serialization.h
deleted file mode 100644
index 7a10b1cb753..00000000000
--- a/chromium/mojo/public/cpp/bindings/lib/bindings_serialization.h
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2013 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_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_
-#define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <vector>
-
-#include "base/memory/ref_counted.h"
-#include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
-#include "mojo/public/cpp/bindings/interface_ptr.h"
-#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
-#include "mojo/public/cpp/system/core.h"
-
-namespace mojo {
-namespace internal {
-
-class MultiplexRouter;
-
-// Please note that this is a different value than |mojo::kInvalidHandleValue|,
-// which is the "decoded" invalid handle.
-const MojoHandle kEncodedInvalidHandleValue = static_cast<MojoHandle>(-1);
-
-size_t Align(size_t size);
-char* AlignPointer(char* ptr);
-
-bool IsAligned(const void* ptr);
-
-// Pointers are encoded as relative offsets. The offsets are relative to the
-// address of where the offset value is stored, such that the pointer may be
-// recovered with the expression:
-//
-// ptr = reinterpret_cast<char*>(offset) + *offset
-//
-// A null pointer is encoded as an offset value of 0.
-//
-void EncodePointer(const void* ptr, uint64_t* offset);
-// Note: This function doesn't validate the encoded pointer value.
-const void* DecodePointerRaw(const uint64_t* offset);
-
-// Note: This function doesn't validate the encoded pointer value.
-template <typename T>
-inline void DecodePointer(const uint64_t* offset, T** ptr) {
- *ptr = reinterpret_cast<T*>(const_cast<void*>(DecodePointerRaw(offset)));
-}
-
-// Handles are encoded as indices into a vector of handles. These functions
-// manipulate the value of |handle|, mapping it to and from an index.
-
-void EncodeHandle(Handle* handle, std::vector<Handle>* handles);
-void EncodeHandle(Interface_Data* data, std::vector<Handle>* handles);
-void EncodeHandle(MojoHandle* handle, std::vector<Handle>* handles);
-// Note: The following three functions don't validate the encoded handle value.
-void DecodeHandle(Handle* handle, std::vector<Handle>* handles);
-void DecodeHandle(Interface_Data* data, std::vector<Handle>* handles);
-void DecodeHandle(MojoHandle* handle, std::vector<Handle>* handles);
-
-// The following 2 functions are used to encode/decode all objects (structs and
-// arrays) in a consistent manner.
-
-template <typename T>
-inline void Encode(T* obj, std::vector<Handle>* handles) {
- if (obj->ptr)
- obj->ptr->EncodePointersAndHandles(handles);
- EncodePointer(obj->ptr, &obj->offset);
-}
-
-// Note: This function doesn't validate the encoded pointer and handle values.
-template <typename T>
-inline void Decode(T* obj, std::vector<Handle>* handles) {
- DecodePointer(&obj->offset, &obj->ptr);
- if (obj->ptr)
- obj->ptr->DecodePointersAndHandles(handles);
-}
-
-template <typename T>
-inline void InterfacePointerToData(InterfacePtr<T> input,
- Interface_Data* output) {
- InterfacePtrInfo<T> info = input.PassInterface();
- output->handle = info.PassHandle().release();
- output->version = info.version();
-}
-
-template <typename T>
-inline void InterfaceDataToPointer(Interface_Data* input,
- InterfacePtr<T>* output) {
- output->Bind(InterfacePtrInfo<T>(
- MakeScopedHandle(FetchAndReset(&input->handle)), input->version));
-}
-
-template <typename T>
-inline void AssociatedInterfacePtrInfoToData(
- AssociatedInterfacePtrInfo<T> input,
- AssociatedInterface_Data* output) {
- output->version = input.version();
- output->interface_id =
- AssociatedInterfacePtrInfoHelper::PassHandle(&input).release();
-}
-
-template <typename T>
-inline void AssociatedInterfaceDataToPtrInfo(
- AssociatedInterface_Data* input,
- AssociatedInterfacePtrInfo<T>* output,
- MultiplexRouter* router) {
- AssociatedInterfacePtrInfoHelper::SetHandle(
- output,
- router->CreateLocalEndpointHandle(FetchAndReset(&input->interface_id)));
- output->set_version(input->version);
-}
-
-class WTFStringContext {
- public:
- virtual ~WTFStringContext() {}
-};
-
-// Context information for serialization/deserialization routines.
-struct SerializationContext {
- SerializationContext();
- explicit SerializationContext(scoped_refptr<MultiplexRouter> in_router);
-
- ~SerializationContext();
-
- // Used to serialize/deserialize associated interface pointers and requests.
- scoped_refptr<MultiplexRouter> router;
-
- scoped_ptr<WTFStringContext> wtf_string_context;
-};
-
-} // namespace internal
-} // namespace mojo
-
-#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/bounds_checker.cc b/chromium/mojo/public/cpp/bindings/lib/bounds_checker.cc
index 64314ec21d2..49416d1116c 100644
--- a/chromium/mojo/public/cpp/bindings/lib/bounds_checker.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/bounds_checker.cc
@@ -8,7 +8,7 @@
#include <stdint.h>
#include "base/logging.h"
-#include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
+#include "mojo/public/cpp/bindings/lib/serialization_util.h"
#include "mojo/public/cpp/system/handle.h"
namespace mojo {
@@ -50,8 +50,8 @@ bool BoundsChecker::ClaimMemory(const void* position, uint32_t num_bytes) {
return true;
}
-bool BoundsChecker::ClaimHandle(const Handle& encoded_handle) {
- uint32_t index = encoded_handle.value();
+bool BoundsChecker::ClaimHandle(const Handle_Data& encoded_handle) {
+ uint32_t index = encoded_handle.value;
if (index == kEncodedInvalidHandleValue)
return true;
diff --git a/chromium/mojo/public/cpp/bindings/lib/bounds_checker.h b/chromium/mojo/public/cpp/bindings/lib/bounds_checker.h
index aac3b665c94..d59a68aa034 100644
--- a/chromium/mojo/public/cpp/bindings/lib/bounds_checker.h
+++ b/chromium/mojo/public/cpp/bindings/lib/bounds_checker.h
@@ -9,6 +9,7 @@
#include <stdint.h>
#include "base/macros.h"
+#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
namespace mojo {
@@ -38,7 +39,7 @@ class BoundsChecker {
// - |encoded_handle|'s value is |kEncodedInvalidHandleValue|.
// - the handle is contained inside the valid range of handle indices. In this
// case, the valid range is shinked to begin right after the claimed handle.
- bool ClaimHandle(const Handle& encoded_handle);
+ bool ClaimHandle(const Handle_Data& encoded_handle);
// Returns true if the specified range is not empty, and the range is
// contained inside the valid memory range.
diff --git a/chromium/mojo/public/cpp/bindings/lib/buffer.h b/chromium/mojo/public/cpp/bindings/lib/buffer.h
index 98bbce0e6ae..c3b570e7767 100644
--- a/chromium/mojo/public/cpp/bindings/lib/buffer.h
+++ b/chromium/mojo/public/cpp/bindings/lib/buffer.h
@@ -10,18 +10,12 @@
namespace mojo {
namespace internal {
-class PickleBuffer;
-
// Buffer provides a way to allocate memory. Allocations are 8-byte aligned and
// zero-initialized. Allocations remain valid for the lifetime of the Buffer.
class Buffer {
public:
virtual ~Buffer() {}
virtual void* Allocate(size_t num_bytes) = 0;
-
- // TODO(rockot): Remove this. It's a hack to get a PickleBuffer in
- // Serialize_ calls without having to update every call site.
- virtual PickleBuffer* AsPickleBuffer() = 0;
};
} // namespace internal
diff --git a/chromium/mojo/public/cpp/bindings/lib/connector.cc b/chromium/mojo/public/cpp/bindings/lib/connector.cc
index 70f9fd78b2a..9f1037ceae8 100644
--- a/chromium/mojo/public/cpp/bindings/lib/connector.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/connector.cc
@@ -8,10 +8,10 @@
#include <utility>
#include "base/bind.h"
+#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/synchronization/lock.h"
-#include "base/thread_task_runner_handle.h"
#include "mojo/public/cpp/bindings/lib/sync_handle_watcher.h"
namespace mojo {
@@ -45,9 +45,12 @@ class MayAutoLock {
// ----------------------------------------------------------------------------
Connector::Connector(ScopedMessagePipeHandle message_pipe,
- ConnectorConfig config)
+ ConnectorConfig config,
+ scoped_refptr<base::SingleThreadTaskRunner> runner)
: message_pipe_(std::move(message_pipe)),
incoming_receiver_(nullptr),
+ task_runner_(std::move(runner)),
+ handle_watcher_(task_runner_),
error_(false),
drop_writes_(false),
enforce_errors_from_incoming_receiver_(true),
@@ -147,21 +150,11 @@ bool Connector::Accept(Message* message) {
return true;
MojoResult rv =
- WriteMessageRaw(message_pipe_.get(),
- message->data(),
- message->data_num_bytes(),
- message->mutable_handles()->empty()
- ? nullptr
- : reinterpret_cast<const MojoHandle*>(
- &message->mutable_handles()->front()),
- static_cast<uint32_t>(message->mutable_handles()->size()),
+ WriteMessageNew(message_pipe_.get(), message->TakeMojoMessage(),
MOJO_WRITE_MESSAGE_FLAG_NONE);
switch (rv) {
case MOJO_RESULT_OK:
- // The handles were successfully transferred, so we don't need the message
- // to track their lifetime any longer.
- message->mutable_handles()->clear();
break;
case MOJO_RESULT_FAILED_PRECONDITION:
// There's no point in continuing to write to this pipe since the other
@@ -249,7 +242,7 @@ void Connector::WaitToReadMore() {
if (rv != MOJO_RESULT_OK) {
// If the watch failed because the handle is invalid or its conditions can
// no longer be met, we signal the error asynchronously to avoid reentry.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
+ task_runner_->PostTask(
FROM_HERE,
base::Bind(&Connector::OnWatcherHandleReady, weak_self_, rv));
}
diff --git a/chromium/mojo/public/cpp/bindings/lib/connector.h b/chromium/mojo/public/cpp/bindings/lib/connector.h
index f61c18fb897..243159ef32f 100644
--- a/chromium/mojo/public/cpp/bindings/lib/connector.h
+++ b/chromium/mojo/public/cpp/bindings/lib/connector.h
@@ -5,9 +5,11 @@
#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_CONNECTOR_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_CONNECTOR_H_
+#include <memory>
+
#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "mojo/public/cpp/bindings/callback.h"
#include "mojo/public/cpp/bindings/lib/sync_handle_watcher.h"
@@ -42,7 +44,9 @@ class Connector : public MessageReceiver {
};
// The Connector takes ownership of |message_pipe|.
- Connector(ScopedMessagePipeHandle message_pipe, ConnectorConfig config);
+ Connector(ScopedMessagePipeHandle message_pipe,
+ ConnectorConfig config,
+ scoped_refptr<base::SingleThreadTaskRunner> runner);
~Connector() override;
// Sets the receiver to handle messages read from the message pipe. The
@@ -139,6 +143,10 @@ class Connector : public MessageReceiver {
return sync_handle_watcher_callback_count_ > 0;
}
+ base::SingleThreadTaskRunner* task_runner() const {
+ return task_runner_.get();
+ }
+
private:
// Callback of mojo::Watcher.
void OnWatcherHandleReady(MojoResult result);
@@ -170,6 +178,7 @@ class Connector : public MessageReceiver {
ScopedMessagePipeHandle message_pipe_;
MessageReceiver* incoming_receiver_;
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
Watcher handle_watcher_;
bool error_;
@@ -180,9 +189,9 @@ class Connector : public MessageReceiver {
// If sending messages is allowed from multiple threads, |lock_| is used to
// protect modifications to |message_pipe_| and |drop_writes_|.
- scoped_ptr<base::Lock> lock_;
+ std::unique_ptr<base::Lock> lock_;
- scoped_ptr<SyncHandleWatcher> sync_watcher_;
+ std::unique_ptr<SyncHandleWatcher> sync_watcher_;
bool allow_woken_up_by_others_;
// If non-zero, currently the control flow is inside the sync handle watcher
// callback.
diff --git a/chromium/mojo/public/cpp/bindings/lib/control_message_handler.cc b/chromium/mojo/public/cpp/bindings/lib/control_message_handler.cc
index 1316b6d7d5c..1bcd87daf9e 100644
--- a/chromium/mojo/public/cpp/bindings/lib/control_message_handler.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/control_message_handler.cc
@@ -10,6 +10,7 @@
#include "base/logging.h"
#include "mojo/public/cpp/bindings/lib/message_builder.h"
+#include "mojo/public/cpp/bindings/lib/serialization.h"
#include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h"
namespace mojo {
@@ -55,14 +56,14 @@ bool ControlMessageHandler::Run(Message* message,
response_params_ptr->query_version_result = QueryVersionResult::New();
response_params_ptr->query_version_result->version = interface_version_;
- size_t size = GetSerializedSize_(response_params_ptr, nullptr);
+ size_t size = PrepareToSerialize<RunResponseMessageParamsPtr>(
+ response_params_ptr, &context_);
ResponseMessageBuilder builder(kRunMessageId, size, message->request_id());
RunResponseMessageParams_Data* response_params = nullptr;
- Serialize_(std::move(response_params_ptr), builder.buffer(), &response_params,
- nullptr);
- response_params->EncodePointersAndHandles(
- builder.message()->mutable_handles());
+ Serialize<RunResponseMessageParamsPtr>(response_params_ptr, builder.buffer(),
+ &response_params, &context_);
+ response_params->EncodePointers();
bool ok = responder->Accept(builder.message());
ALLOW_UNUSED_LOCAL(ok);
delete responder;
@@ -74,10 +75,10 @@ bool ControlMessageHandler::RunOrClosePipe(Message* message) {
RunOrClosePipeMessageParams_Data* params =
reinterpret_cast<RunOrClosePipeMessageParams_Data*>(
message->mutable_payload());
- params->DecodePointersAndHandles(message->mutable_handles());
+ params->DecodePointers();
RunOrClosePipeMessageParamsPtr params_ptr;
- Deserialize_(params, &params_ptr, nullptr);
+ Deserialize<RunOrClosePipeMessageParamsPtr>(params, &params_ptr, &context_);
return interface_version_ >= params_ptr->require_version->version;
}
diff --git a/chromium/mojo/public/cpp/bindings/lib/control_message_handler.h b/chromium/mojo/public/cpp/bindings/lib/control_message_handler.h
index 27acde8cbdf..13b5aa6214e 100644
--- a/chromium/mojo/public/cpp/bindings/lib/control_message_handler.h
+++ b/chromium/mojo/public/cpp/bindings/lib/control_message_handler.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include "base/macros.h"
+#include "mojo/public/cpp/bindings/lib/serialization_context.h"
#include "mojo/public/cpp/bindings/message.h"
namespace mojo {
@@ -32,6 +33,7 @@ class ControlMessageHandler : public MessageReceiverWithResponderStatus {
bool RunOrClosePipe(Message* message);
uint32_t interface_version_;
+ SerializationContext context_;
DISALLOW_COPY_AND_ASSIGN(ControlMessageHandler);
};
diff --git a/chromium/mojo/public/cpp/bindings/lib/control_message_proxy.cc b/chromium/mojo/public/cpp/bindings/lib/control_message_proxy.cc
index 620806502c2..6189e6973e7 100644
--- a/chromium/mojo/public/cpp/bindings/lib/control_message_proxy.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/control_message_proxy.cc
@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "mojo/public/cpp/bindings/lib/message_builder.h"
+#include "mojo/public/cpp/bindings/lib/serialization.h"
#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h"
@@ -35,10 +36,11 @@ bool RunResponseForwardToCallback::Accept(Message* message) {
RunResponseMessageParams_Data* params =
reinterpret_cast<RunResponseMessageParams_Data*>(
message->mutable_payload());
- params->DecodePointersAndHandles(message->mutable_handles());
+ params->DecodePointers();
RunResponseMessageParamsPtr params_ptr;
- Deserialize_(params, &params_ptr, nullptr);
+ SerializationContext context;
+ Deserialize<RunResponseMessageParamsPtr>(params, &params_ptr, &context);
callback_.Run(std::move(params_ptr->query_version_result));
return true;
@@ -46,36 +48,41 @@ bool RunResponseForwardToCallback::Accept(Message* message) {
void SendRunMessage(MessageReceiverWithResponder* receiver,
QueryVersionPtr query_version,
- const RunCallback& callback) {
+ const RunCallback& callback,
+ SerializationContext* context) {
RunMessageParamsPtr params_ptr(RunMessageParams::New());
params_ptr->reserved0 = 16u;
params_ptr->reserved1 = 0u;
params_ptr->query_version = std::move(query_version);
- size_t size = GetSerializedSize_(params_ptr, nullptr);
+ size_t size = PrepareToSerialize<RunMessageParamsPtr>(params_ptr, context);
RequestMessageBuilder builder(kRunMessageId, size);
RunMessageParams_Data* params = nullptr;
- Serialize_(std::move(params_ptr), builder.buffer(), &params, nullptr);
- params->EncodePointersAndHandles(builder.message()->mutable_handles());
+ Serialize<RunMessageParamsPtr>(params_ptr, builder.buffer(), &params,
+ context);
+ params->EncodePointers();
MessageReceiver* responder = new RunResponseForwardToCallback(callback);
if (!receiver->AcceptWithResponder(builder.message(), responder))
delete responder;
}
void SendRunOrClosePipeMessage(MessageReceiverWithResponder* receiver,
- RequireVersionPtr require_version) {
+ RequireVersionPtr require_version,
+ SerializationContext* context) {
RunOrClosePipeMessageParamsPtr params_ptr(RunOrClosePipeMessageParams::New());
params_ptr->reserved0 = 16u;
params_ptr->reserved1 = 0u;
params_ptr->require_version = std::move(require_version);
- size_t size = GetSerializedSize_(params_ptr, nullptr);
+ size_t size =
+ PrepareToSerialize<RunOrClosePipeMessageParamsPtr>(params_ptr, context);
MessageBuilder builder(kRunOrClosePipeMessageId, size);
RunOrClosePipeMessageParams_Data* params = nullptr;
- Serialize_(std::move(params_ptr), builder.buffer(), &params, nullptr);
- params->EncodePointersAndHandles(builder.message()->mutable_handles());
+ Serialize<RunOrClosePipeMessageParamsPtr>(params_ptr, builder.buffer(),
+ &params, context);
+ params->EncodePointers();
bool ok = receiver->Accept(builder.message());
ALLOW_UNUSED_LOCAL(ok);
}
@@ -91,13 +98,13 @@ void ControlMessageProxy::QueryVersion(
auto run_callback = [callback](QueryVersionResultPtr query_version_result) {
callback.Run(query_version_result->version);
};
- SendRunMessage(receiver_, QueryVersion::New(), run_callback);
+ SendRunMessage(receiver_, QueryVersion::New(), run_callback, &context_);
}
void ControlMessageProxy::RequireVersion(uint32_t version) {
RequireVersionPtr require_version(RequireVersion::New());
require_version->version = version;
- SendRunOrClosePipeMessage(receiver_, std::move(require_version));
+ SendRunOrClosePipeMessage(receiver_, std::move(require_version), &context_);
}
} // namespace internal
diff --git a/chromium/mojo/public/cpp/bindings/lib/control_message_proxy.h b/chromium/mojo/public/cpp/bindings/lib/control_message_proxy.h
index 33aaf82a9f3..ce20fc8415f 100644
--- a/chromium/mojo/public/cpp/bindings/lib/control_message_proxy.h
+++ b/chromium/mojo/public/cpp/bindings/lib/control_message_proxy.h
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "mojo/public/cpp/bindings/callback.h"
+#include "mojo/public/cpp/bindings/lib/serialization_context.h"
namespace mojo {
@@ -28,6 +29,7 @@ class ControlMessageProxy {
protected:
// Not owned.
MessageReceiverWithResponder* receiver_;
+ SerializationContext context_;
DISALLOW_COPY_AND_ASSIGN(ControlMessageProxy);
};
diff --git a/chromium/mojo/public/cpp/bindings/lib/fixed_buffer.cc b/chromium/mojo/public/cpp/bindings/lib/fixed_buffer.cc
index 9653345532e..50b8a21c56b 100644
--- a/chromium/mojo/public/cpp/bindings/lib/fixed_buffer.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/fixed_buffer.cc
@@ -10,7 +10,7 @@
#include <algorithm>
#include "base/logging.h"
-#include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
+#include "mojo/public/cpp/bindings/lib/serialization_util.h"
namespace mojo {
namespace internal {
@@ -39,8 +39,6 @@ void* FixedBuffer::Allocate(size_t delta) {
return result;
}
-PickleBuffer* FixedBuffer::AsPickleBuffer() { return nullptr; }
-
FixedBufferForTesting::FixedBufferForTesting(size_t size) {
size_ = internal::Align(size);
// Use calloc here to ensure all message memory is zero'd out.
diff --git a/chromium/mojo/public/cpp/bindings/lib/fixed_buffer.h b/chromium/mojo/public/cpp/bindings/lib/fixed_buffer.h
index d087c3b36a5..9a5704b4bfa 100644
--- a/chromium/mojo/public/cpp/bindings/lib/fixed_buffer.h
+++ b/chromium/mojo/public/cpp/bindings/lib/fixed_buffer.h
@@ -51,8 +51,6 @@ class FixedBuffer : public Buffer {
// memory is zero-filled.
void* Allocate(size_t num_bytes) override;
- PickleBuffer* AsPickleBuffer() override;
-
protected:
char* ptr_;
size_t cursor_;
diff --git a/chromium/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc b/chromium/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
index 574d627888a..9e32c5af239 100644
--- a/chromium/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
@@ -5,15 +5,15 @@
#include "mojo/public/cpp/bindings/lib/interface_endpoint_client.h"
#include <stdint.h>
+
#include <utility>
#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
+#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
-#include "base/thread_task_runner_handle.h"
#include "mojo/public/cpp/bindings/associated_group.h"
#include "mojo/public/cpp/bindings/lib/interface_endpoint_controller.h"
#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
@@ -38,18 +38,24 @@ void DCheckIfInvalid(const base::WeakPtr<InterfaceEndpointClient>& client,
class ResponderThunk : public MessageReceiverWithStatus {
public:
explicit ResponderThunk(
- const base::WeakPtr<InterfaceEndpointClient>& endpoint_client)
- : endpoint_client_(endpoint_client), accept_was_invoked_(false),
- task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
+ const base::WeakPtr<InterfaceEndpointClient>& endpoint_client,
+ scoped_refptr<base::SingleThreadTaskRunner> runner)
+ : endpoint_client_(endpoint_client),
+ accept_was_invoked_(false),
+ task_runner_(std::move(runner)) {}
~ResponderThunk() override {
if (!accept_was_invoked_) {
// The Mojo application handled a message that was expecting a response
// but did not send a response.
+ // We raise an error to signal the calling application that an error
+ // condition occurred. Without this the calling application would have no
+ // way of knowing it should stop waiting for a response.
if (task_runner_->RunsTasksOnCurrentThread()) {
+ // Please note that even if this code is run from a different task
+ // runner on the same thread as |task_runner_|, it is okay to directly
+ // call InterfaceEndpointClient::RaiseError(), because it will raise
+ // error from the correct task runner asynchronously.
if (endpoint_client_) {
- // We raise an error to signal the calling application that an error
- // condition occurred. Without this the calling application would have
- // no way of knowing it should stop waiting for a response.
endpoint_client_->RaiseError();
}
} else {
@@ -126,14 +132,16 @@ bool InterfaceEndpointClient::HandleIncomingMessageThunk::Accept(
InterfaceEndpointClient::InterfaceEndpointClient(
ScopedInterfaceEndpointHandle handle,
MessageReceiverWithResponderStatus* receiver,
- scoped_ptr<MessageFilter> payload_validator,
- bool expect_sync_requests)
+ std::unique_ptr<MessageFilter> payload_validator,
+ bool expect_sync_requests,
+ scoped_refptr<base::SingleThreadTaskRunner> runner)
: handle_(std::move(handle)),
incoming_receiver_(receiver),
payload_validator_(std::move(payload_validator)),
thunk_(this),
next_request_id_(1),
encountered_error_(false),
+ task_runner_(std::move(runner)),
weak_ptr_factory_(this) {
DCHECK(handle_.is_valid());
DCHECK(handle_.is_local());
@@ -142,7 +150,8 @@ InterfaceEndpointClient::InterfaceEndpointClient(
// directly is a little awkward.
payload_validator_->set_sink(&thunk_);
- controller_ = handle_.router()->AttachEndpointClient(handle_, this);
+ controller_ =
+ handle_.router()->AttachEndpointClient(handle_, this, task_runner_);
if (expect_sync_requests)
controller_->AllowWokenUpBySyncWatchOnSameThread();
}
@@ -210,19 +219,20 @@ bool InterfaceEndpointClient::AcceptWithResponder(Message* message,
message->set_request_id(request_id);
+ bool is_sync = message->has_flag(kMessageIsSync);
if (!controller_->SendMessage(message))
return false;
- if (!message->has_flag(kMessageIsSync)) {
+ if (!is_sync) {
// We assume ownership of |responder|.
- async_responders_[request_id] = make_scoped_ptr(responder);
+ async_responders_[request_id] = base::WrapUnique(responder);
return true;
}
bool response_received = false;
- scoped_ptr<MessageReceiver> sync_responder(responder);
+ std::unique_ptr<MessageReceiver> sync_responder(responder);
sync_responses_.insert(std::make_pair(
- request_id, make_scoped_ptr(new SyncResponseInfo(&response_received))));
+ request_id, base::WrapUnique(new SyncResponseInfo(&response_received))));
base::WeakPtr<InterfaceEndpointClient> weak_self =
weak_ptr_factory_.GetWeakPtr();
@@ -233,7 +243,7 @@ bool InterfaceEndpointClient::AcceptWithResponder(Message* message,
auto iter = sync_responses_.find(request_id);
DCHECK_EQ(&response_received, iter->second->response_received);
if (response_received) {
- scoped_ptr<Message> response = std::move(iter->second->response);
+ std::unique_ptr<Message> response = std::move(iter->second->response);
ignore_result(sync_responder->Accept(response.get()));
}
sync_responses_.erase(iter);
@@ -266,7 +276,7 @@ bool InterfaceEndpointClient::HandleValidatedMessage(Message* message) {
return false;
MessageReceiverWithStatus* responder =
- new ResponderThunk(weak_ptr_factory_.GetWeakPtr());
+ new ResponderThunk(weak_ptr_factory_.GetWeakPtr(), task_runner_);
bool ok = incoming_receiver_->AcceptWithResponder(message, responder);
if (!ok)
delete responder;
@@ -287,7 +297,7 @@ bool InterfaceEndpointClient::HandleValidatedMessage(Message* message) {
auto it = async_responders_.find(request_id);
if (it == async_responders_.end())
return false;
- scoped_ptr<MessageReceiver> responder = std::move(it->second);
+ std::unique_ptr<MessageReceiver> responder = std::move(it->second);
async_responders_.erase(it);
return responder->Accept(message);
} else {
diff --git a/chromium/mojo/public/cpp/bindings/lib/interface_endpoint_client.h b/chromium/mojo/public/cpp/bindings/lib/interface_endpoint_client.h
index 2560cfc42dc..3f820db3c30 100644
--- a/chromium/mojo/public/cpp/bindings/lib/interface_endpoint_client.h
+++ b/chromium/mojo/public/cpp/bindings/lib/interface_endpoint_client.h
@@ -8,16 +8,18 @@
#include <stdint.h>
#include <map>
+#include <memory>
#include "base/logging.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "mojo/public/cpp/bindings/callback.h"
-#include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h"
#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/cpp/bindings/message_filter.h"
+#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
namespace mojo {
@@ -37,8 +39,9 @@ class InterfaceEndpointClient : public MessageReceiverWithResponder {
// object.
InterfaceEndpointClient(ScopedInterfaceEndpointHandle handle,
MessageReceiverWithResponderStatus* receiver,
- scoped_ptr<MessageFilter> payload_validator,
- bool expect_sync_requests);
+ std::unique_ptr<MessageFilter> payload_validator,
+ bool expect_sync_requests,
+ scoped_refptr<base::SingleThreadTaskRunner> runner);
~InterfaceEndpointClient() override;
// Sets the error handler to receive notifications when an error is
@@ -86,14 +89,15 @@ class InterfaceEndpointClient : public MessageReceiverWithResponder {
private:
// Maps from the id of a response to the MessageReceiver that handles the
// response.
- using AsyncResponderMap = std::map<uint64_t, scoped_ptr<MessageReceiver>>;
+ using AsyncResponderMap =
+ std::map<uint64_t, std::unique_ptr<MessageReceiver>>;
struct SyncResponseInfo {
public:
explicit SyncResponseInfo(bool* in_response_received);
~SyncResponseInfo();
- scoped_ptr<Message> response;
+ std::unique_ptr<Message> response;
// Points to a stack-allocated variable.
bool* response_received;
@@ -102,7 +106,7 @@ class InterfaceEndpointClient : public MessageReceiverWithResponder {
DISALLOW_COPY_AND_ASSIGN(SyncResponseInfo);
};
- using SyncResponseMap = std::map<uint64_t, scoped_ptr<SyncResponseInfo>>;
+ using SyncResponseMap = std::map<uint64_t, std::unique_ptr<SyncResponseInfo>>;
// Used as the sink for |payload_validator_| and forwards messages to
// HandleValidatedMessage().
@@ -123,11 +127,11 @@ class InterfaceEndpointClient : public MessageReceiverWithResponder {
bool HandleValidatedMessage(Message* message);
ScopedInterfaceEndpointHandle handle_;
- scoped_ptr<AssociatedGroup> associated_group_;
+ std::unique_ptr<AssociatedGroup> associated_group_;
InterfaceEndpointController* controller_;
MessageReceiverWithResponderStatus* const incoming_receiver_;
- scoped_ptr<MessageFilter> payload_validator_;
+ std::unique_ptr<MessageFilter> payload_validator_;
HandleIncomingMessageThunk thunk_;
AsyncResponderMap async_responders_;
@@ -138,6 +142,8 @@ class InterfaceEndpointClient : public MessageReceiverWithResponder {
Closure error_handler_;
bool encountered_error_;
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
base::ThreadChecker thread_checker_;
base::WeakPtrFactory<InterfaceEndpointClient> weak_ptr_factory_;
diff --git a/chromium/mojo/public/cpp/bindings/lib/interface_ptr_state.h b/chromium/mojo/public/cpp/bindings/lib/interface_ptr_state.h
index 3f7d938e2dd..8cda57d2bdf 100644
--- a/chromium/mojo/public/cpp/bindings/lib/interface_ptr_state.h
+++ b/chromium/mojo/public/cpp/bindings/lib/interface_ptr_state.h
@@ -6,13 +6,16 @@
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_STATE_H_
#include <stdint.h>
+
#include <algorithm> // For |std::swap()|.
+#include <memory>
#include <utility>
#include "base/logging.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/single_thread_task_runner.h"
#include "mojo/public/cpp/bindings/associated_group.h"
#include "mojo/public/cpp/bindings/callback.h"
#include "mojo/public/cpp/bindings/interface_ptr_info.h"
@@ -23,7 +26,7 @@
#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
#include "mojo/public/cpp/bindings/lib/router.h"
-#include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h"
+#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
namespace mojo {
namespace internal {
@@ -89,10 +92,12 @@ class InterfacePtrState<Interface, false> {
swap(other->proxy_, proxy_);
swap(other->router_, router_);
handle_.swap(other->handle_);
+ runner_.swap(other->runner_);
swap(other->version_, version_);
}
- void Bind(InterfacePtrInfo<Interface> info) {
+ void Bind(InterfacePtrInfo<Interface> info,
+ scoped_refptr<base::SingleThreadTaskRunner> runner) {
DCHECK(!proxy_);
DCHECK(!router_);
DCHECK(!handle_.is_valid());
@@ -101,6 +106,7 @@ class InterfacePtrState<Interface, false> {
handle_ = info.PassHandle();
version_ = info.version();
+ runner_ = std::move(runner);
}
bool HasAssociatedInterfaces() const { return false; }
@@ -161,7 +167,8 @@ class InterfacePtrState<Interface, false> {
filters.Append<MessageHeaderValidator>();
filters.Append<typename Interface::ResponseValidator_>();
- router_ = new Router(std::move(handle_), std::move(filters), false);
+ router_ = new Router(std::move(handle_), std::move(filters), false,
+ std::move(runner_));
proxy_ = new Proxy(router_);
}
@@ -173,6 +180,7 @@ class InterfacePtrState<Interface, false> {
// message pipe handle is needed. |handle_| is valid between the Bind() call
// and the initialization of |proxy_| and |router_|.
ScopedMessagePipeHandle handle_;
+ scoped_refptr<base::SingleThreadTaskRunner> runner_;
uint32_t version_;
@@ -236,10 +244,12 @@ class InterfacePtrState<Interface, true> {
swap(other->endpoint_client_, endpoint_client_);
swap(other->proxy_, proxy_);
handle_.swap(other->handle_);
+ runner_.swap(other->runner_);
swap(other->version_, version_);
}
- void Bind(InterfacePtrInfo<Interface> info) {
+ void Bind(InterfacePtrInfo<Interface> info,
+ scoped_refptr<base::SingleThreadTaskRunner> runner) {
DCHECK(!router_);
DCHECK(!endpoint_client_);
DCHECK(!proxy_);
@@ -249,6 +259,7 @@ class InterfacePtrState<Interface, true> {
handle_ = info.PassHandle();
version_ = info.version();
+ runner_ = std::move(runner);
}
bool HasAssociatedInterfaces() const {
@@ -313,23 +324,25 @@ class InterfacePtrState<Interface, true> {
if (!handle_.is_valid())
return;
- router_ = new MultiplexRouter(true, std::move(handle_));
+ router_ = new MultiplexRouter(true, std::move(handle_), runner_);
endpoint_client_.reset(new InterfaceEndpointClient(
router_->CreateLocalEndpointHandle(kMasterInterfaceId), nullptr,
- make_scoped_ptr(new typename Interface::ResponseValidator_()), false));
+ base::WrapUnique(new typename Interface::ResponseValidator_()), false,
+ std::move(runner_)));
proxy_.reset(new Proxy(endpoint_client_.get()));
proxy_->serialization_context()->router = endpoint_client_->router();
}
scoped_refptr<MultiplexRouter> router_;
- scoped_ptr<InterfaceEndpointClient> endpoint_client_;
- scoped_ptr<Proxy> proxy_;
+ std::unique_ptr<InterfaceEndpointClient> endpoint_client_;
+ std::unique_ptr<Proxy> proxy_;
// |router_| (as well as other members above) is not initialized until
// read/write with the message pipe handle is needed. |handle_| is valid
// between the Bind() call and the initialization of |router_|.
ScopedMessagePipeHandle handle_;
+ scoped_refptr<base::SingleThreadTaskRunner> runner_;
uint32_t version_;
diff --git a/chromium/mojo/public/cpp/bindings/lib/macros.h b/chromium/mojo/public/cpp/bindings/lib/macros.h
deleted file mode 100644
index 62f4292c1ee..00000000000
--- a/chromium/mojo/public/cpp/bindings/lib/macros.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2014 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_BINDINGS_LIB_MACROS_H_
-#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MACROS_H_
-
-// This file defines macros that are only used by generated bindings.
-
-// The C++ standard requires that static const members have an out-of-class
-// definition (in a single compilation unit), but MSVC chokes on this (when
-// language extensions, which are required, are enabled). (You're only likely to
-// notice the need for a definition if you take the address of the member or,
-// more commonly, pass it to a function that takes it as a reference argument --
-// probably an STL function.) This macro makes MSVC do the right thing. See
-// http://msdn.microsoft.com/en-us/library/34h23df8(v=vs.100).aspx for more
-// information. This workaround does not appear to be necessary after VS2015.
-// Use like:
-//
-// In the .h file:
-// struct Foo {
-// static const int kBar = 5;
-// };
-//
-// In the .cc file:
-// MOJO_STATIC_CONST_MEMBER_DEFINITION const int Foo::kBar;
-#if defined(_MSC_VER) && _MSC_VER < 1900
-#define MOJO_STATIC_CONST_MEMBER_DEFINITION __declspec(selectany)
-#else
-#define MOJO_STATIC_CONST_MEMBER_DEFINITION
-#endif
-
-#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MACROS_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/map_data_internal.h b/chromium/mojo/public/cpp/bindings/lib/map_data_internal.h
index 8315dbc8e10..a5363617817 100644
--- a/chromium/mojo/public/cpp/bindings/lib/map_data_internal.h
+++ b/chromium/mojo/public/cpp/bindings/lib/map_data_internal.h
@@ -113,17 +113,17 @@ class Map_Data {
StructHeader header_;
- ArrayPointer<Key> keys;
- ArrayPointer<Value> values;
+ Pointer<Array_Data<Key>> keys;
+ Pointer<Array_Data<Value>> values;
- void EncodePointersAndHandles(std::vector<mojo::Handle>* handles) {
- Encode(&keys, handles);
- Encode(&values, handles);
+ void EncodePointers() {
+ Encode(&keys);
+ Encode(&values);
}
- void DecodePointersAndHandles(std::vector<mojo::Handle>* handles) {
- Decode(&keys, handles);
- Decode(&values, handles);
+ void DecodePointers() {
+ Decode(&keys);
+ Decode(&values);
}
private:
diff --git a/chromium/mojo/public/cpp/bindings/lib/map_serialization.h b/chromium/mojo/public/cpp/bindings/lib/map_serialization.h
index bca23796bba..56ef68d3162 100644
--- a/chromium/mojo/public/cpp/bindings/lib/map_serialization.h
+++ b/chromium/mojo/public/cpp/bindings/lib/map_serialization.h
@@ -5,191 +5,115 @@
#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_
-#include <stddef.h>
-#include <utility>
-
-#include "mojo/public/cpp/bindings/lib/array_internal.h"
+#include "mojo/public/cpp/bindings/array.h"
#include "mojo/public/cpp/bindings/lib/map_data_internal.h"
-#include "mojo/public/cpp/bindings/lib/map_internal.h"
#include "mojo/public/cpp/bindings/lib/serialization_forward.h"
#include "mojo/public/cpp/bindings/map.h"
namespace mojo {
namespace internal {
-template <typename MapType,
- typename DataType,
- bool value_is_move_only_type = IsMoveOnlyType<MapType>::value,
- bool is_union =
- IsUnionDataType<typename RemovePointer<DataType>::type>::value>
-struct MapSerializer;
-
-template <typename MapType, typename DataType>
-struct MapSerializer<MapType, DataType, false, false> {
- static size_t GetBaseArraySize(size_t count) {
- return Align(count * sizeof(DataType));
- }
- static size_t GetItemSize(const MapType& item,
- SerializationContext* context) {
- return 0;
- }
-};
-
-template <>
-struct MapSerializer<bool, bool, false, false> {
- static size_t GetBaseArraySize(size_t count) {
- return Align((count + 7) / 8);
- }
- static size_t GetItemSize(bool item, SerializationContext* context) {
- return 0;
- }
-};
-
-template <typename H>
-struct MapSerializer<ScopedHandleBase<H>, H, true, false> {
- static size_t GetBaseArraySize(size_t count) {
- return Align(count * sizeof(H));
- }
- static size_t GetItemSize(const ScopedHandleBase<H>& item,
- SerializationContext* context) {
- return 0;
- }
-};
-
-// This template must only apply to pointer mojo entity (structs and arrays).
-// This is done by ensuring that WrapperTraits<S>::DataType is a pointer.
-template <typename S>
-struct MapSerializer<
- S,
- typename EnableIf<IsPointer<typename WrapperTraits<S>::DataType>::value,
- typename WrapperTraits<S>::DataType>::type,
- true,
- false> {
- typedef
- typename RemovePointer<typename WrapperTraits<S>::DataType>::type S_Data;
- static size_t GetBaseArraySize(size_t count) {
- return count * sizeof(StructPointer<S_Data>);
- }
- static size_t GetItemSize(const S& item, SerializationContext* context) {
- return GetSerializedSize_(item, context);
- }
-};
+template <typename Key, typename Value>
+struct MapContext {
+ explicit MapContext(bool in_is_null) : is_null(in_is_null) {}
-template <typename U, typename U_Data>
-struct MapSerializer<U, U_Data*, true, true> {
- static size_t GetBaseArraySize(size_t count) {
- return count * sizeof(U_Data);
- }
- static size_t GetItemSize(const U& item, SerializationContext* context) {
- return GetSerializedSize_(item, true, context);
- }
+ bool is_null;
+ Array<Key> keys;
+ Array<Value> values;
};
-template <>
-struct MapSerializer<String, String_Data*, false, false> {
- static size_t GetBaseArraySize(size_t count) {
- return count * sizeof(StringPointer);
+template <typename Key, typename Value, typename MaybeConstUserType>
+struct Serializer<Map<Key, Value>, MaybeConstUserType> {
+ using UserType = typename std::remove_const<MaybeConstUserType>::type;
+ using UserKey = typename UserType::Key;
+ using UserValue = typename UserType::Value;
+ using Data = typename Map<Key, Value>::Data_;
+
+ static_assert(std::is_same<MaybeConstUserType, UserType>::value,
+ "Only support serialization of non-const Maps.");
+ static_assert(IsSpecializationOf<Map, UserType>::value,
+ "Custom mapping of mojom map is not supported yet.");
+
+ static size_t PrepareToSerialize(UserType& input,
+ SerializationContext* context) {
+ auto map_context = new MapContext<UserKey, UserValue>(input.is_null());
+ if (!context->custom_contexts)
+ context->custom_contexts.reset(new std::queue<void*>());
+ context->custom_contexts->push(map_context);
+
+ if (!input)
+ return 0;
+
+ input.DecomposeMapTo(&map_context->keys, &map_context->values);
+
+ size_t struct_overhead = sizeof(Data);
+ size_t keys_size =
+ internal::PrepareToSerialize<Array<Key>>(map_context->keys, context);
+ size_t values_size = internal::PrepareToSerialize<Array<Value>>(
+ map_context->values, context);
+
+ return struct_overhead + keys_size + values_size;
}
- static size_t GetItemSize(const String& item, SerializationContext* context) {
- return GetSerializedSize_(item, context);
- }
-};
-
-} // namespace internal
-// TODO(erg): This can't go away yet. We still need to calculate out the size
-// of a struct header, and two arrays.
-template <typename MapKey, typename MapValue>
-inline size_t GetSerializedSize_(const Map<MapKey, MapValue>& input,
- internal::SerializationContext* context) {
- if (!input)
- return 0;
- typedef typename internal::WrapperTraits<MapKey>::DataType DataKey;
- typedef typename internal::WrapperTraits<MapValue>::DataType DataValue;
-
- size_t count = input.size();
- size_t struct_overhead = sizeof(mojo::internal::Map_Data<DataKey, DataValue>);
- size_t key_base_size =
- sizeof(internal::ArrayHeader) +
- internal::MapSerializer<MapKey, DataKey>::GetBaseArraySize(count);
- size_t value_base_size =
- sizeof(internal::ArrayHeader) +
- internal::MapSerializer<MapValue, DataValue>::GetBaseArraySize(count);
-
- size_t key_data_size = 0;
- size_t value_data_size = 0;
- for (auto it = input.begin(); it != input.end(); ++it) {
- key_data_size += internal::MapSerializer<MapKey, DataKey>::GetItemSize(
- it->first, context);
- value_data_size +=
- internal::MapSerializer<MapValue, DataValue>::GetItemSize(it->second,
- context);
- }
+ // We don't need an ArrayValidateParams instance for key validation since
+ // we can deduce it from the Key type. (which can only be primitive types or
+ // non-nullable strings.)
+ static void Serialize(UserType& input,
+ Buffer* buf,
+ Data** output,
+ const ArrayValidateParams* value_validate_params,
+ SerializationContext* context) {
+ std::unique_ptr<MapContext<UserKey, UserValue>> map_context(
+ static_cast<MapContext<UserKey, UserValue>*>(
+ context->custom_contexts->front()));
+ context->custom_contexts->pop();
+
+ if (map_context->is_null) {
+ *output = nullptr;
+ return;
+ }
- return struct_overhead + key_base_size + key_data_size + value_base_size +
- value_data_size;
-}
-
-// We don't need an ArrayValidateParams instance for key validation since
-// we can deduce it from the Key type. (which can only be primitive types or
-// non-nullable strings.)
-template <typename MapKey,
- typename MapValue,
- typename DataKey,
- typename DataValue>
-inline void SerializeMap_(
- Map<MapKey, MapValue> input,
- internal::Buffer* buf,
- internal::Map_Data<DataKey, DataValue>** output,
- const internal::ArrayValidateParams* value_validate_params,
- internal::SerializationContext* context) {
- if (input) {
- internal::Map_Data<DataKey, DataValue>* result =
- internal::Map_Data<DataKey, DataValue>::New(buf);
+ auto result = Data::New(buf);
if (result) {
- Array<MapKey> keys;
- Array<MapValue> values;
- input.DecomposeMapTo(&keys, &values);
- const internal::ArrayValidateParams* key_validate_params =
- internal::MapKeyValidateParamsFactory<DataKey>::Get();
- SerializeArray_(std::move(keys), buf, &result->keys.ptr,
- key_validate_params, context);
- SerializeArray_(std::move(values), buf, &result->values.ptr,
- value_validate_params, context);
+ const ArrayValidateParams* key_validate_params =
+ MapKeyValidateParamsFactory<
+ typename GetDataTypeAsArrayElement<Key>::Data>::Get();
+ internal::Serialize<Array<Key>>(map_context->keys, buf, &result->keys.ptr,
+ key_validate_params, context);
+ internal::Serialize<Array<Value>>(map_context->values, buf,
+ &result->values.ptr,
+ value_validate_params, context);
}
*output = result;
- } else {
- *output = nullptr;
}
-}
-
-template <typename MapKey,
- typename MapValue,
- typename DataKey,
- typename DataValue>
-inline bool Deserialize_(internal::Map_Data<DataKey, DataValue>* input,
- Map<MapKey, MapValue>* output,
- internal::SerializationContext* context) {
- bool success = true;
- if (input) {
- Array<MapKey> keys;
- Array<MapValue> values;
-
- // Note that we rely on complete deserialization taking place in order to
- // transfer ownership of all encoded handles. Therefore we don't
- // short-circuit on failure here.
- if (!Deserialize_(input->keys.ptr, &keys, context))
- success = false;
- if (!Deserialize_(input->values.ptr, &values, context))
- success = false;
-
- *output = Map<MapKey, MapValue>(std::move(keys), std::move(values));
- } else {
- *output = nullptr;
+
+ static bool Deserialize(Data* input,
+ UserType* output,
+ SerializationContext* context) {
+ bool success = true;
+ if (input) {
+ Array<UserKey> keys;
+ Array<UserValue> values;
+
+ // Note that we rely on complete deserialization taking place in order to
+ // transfer ownership of all encoded handles. Therefore we don't
+ // short-circuit on failure here.
+ if (!internal::Deserialize<Array<Key>>(input->keys.ptr, &keys, context))
+ success = false;
+ if (!internal::Deserialize<Array<Value>>(input->values.ptr, &values,
+ context)) {
+ success = false;
+ }
+
+ *output = UserType(std::move(keys), std::move(values));
+ } else {
+ *output = nullptr;
+ }
+ return success;
}
- return success;
-}
+};
+} // namespace internal
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/message.cc b/chromium/mojo/public/cpp/bindings/lib/message.cc
index e1e8f190df9..4274cc86cb1 100644
--- a/chromium/mojo/public/cpp/bindings/lib/message.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/message.cc
@@ -9,6 +9,7 @@
#include <stdlib.h>
#include <algorithm>
+#include <utility>
#include "base/logging.h"
@@ -23,7 +24,15 @@ Message::~Message() {
void Message::Initialize(size_t capacity, bool zero_initialized) {
DCHECK(!buffer_);
- buffer_.reset(new internal::PickleBuffer(capacity, zero_initialized));
+ buffer_.reset(new internal::MessageBuffer(capacity, zero_initialized));
+}
+
+void Message::InitializeFromMojoMessage(ScopedMessageHandle message,
+ uint32_t num_bytes,
+ std::vector<Handle>* handles) {
+ DCHECK(!buffer_);
+ buffer_.reset(new internal::MessageBuffer(std::move(message), num_bytes));
+ handles_.swap(*handles);
}
void Message::MoveTo(Message* destination) {
@@ -38,6 +47,37 @@ void Message::MoveTo(Message* destination) {
buffer_.reset();
}
+ScopedMessageHandle Message::TakeMojoMessage() {
+ if (handles_.empty()) // Fast path for the common case: No handles.
+ return buffer_->TakeMessage();
+
+ // Allocate a new message with space for the handles, then copy the buffer
+ // contents into it.
+ //
+ // TODO(rockot): We could avoid this copy by extending GetSerializedSize()
+ // behavior to collect handles. It's unoptimized for now because it's much
+ // more common to have messages with no handles.
+ ScopedMessageHandle new_message;
+ MojoResult rv = AllocMessage(
+ data_num_bytes(),
+ handles_.empty() ? nullptr
+ : reinterpret_cast<const MojoHandle*>(handles_.data()),
+ handles_.size(),
+ MOJO_ALLOC_MESSAGE_FLAG_NONE,
+ &new_message);
+ CHECK_EQ(rv, MOJO_RESULT_OK);
+ handles_.clear();
+
+ void* new_buffer = nullptr;
+ rv = GetMessageBuffer(new_message.get(), &new_buffer);
+ CHECK_EQ(rv, MOJO_RESULT_OK);
+
+ memcpy(new_buffer, data(), data_num_bytes());
+ buffer_.reset();
+
+ return new_message;
+}
+
void Message::CloseHandles() {
for (std::vector<Handle>::iterator it = handles_.begin();
it != handles_.end(); ++it) {
@@ -49,28 +89,32 @@ void Message::CloseHandles() {
MojoResult ReadMessage(MessagePipeHandle handle, Message* message) {
MojoResult rv;
+ std::vector<Handle> handles;
+ ScopedMessageHandle mojo_message;
uint32_t num_bytes = 0, num_handles = 0;
- rv = ReadMessageRaw(handle,
- nullptr,
+ rv = ReadMessageNew(handle,
+ &mojo_message,
&num_bytes,
nullptr,
&num_handles,
MOJO_READ_MESSAGE_FLAG_NONE);
- if (rv != MOJO_RESULT_RESOURCE_EXHAUSTED)
- return rv;
-
- message->Initialize(num_bytes, false /* zero_initialized */);
+ if (rv == MOJO_RESULT_RESOURCE_EXHAUSTED) {
+ DCHECK_GT(num_handles, 0u);
+ handles.resize(num_handles);
+ rv = ReadMessageNew(handle,
+ &mojo_message,
+ &num_bytes,
+ reinterpret_cast<MojoHandle*>(handles.data()),
+ &num_handles,
+ MOJO_READ_MESSAGE_FLAG_NONE);
+ }
- void* mutable_data = message->buffer()->Allocate(num_bytes);
- message->mutable_handles()->resize(num_handles);
+ if (rv != MOJO_RESULT_OK)
+ return rv;
- rv = ReadMessageRaw(
- handle, mutable_data, &num_bytes,
- message->mutable_handles()->empty()
- ? nullptr
- : reinterpret_cast<MojoHandle*>(message->mutable_handles()->data()),
- &num_handles, MOJO_READ_MESSAGE_FLAG_NONE);
- return rv;
+ message->InitializeFromMojoMessage(
+ std::move(mojo_message), num_bytes, &handles);
+ return MOJO_RESULT_OK;
}
} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/message_buffer.cc b/chromium/mojo/public/cpp/bindings/lib/message_buffer.cc
new file mode 100644
index 00000000000..7a153647f8f
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/message_buffer.cc
@@ -0,0 +1,65 @@
+// Copyright 2016 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 "mojo/public/cpp/bindings/lib/message_buffer.h"
+
+#include <limits>
+
+#include "mojo/public/cpp/bindings/lib/serialization_util.h"
+
+namespace mojo {
+namespace internal {
+
+MessageBuffer::MessageBuffer(size_t capacity, bool zero_initialized) {
+ DCHECK_LE(capacity, std::numeric_limits<uint32_t>::max());
+ data_num_bytes_ = static_cast<uint32_t>(capacity);
+
+ MojoResult rv = AllocMessage(capacity, nullptr, 0,
+ MOJO_ALLOC_MESSAGE_FLAG_NONE, &message_);
+ CHECK_EQ(rv, MOJO_RESULT_OK);
+
+ if (capacity == 0) {
+ buffer_ = nullptr;
+ } else {
+ rv = GetMessageBuffer(message_.get(), &buffer_);
+ CHECK_EQ(rv, MOJO_RESULT_OK);
+
+ if (zero_initialized)
+ memset(buffer_, 0, capacity);
+ }
+}
+
+MessageBuffer::MessageBuffer(ScopedMessageHandle message, uint32_t num_bytes) {
+ message_ = std::move(message);
+ data_num_bytes_ = num_bytes;
+
+ if (num_bytes == 0) {
+ buffer_ = nullptr;
+ } else {
+ MojoResult rv = GetMessageBuffer(message_.get(), &buffer_);
+ CHECK_EQ(rv, MOJO_RESULT_OK);
+ }
+}
+
+MessageBuffer::~MessageBuffer() {}
+
+void* MessageBuffer::Allocate(size_t delta) {
+ delta = internal::Align(delta);
+
+ DCHECK_LE(delta, static_cast<size_t>(data_num_bytes_));
+ DCHECK_GT(bytes_claimed_ + static_cast<uint32_t>(delta), bytes_claimed_);
+
+ uint32_t new_bytes_claimed = bytes_claimed_ + static_cast<uint32_t>(delta);
+ if (new_bytes_claimed > data_num_bytes_) {
+ NOTREACHED();
+ return nullptr;
+ }
+
+ char* start = static_cast<char*>(buffer_) + bytes_claimed_;
+ bytes_claimed_ = new_bytes_claimed;
+ return static_cast<void*>(start);
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/message_buffer.h b/chromium/mojo/public/cpp/bindings/lib/message_buffer.h
new file mode 100644
index 00000000000..47ffea01514
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/message_buffer.h
@@ -0,0 +1,52 @@
+// Copyright 2016 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_BINDINGS_MESSAGE_LIB_MESSAGE_BUFFER_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_LIB_MESSAGE_BUFFER_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <utility>
+
+#include "base/macros.h"
+#include "mojo/public/cpp/bindings/lib/buffer.h"
+#include "mojo/public/cpp/system/message.h"
+
+namespace mojo {
+namespace internal {
+
+// A fixed-size Buffer implementation using a Mojo message object for storage.
+class MessageBuffer : public Buffer {
+ public:
+ // Initializes this buffer to carry a fixed byte capacity and no handles.
+ MessageBuffer(size_t capacity, bool zero_initialized);
+
+ // Initializes this buffer from an existing Mojo MessageHandle.
+ MessageBuffer(ScopedMessageHandle message, uint32_t num_bytes);
+
+ ~MessageBuffer() override;
+
+ void* data() const { return buffer_; }
+ uint32_t data_num_bytes() const { return data_num_bytes_; }
+
+ // Buffer:
+ void* Allocate(size_t delta) override;
+
+ ScopedMessageHandle TakeMessage() { return std::move(message_); }
+
+ private:
+ uint32_t data_num_bytes_ = 0;
+ ScopedMessageHandle message_;
+ void* buffer_;
+
+ uint32_t bytes_claimed_ = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(MessageBuffer);
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_LIB_MESSAGE_BUFFER_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/message_builder.cc b/chromium/mojo/public/cpp/bindings/lib/message_builder.cc
index 428fa91fda1..4ffa1808cc9 100644
--- a/chromium/mojo/public/cpp/bindings/lib/message_builder.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/message_builder.cc
@@ -7,7 +7,7 @@
#include <stddef.h>
#include <stdint.h>
-#include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
+#include "mojo/public/cpp/bindings/lib/serialization_util.h"
#include "mojo/public/cpp/bindings/message.h"
namespace mojo {
diff --git a/chromium/mojo/public/cpp/bindings/lib/multiplex_router.cc b/chromium/mojo/public/cpp/bindings/lib/multiplex_router.cc
index 75d14467e5a..d081b0155ba 100644
--- a/chromium/mojo/public/cpp/bindings/lib/multiplex_router.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/multiplex_router.cc
@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
@@ -64,12 +65,14 @@ class MultiplexRouter::InterfaceEndpoint
InterfaceEndpointClient* client() const { return client_; }
- void AttachClient(InterfaceEndpointClient* client) {
+ void AttachClient(InterfaceEndpointClient* client,
+ scoped_refptr<base::SingleThreadTaskRunner> runner) {
router_->lock_.AssertAcquired();
DCHECK(!client_);
DCHECK(!closed_);
+ DCHECK(runner->BelongsToCurrentThread());
- task_runner_ = base::MessageLoop::current()->task_runner();
+ task_runner_ = std::move(runner);
client_ = client;
}
@@ -241,7 +244,7 @@ class MultiplexRouter::InterfaceEndpoint
// used exclusively on the client's thread. They may be accessed outside of
// the router's lock.
- scoped_ptr<SyncHandleWatcher> sync_watcher_;
+ std::unique_ptr<SyncHandleWatcher> sync_watcher_;
DISALLOW_COPY_AND_ASSIGN(InterfaceEndpoint);
};
@@ -249,16 +252,17 @@ class MultiplexRouter::InterfaceEndpoint
struct MultiplexRouter::Task {
public:
// Doesn't take ownership of |message| but takes its contents.
- static scoped_ptr<Task> CreateMessageTask(Message* message) {
+ static std::unique_ptr<Task> CreateMessageTask(Message* message) {
Task* task = new Task(MESSAGE);
task->message.reset(new Message);
message->MoveTo(task->message.get());
- return make_scoped_ptr(task);
+ return base::WrapUnique(task);
}
- static scoped_ptr<Task> CreateNotifyErrorTask(InterfaceEndpoint* endpoint) {
+ static std::unique_ptr<Task> CreateNotifyErrorTask(
+ InterfaceEndpoint* endpoint) {
Task* task = new Task(NOTIFY_ERROR);
task->endpoint_to_notify = endpoint;
- return make_scoped_ptr(task);
+ return base::WrapUnique(task);
}
~Task() {}
@@ -266,7 +270,7 @@ struct MultiplexRouter::Task {
bool IsMessageTask() const { return type == MESSAGE; }
bool IsNotifyErrorTask() const { return type == NOTIFY_ERROR; }
- scoped_ptr<Message> message;
+ std::unique_ptr<Message> message;
scoped_refptr<InterfaceEndpoint> endpoint_to_notify;
enum Type { MESSAGE, NOTIFY_ERROR };
@@ -276,13 +280,17 @@ struct MultiplexRouter::Task {
explicit Task(Type in_type) : type(in_type) {}
};
-MultiplexRouter::MultiplexRouter(bool set_interface_id_namesapce_bit,
- ScopedMessagePipeHandle message_pipe)
+MultiplexRouter::MultiplexRouter(
+ bool set_interface_id_namesapce_bit,
+ ScopedMessagePipeHandle message_pipe,
+ scoped_refptr<base::SingleThreadTaskRunner> runner)
: RefCountedDeleteOnMessageLoop(
base::MessageLoop::current()->task_runner()),
set_interface_id_namespace_bit_(set_interface_id_namesapce_bit),
header_validator_(this),
- connector_(std::move(message_pipe), Connector::MULTI_THREADED_SEND),
+ connector_(std::move(message_pipe),
+ Connector::MULTI_THREADED_SEND,
+ std::move(runner)),
control_message_handler_(this),
control_message_proxy_(&connector_),
next_interface_id_value_(1),
@@ -384,12 +392,13 @@ void MultiplexRouter::CloseEndpointHandle(InterfaceId id, bool is_local) {
if (!IsMasterInterfaceId(id))
control_message_proxy_.NotifyPeerEndpointClosed(id);
- ProcessTasks(NO_DIRECT_CLIENT_CALLS);
+ ProcessTasks(NO_DIRECT_CLIENT_CALLS, nullptr);
}
InterfaceEndpointController* MultiplexRouter::AttachEndpointClient(
const ScopedInterfaceEndpointHandle& handle,
- InterfaceEndpointClient* client) {
+ InterfaceEndpointClient* client,
+ scoped_refptr<base::SingleThreadTaskRunner> runner) {
const InterfaceId id = handle.id();
DCHECK(IsValidInterfaceId(id));
@@ -399,11 +408,11 @@ InterfaceEndpointController* MultiplexRouter::AttachEndpointClient(
DCHECK(ContainsKey(endpoints_, id));
InterfaceEndpoint* endpoint = endpoints_[id].get();
- endpoint->AttachClient(client);
+ endpoint->AttachClient(client, std::move(runner));
if (endpoint->peer_closed())
tasks_.push_back(Task::CreateNotifyErrorTask(endpoint));
- ProcessTasks(NO_DIRECT_CLIENT_CALLS);
+ ProcessTasks(NO_DIRECT_CLIENT_CALLS, nullptr);
return endpoint;
}
@@ -430,8 +439,8 @@ void MultiplexRouter::RaiseError() {
}
}
-scoped_ptr<AssociatedGroup> MultiplexRouter::CreateAssociatedGroup() {
- scoped_ptr<AssociatedGroup> group(new AssociatedGroup);
+std::unique_ptr<AssociatedGroup> MultiplexRouter::CreateAssociatedGroup() {
+ std::unique_ptr<AssociatedGroup> group(new AssociatedGroup);
group->router_ = this;
return group;
}
@@ -482,7 +491,8 @@ bool MultiplexRouter::Accept(Message* message) {
: ALLOW_DIRECT_CLIENT_CALLS;
bool processed =
- tasks_.empty() && ProcessIncomingMessage(message, client_call_behavior);
+ tasks_.empty() && ProcessIncomingMessage(message, client_call_behavior,
+ connector_.task_runner());
if (!processed) {
// Either the task queue is not empty or we cannot process the message
@@ -501,7 +511,7 @@ bool MultiplexRouter::Accept(Message* message) {
// Processing the message may result in new tasks (for error notification)
// being added to the queue. In this case, we have to attempt to process the
// tasks.
- ProcessTasks(client_call_behavior);
+ ProcessTasks(client_call_behavior, connector_.task_runner());
}
// Always return true. If we see errors during message processing, we will
@@ -564,17 +574,20 @@ void MultiplexRouter::OnPipeConnectionError() {
ProcessTasks(connector_.during_sync_handle_watcher_callback()
? ALLOW_DIRECT_CLIENT_CALLS_FOR_SYNC_MESSAGES
- : ALLOW_DIRECT_CLIENT_CALLS);
+ : ALLOW_DIRECT_CLIENT_CALLS,
+ connector_.task_runner());
}
-void MultiplexRouter::ProcessTasks(ClientCallBehavior client_call_behavior) {
+void MultiplexRouter::ProcessTasks(
+ ClientCallBehavior client_call_behavior,
+ base::SingleThreadTaskRunner* current_task_runner) {
lock_.AssertAcquired();
if (posted_to_process_tasks_)
return;
while (!tasks_.empty()) {
- scoped_ptr<Task> task(std::move(tasks_.front()));
+ std::unique_ptr<Task> task(std::move(tasks_.front()));
tasks_.pop_front();
InterfaceId id = kInvalidInterfaceId;
@@ -589,8 +602,10 @@ void MultiplexRouter::ProcessTasks(ClientCallBehavior client_call_behavior) {
bool processed =
task->IsNotifyErrorTask()
- ? ProcessNotifyErrorTask(task.get(), client_call_behavior)
- : ProcessIncomingMessage(task->message.get(), client_call_behavior);
+ ? ProcessNotifyErrorTask(task.get(), client_call_behavior,
+ current_task_runner)
+ : ProcessIncomingMessage(task->message.get(), client_call_behavior,
+ current_task_runner);
if (!processed) {
tasks_.push_front(std::move(task));
@@ -620,11 +635,11 @@ bool MultiplexRouter::ProcessFirstSyncMessageForEndpoint(InterfaceId id) {
iter->second.pop_front();
DCHECK(task->IsMessageTask());
- scoped_ptr<Message> message(std::move(task->message));
+ std::unique_ptr<Message> message(std::move(task->message));
// Note: after this call, |task| and |iter| may be invalidated.
bool processed = ProcessIncomingMessage(
- message.get(), ALLOW_DIRECT_CLIENT_CALLS_FOR_SYNC_MESSAGES);
+ message.get(), ALLOW_DIRECT_CLIENT_CALLS_FOR_SYNC_MESSAGES, nullptr);
DCHECK(processed);
iter = sync_message_tasks_.find(id);
@@ -633,18 +648,22 @@ bool MultiplexRouter::ProcessFirstSyncMessageForEndpoint(InterfaceId id) {
bool MultiplexRouter::ProcessNotifyErrorTask(
Task* task,
- ClientCallBehavior client_call_behavior) {
+ ClientCallBehavior client_call_behavior,
+ base::SingleThreadTaskRunner* current_task_runner) {
+ DCHECK(!current_task_runner || current_task_runner->BelongsToCurrentThread());
lock_.AssertAcquired();
InterfaceEndpoint* endpoint = task->endpoint_to_notify.get();
if (!endpoint->client())
return true;
- if (!endpoint->task_runner()->BelongsToCurrentThread() ||
- client_call_behavior != ALLOW_DIRECT_CLIENT_CALLS) {
+ if (client_call_behavior != ALLOW_DIRECT_CLIENT_CALLS ||
+ endpoint->task_runner() != current_task_runner) {
MaybePostToProcessTasks(endpoint->task_runner());
return false;
}
+ DCHECK(endpoint->task_runner()->BelongsToCurrentThread());
+
InterfaceEndpointClient* client = endpoint->client();
{
// We must unlock before calling into |client| because it may call this
@@ -660,7 +679,9 @@ bool MultiplexRouter::ProcessNotifyErrorTask(
bool MultiplexRouter::ProcessIncomingMessage(
Message* message,
- ClientCallBehavior client_call_behavior) {
+ ClientCallBehavior client_call_behavior,
+ base::SingleThreadTaskRunner* current_task_runner) {
+ DCHECK(!current_task_runner || current_task_runner->BelongsToCurrentThread());
lock_.AssertAcquired();
if (!message) {
@@ -703,16 +724,22 @@ bool MultiplexRouter::ProcessIncomingMessage(
return false;
}
- bool can_direct_call =
- (client_call_behavior == ALLOW_DIRECT_CLIENT_CALLS) ||
- (client_call_behavior == ALLOW_DIRECT_CLIENT_CALLS_FOR_SYNC_MESSAGES &&
- message->has_flag(kMessageIsSync));
+ bool can_direct_call;
+ if (message->has_flag(kMessageIsSync)) {
+ can_direct_call = client_call_behavior != NO_DIRECT_CLIENT_CALLS &&
+ endpoint->task_runner()->BelongsToCurrentThread();
+ } else {
+ can_direct_call = client_call_behavior == ALLOW_DIRECT_CLIENT_CALLS &&
+ endpoint->task_runner() == current_task_runner;
+ }
- if (!endpoint->task_runner()->BelongsToCurrentThread() || !can_direct_call) {
+ if (!can_direct_call) {
MaybePostToProcessTasks(endpoint->task_runner());
return false;
}
+ DCHECK(endpoint->task_runner()->BelongsToCurrentThread());
+
InterfaceEndpointClient* client = endpoint->client();
bool result = false;
{
@@ -738,6 +765,7 @@ void MultiplexRouter::MaybePostToProcessTasks(
return;
posted_to_process_tasks_ = true;
+ posted_to_task_runner_ = task_runner;
task_runner->PostTask(
FROM_HERE, base::Bind(&MultiplexRouter::LockAndCallProcessTasks, this));
}
@@ -747,7 +775,9 @@ void MultiplexRouter::LockAndCallProcessTasks() {
// always called using base::Bind(), which holds a ref.
base::AutoLock locker(lock_);
posted_to_process_tasks_ = false;
- ProcessTasks(ALLOW_DIRECT_CLIENT_CALLS);
+ scoped_refptr<base::SingleThreadTaskRunner> runner(
+ std::move(posted_to_task_runner_));
+ ProcessTasks(ALLOW_DIRECT_CLIENT_CALLS, runner.get());
}
void MultiplexRouter::UpdateEndpointStateMayRemove(
diff --git a/chromium/mojo/public/cpp/bindings/lib/multiplex_router.h b/chromium/mojo/public/cpp/bindings/lib/multiplex_router.h
index e9cd35b9c9b..c348c7d8954 100644
--- a/chromium/mojo/public/cpp/bindings/lib/multiplex_router.h
+++ b/chromium/mojo/public/cpp/bindings/lib/multiplex_router.h
@@ -9,13 +9,14 @@
#include <deque>
#include <map>
+#include <memory>
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/ref_counted_delete_on_message_loop.h"
-#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_checker.h"
#include "mojo/public/cpp/bindings/callback.h"
@@ -25,7 +26,7 @@
#include "mojo/public/cpp/bindings/lib/pipe_control_message_handler.h"
#include "mojo/public/cpp/bindings/lib/pipe_control_message_handler_delegate.h"
#include "mojo/public/cpp/bindings/lib/pipe_control_message_proxy.h"
-#include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h"
+#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
namespace base {
class SingleThreadTaskRunner;
@@ -57,7 +58,8 @@ class MultiplexRouter
// If |set_interface_id_namespace_bit| is true, the interface IDs generated by
// this router will have the highest bit set.
MultiplexRouter(bool set_interface_id_namespace_bit,
- ScopedMessagePipeHandle message_pipe);
+ ScopedMessagePipeHandle message_pipe,
+ scoped_refptr<base::SingleThreadTaskRunner> runner);
// ---------------------------------------------------------------------------
// The following public methods are safe to call from any threads.
@@ -84,7 +86,8 @@ class MultiplexRouter
// DetachEndpointClient().
InterfaceEndpointController* AttachEndpointClient(
const ScopedInterfaceEndpointHandle& handle,
- InterfaceEndpointClient* endpoint_client);
+ InterfaceEndpointClient* endpoint_client,
+ scoped_refptr<base::SingleThreadTaskRunner> runner);
// Detaches the client attached to the specified endpoint. It must be called
// on the same thread as the corresponding AttachEndpointClient() call.
@@ -94,7 +97,7 @@ class MultiplexRouter
// and notifies all interfaces running on this pipe.
void RaiseError();
- scoped_ptr<AssociatedGroup> CreateAssociatedGroup();
+ std::unique_ptr<AssociatedGroup> CreateAssociatedGroup();
static MultiplexRouter* GetRouter(AssociatedGroup* associated_group);
@@ -181,11 +184,16 @@ class MultiplexRouter
};
// Processes enqueued tasks (incoming messages and error notifications).
+ // |current_task_runner| is only used when |client_call_behavior| is
+ // ALLOW_DIRECT_CLIENT_CALLS to determine whether we are on the right task
+ // runner to make client calls for async messages or connection error
+ // notifications.
//
// Note: Because calling into InterfaceEndpointClient may lead to destruction
// of this object, if direct calls are allowed, the caller needs to hold on to
// a ref outside of |lock_| before calling this method.
- void ProcessTasks(ClientCallBehavior client_call_behavior);
+ void ProcessTasks(ClientCallBehavior client_call_behavior,
+ base::SingleThreadTaskRunner* current_task_runner);
// Processes the first queued sync message for the endpoint corresponding to
// |id|; returns whether there are more sync messages for that endpoint in the
@@ -196,10 +204,14 @@ class MultiplexRouter
bool ProcessFirstSyncMessageForEndpoint(InterfaceId id);
// Returns true to indicate that |task|/|message| has been processed.
- bool ProcessNotifyErrorTask(Task* task,
- ClientCallBehavior client_call_behavior);
- bool ProcessIncomingMessage(Message* message,
- ClientCallBehavior client_call_behavior);
+ bool ProcessNotifyErrorTask(
+ Task* task,
+ ClientCallBehavior client_call_behavior,
+ base::SingleThreadTaskRunner* current_task_runner);
+ bool ProcessIncomingMessage(
+ Message* message,
+ ClientCallBehavior client_call_behavior,
+ base::SingleThreadTaskRunner* current_task_runner);
void MaybePostToProcessTasks(base::SingleThreadTaskRunner* task_runner);
void LockAndCallProcessTasks();
@@ -232,11 +244,12 @@ class MultiplexRouter
std::map<InterfaceId, scoped_refptr<InterfaceEndpoint>> endpoints_;
uint32_t next_interface_id_value_;
- std::deque<scoped_ptr<Task>> tasks_;
+ std::deque<std::unique_ptr<Task>> tasks_;
// It refers to tasks in |tasks_| and doesn't own any of them.
std::map<InterfaceId, std::deque<Task*>> sync_message_tasks_;
bool posted_to_process_tasks_;
+ scoped_refptr<base::SingleThreadTaskRunner> posted_to_task_runner_;
bool encountered_error_;
diff --git a/chromium/mojo/public/cpp/bindings/lib/native_serialization.h b/chromium/mojo/public/cpp/bindings/lib/native_serialization.h
deleted file mode 100644
index 835e072a8f3..00000000000
--- a/chromium/mojo/public/cpp/bindings/lib/native_serialization.h
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2015 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_BINDINGS_LIB_NATIVE_SERIALIZATION_H_
-#define MOJO_PUBLIC_CPP_BINDINGS_LIB_NATIVE_SERIALIZATION_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <limits>
-
-#include "base/logging.h"
-#include "base/pickle.h"
-#include "ipc/ipc_param_traits.h"
-#include "mojo/public/cpp/bindings/lib/array_internal.h"
-#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
-#include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
-#include "mojo/public/cpp/bindings/lib/pickle_buffer.h"
-
-namespace mojo {
-namespace internal {
-
-// Generated bindings for native-only types will specialize this to |true|.
-// It can be used as a signal (by e.g. the Array serializer) for when to use
-// SerializeNative_ with a type.
-template <typename E>
-struct ShouldUseNativeSerializer { static const bool value = false; };
-
-template <typename T>
-size_t GetSerializedSizeNative_(const T& value, SerializationContext* context) {
- base::PickleSizer sizer;
- IPC::ParamTraits<T>::GetSize(&sizer, value);
- return Align(sizer.payload_size() + sizeof(ArrayHeader));
-}
-
-template <typename T>
-void SerializeNative_(const T& value,
- Buffer* buffer,
- Array_Data<uint8_t>** out,
- SerializationContext* context) {
- PickleBuffer* pickler = buffer->AsPickleBuffer();
- DCHECK(pickler) << "Native types can only be used with PickleBuffers.";
-
- ArrayHeader* header =
- reinterpret_cast<ArrayHeader*>(buffer->Allocate(sizeof(ArrayHeader)));
-
- // Remember where the Pickle started before writing.
- base::Pickle* pickle = pickler->pickle();
- const char* data_start = pickle->end_of_payload();
-
-#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
- const char* payload_base = pickle->payload();
- size_t size_before_write = pickle->payload_size();
-#endif
-
- IPC::ParamTraits<T>::Write(pickle, value);
-
-#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
- // Ensure the pickle buffer hasn't moved.
- DCHECK_EQ(payload_base, pickle->payload());
- // Explicitly validate that the value returned by GetSize() always equals the
- // number of bytes actually written by Write().
- DCHECK_GE(pickle->payload_size(), size_before_write);
- size_t bytes_written = pickle->payload_size() - size_before_write;
- DCHECK_EQ(Align(bytes_written + sizeof(ArrayHeader)),
- GetSerializedSizeNative_(value, context));
-#endif
-
- // Fix up the ArrayHeader so that num_elements contains the length of the
- // pickled data.
- size_t pickled_size = pickle->end_of_payload() - data_start;
- size_t total_size = pickled_size + sizeof(ArrayHeader);
- DCHECK_LT(total_size, std::numeric_limits<uint32_t>::max());
- header->num_bytes = static_cast<uint32_t>(total_size);
- header->num_elements = static_cast<uint32_t>(pickled_size);
-
- *out = reinterpret_cast<Array_Data<uint8_t>*>(header);
-}
-
-template <typename T>
-bool DeserializeNative_(Array_Data<uint8_t>* data,
- T* out,
- SerializationContext* context) {
- if (!data)
- return true;
-
- // Construct a temporary base::Pickle view over the array data. Note that
- // the Array_Data is laid out like this:
- //
- // [num_bytes (4 bytes)] [num_elements (4 bytes)] [elements...]
- //
- // and base::Pickle expects to view data like this:
- //
- // [payload_size (4 bytes)] [header bytes ...] [payload...]
- //
- // Because ArrayHeader's num_bytes includes the length of the header and
- // Pickle's payload_size does not, we need to adjust the stored value
- // momentarily so Pickle can view the data.
- ArrayHeader* header = reinterpret_cast<ArrayHeader*>(data);
- DCHECK_GE(header->num_bytes, sizeof(ArrayHeader));
- header->num_bytes -= sizeof(ArrayHeader);
-
- {
- // Construct a view over the full Array_Data, including our hacked up
- // header. Pickle will infer from this that the header is 8 bytes long,
- // and the payload will contain all of the pickled bytes.
- base::Pickle pickle_view(reinterpret_cast<const char*>(header),
- header->num_bytes + sizeof(ArrayHeader));
- base::PickleIterator iter(pickle_view);
- if (!IPC::ParamTraits<T>::Read(&pickle_view, &iter, out))
- return false;
- }
-
- // Return the header to its original state.
- header->num_bytes += sizeof(ArrayHeader);
-
- return true;
-}
-
-} // namespace internal
-} // namespace mojo
-
-#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_NATIVE_SERIALIZATION_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/native_struct.cc b/chromium/mojo/public/cpp/bindings/lib/native_struct.cc
new file mode 100644
index 00000000000..837b75a60e3
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/native_struct.cc
@@ -0,0 +1,30 @@
+// Copyright 2016 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 "mojo/public/cpp/bindings/native_struct.h"
+
+namespace mojo {
+
+// static
+NativeStructPtr NativeStruct::New() {
+ NativeStructPtr rv;
+ internal::StructHelper<NativeStruct>::Initialize(&rv);
+ return rv;
+}
+
+NativeStruct::NativeStruct() : data(nullptr) {}
+
+NativeStruct::~NativeStruct() {}
+
+NativeStructPtr NativeStruct::Clone() const {
+ NativeStructPtr rv(New());
+ rv->data = data.Clone();
+ return rv;
+}
+
+bool NativeStruct::Equals(const NativeStruct& other) const {
+ return data.Equals(other.data);
+}
+
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/native_struct_data.cc b/chromium/mojo/public/cpp/bindings/lib/native_struct_data.cc
new file mode 100644
index 00000000000..1d6bf6f873f
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/native_struct_data.cc
@@ -0,0 +1,22 @@
+// Copyright 2016 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 "mojo/public/cpp/bindings/lib/native_struct_data.h"
+
+#include "mojo/public/cpp/bindings/lib/bounds_checker.h"
+#include "mojo/public/cpp/bindings/lib/buffer.h"
+
+namespace mojo {
+namespace internal {
+
+// static
+bool NativeStruct_Data::Validate(const void* data,
+ BoundsChecker* bounds_checker) {
+ const ArrayValidateParams data_validate_params(0, false, nullptr);
+ return Array_Data<uint8_t>::Validate(data, bounds_checker,
+ &data_validate_params);
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/native_struct_data.h b/chromium/mojo/public/cpp/bindings/lib/native_struct_data.h
new file mode 100644
index 00000000000..0c2cccd1488
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/native_struct_data.h
@@ -0,0 +1,41 @@
+// Copyright 2016 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_BINDINGS_LIB_NATIVE_STRUCT_DATA_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_NATIVE_STRUCT_DATA_H_
+
+#include <vector>
+
+#include "mojo/public/cpp/bindings/lib/array_internal.h"
+#include "mojo/public/cpp/system/handle.h"
+
+namespace mojo {
+namespace internal {
+
+class BoundsChecker;
+class Buffer;
+
+class NativeStruct_Data {
+ public:
+ static bool Validate(const void* data, BoundsChecker* bounds_checker);
+
+ void EncodePointers() {}
+ void DecodePointers() {}
+
+ // Unlike normal structs, the memory layout is exactly the same as an array
+ // of uint8_t.
+ Array_Data<uint8_t> data;
+
+ private:
+ NativeStruct_Data() = delete;
+ ~NativeStruct_Data() = delete;
+};
+
+static_assert(sizeof(Array_Data<uint8_t>) == sizeof(NativeStruct_Data),
+ "Mismatched NativeStruct_Data and Array_Data<uint8_t> size");
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_NATIVE_STRUCT_DATA_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/native_struct_serialization.cc b/chromium/mojo/public/cpp/bindings/lib/native_struct_serialization.cc
new file mode 100644
index 00000000000..fe65f147c61
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/native_struct_serialization.cc
@@ -0,0 +1,59 @@
+// Copyright 2016 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 "mojo/public/cpp/bindings/lib/native_struct_serialization.h"
+
+#include "mojo/public/cpp/bindings/lib/serialization.h"
+
+namespace mojo {
+namespace internal {
+
+// static
+size_t UnmappedNativeStructSerializerImpl::PrepareToSerialize(
+ const NativeStructPtr& input,
+ SerializationContext* context) {
+ if (!input)
+ return 0;
+ return internal::PrepareToSerialize<Array<uint8_t>>(input->data, context);
+}
+
+// static
+void UnmappedNativeStructSerializerImpl::Serialize(
+ const NativeStructPtr& input,
+ Buffer* buffer,
+ NativeStruct_Data** output,
+ SerializationContext* context) {
+ if (!input) {
+ *output = nullptr;
+ return;
+ }
+
+ Array_Data<uint8_t>* data = nullptr;
+ const ArrayValidateParams params(0, false, nullptr);
+ internal::Serialize<Array<uint8_t>>(input->data, buffer, &data, &params,
+ context);
+ *output = reinterpret_cast<NativeStruct_Data*>(data);
+}
+
+// static
+bool UnmappedNativeStructSerializerImpl::Deserialize(
+ NativeStruct_Data* input,
+ NativeStructPtr* output,
+ SerializationContext* context) {
+ Array_Data<uint8_t>* data = reinterpret_cast<Array_Data<uint8_t>*>(input);
+
+ NativeStructPtr result(NativeStruct::New());
+ if (!internal::Deserialize<Array<uint8_t>>(data, &result->data, context)) {
+ output = nullptr;
+ return false;
+ }
+ if (!result->data)
+ *output = nullptr;
+ else
+ result.Swap(output);
+ return true;
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/native_struct_serialization.h b/chromium/mojo/public/cpp/bindings/lib/native_struct_serialization.h
new file mode 100644
index 00000000000..09f3c883131
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/native_struct_serialization.h
@@ -0,0 +1,132 @@
+// Copyright 2015 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_BINDINGS_LIB_NATIVE_STRUCT_SERIALIZATION_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_NATIVE_STRUCT_SERIALIZATION_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <limits>
+
+#include "base/logging.h"
+#include "base/pickle.h"
+#include "ipc/ipc_param_traits.h"
+#include "mojo/public/cpp/bindings/lib/array_internal.h"
+#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
+#include "mojo/public/cpp/bindings/lib/native_struct_data.h"
+#include "mojo/public/cpp/bindings/lib/serialization_forward.h"
+#include "mojo/public/cpp/bindings/lib/serialization_util.h"
+#include "mojo/public/cpp/bindings/native_struct.h"
+
+namespace mojo {
+namespace internal {
+
+template <typename MaybeConstUserType>
+struct NativeStructSerializerImpl {
+ using UserType = typename std::remove_const<MaybeConstUserType>::type;
+ using Traits = IPC::ParamTraits<UserType>;
+
+ static size_t PrepareToSerialize(MaybeConstUserType& value,
+ SerializationContext* context) {
+ base::PickleSizer sizer;
+ Traits::GetSize(&sizer, value);
+ return Align(sizer.payload_size() + sizeof(ArrayHeader));
+ }
+
+ static void Serialize(MaybeConstUserType& value,
+ Buffer* buffer,
+ NativeStruct_Data** out,
+ SerializationContext* context) {
+ base::Pickle pickle;
+ Traits::Write(&pickle, value);
+
+#if DCHECK_IS_ON()
+ base::PickleSizer sizer;
+ Traits::GetSize(&sizer, value);
+ DCHECK_EQ(sizer.payload_size(), pickle.payload_size());
+#endif
+
+ size_t total_size = pickle.payload_size() + sizeof(ArrayHeader);
+ DCHECK_LT(total_size, std::numeric_limits<uint32_t>::max());
+
+ // Allocate a uint8 array, initialize its header, and copy the Pickle in.
+ ArrayHeader* header =
+ reinterpret_cast<ArrayHeader*>(buffer->Allocate(total_size));
+ header->num_bytes = static_cast<uint32_t>(total_size);
+ header->num_elements = static_cast<uint32_t>(pickle.payload_size());
+ memcpy(reinterpret_cast<char*>(header) + sizeof(ArrayHeader),
+ pickle.payload(), pickle.payload_size());
+
+ *out = reinterpret_cast<NativeStruct_Data*>(header);
+ }
+
+ static bool Deserialize(NativeStruct_Data* data,
+ UserType* out,
+ SerializationContext* context) {
+ if (!data)
+ return true;
+
+ // Construct a temporary base::Pickle view over the array data. Note that
+ // the Array_Data is laid out like this:
+ //
+ // [num_bytes (4 bytes)] [num_elements (4 bytes)] [elements...]
+ //
+ // and base::Pickle expects to view data like this:
+ //
+ // [payload_size (4 bytes)] [header bytes ...] [payload...]
+ //
+ // Because ArrayHeader's num_bytes includes the length of the header and
+ // Pickle's payload_size does not, we need to adjust the stored value
+ // momentarily so Pickle can view the data.
+ ArrayHeader* header = reinterpret_cast<ArrayHeader*>(data);
+ DCHECK_GE(header->num_bytes, sizeof(ArrayHeader));
+ header->num_bytes -= sizeof(ArrayHeader);
+
+ {
+ // Construct a view over the full Array_Data, including our hacked up
+ // header. Pickle will infer from this that the header is 8 bytes long,
+ // and the payload will contain all of the pickled bytes.
+ base::Pickle pickle_view(reinterpret_cast<const char*>(header),
+ header->num_bytes + sizeof(ArrayHeader));
+ base::PickleIterator iter(pickle_view);
+ if (!Traits::Read(&pickle_view, &iter, out))
+ return false;
+ }
+
+ // Return the header to its original state.
+ header->num_bytes += sizeof(ArrayHeader);
+
+ return true;
+ }
+};
+
+struct UnmappedNativeStructSerializerImpl {
+ static size_t PrepareToSerialize(const NativeStructPtr& input,
+ SerializationContext* context);
+ static void Serialize(const NativeStructPtr& input,
+ Buffer* buffer,
+ NativeStruct_Data** output,
+ SerializationContext* context);
+ static bool Deserialize(NativeStruct_Data* input,
+ NativeStructPtr* output,
+ SerializationContext* context);
+};
+
+template <>
+struct NativeStructSerializerImpl<NativeStructPtr>
+ : public UnmappedNativeStructSerializerImpl {};
+
+template <>
+struct NativeStructSerializerImpl<const NativeStructPtr>
+ : public UnmappedNativeStructSerializerImpl {};
+
+template <typename MaybeConstUserType>
+struct Serializer<NativeStructPtr, MaybeConstUserType>
+ : public NativeStructSerializerImpl<MaybeConstUserType> {};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_NATIVE_STRUCT_SERIALIZATION_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/pickle_buffer.cc b/chromium/mojo/public/cpp/bindings/lib/pickle_buffer.cc
deleted file mode 100644
index ecd75dba69d..00000000000
--- a/chromium/mojo/public/cpp/bindings/lib/pickle_buffer.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2015 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 "mojo/public/cpp/bindings/lib/pickle_buffer.h"
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/pickle.h"
-#include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
-
-namespace mojo {
-namespace internal {
-
-class PickleBuffer::Storage : public base::Pickle {
- public:
- explicit Storage(size_t num_bytes);
- ~Storage() override {}
-
- size_t available_capacity() const {
- return capacity_after_header() - payload_size();
- }
-
- void* GetData() { return static_cast<void*>(mutable_payload()); }
- void* Claim(size_t num_bytes) { return ClaimBytes(num_bytes); }
-
- private:
- // TODO(rockot): Stop wasting 8 bytes per buffer.
- //
- // We don't use Pickle's header at all, but its base header type consumes 4
- // bytes. We waste another 4 bytes to keep our actual buffer aligned to an
- // 8-byte boundary.
- //
- // The reason we don't use base::Pickle's header is that it stores payload
- // length in the first 4 bytes. Mojo Messages are packed like mojom structs,
- // where the first 4 bytes are header size rather than payload size.
- struct PaddedHeader : public base::Pickle::Header {
- uint32_t padding;
- };
-
- static_assert(sizeof(PaddedHeader) % 8 == 0,
- "PickleBuffer requires a Pickle header size with 8-byte alignment.");
-
- DISALLOW_COPY_AND_ASSIGN(Storage);
-};
-
-PickleBuffer::Storage::Storage(size_t num_bytes)
- : base::Pickle(sizeof(PaddedHeader)) {
- headerT<PaddedHeader>()->padding = 0;
- Resize(num_bytes);
-}
-
-PickleBuffer::PickleBuffer(size_t num_bytes, bool zero_initialized)
- : storage_(new Storage(num_bytes)) {
- if (zero_initialized)
- memset(storage_->GetData(), 0, num_bytes);
-}
-
-PickleBuffer::~PickleBuffer() {
-}
-
-const void* PickleBuffer::data() const { return storage_->GetData(); }
-
-size_t PickleBuffer::data_num_bytes() const { return storage_->payload_size(); }
-
-base::Pickle* PickleBuffer::pickle() const {
- return storage_.get();
-}
-
-void* PickleBuffer::Allocate(size_t num_bytes) {
- DCHECK(storage_);
-
- // The last allocation may terminate in between 8-byte boundaries. Pad the
- // front of this allocation if that's the case.
- size_t padded_capacity = Align(storage_->payload_size());
- DCHECK_GE(padded_capacity, storage_->payload_size());
-
- size_t padding_bytes = padded_capacity - storage_->payload_size();
- size_t allocation_size = padding_bytes + num_bytes;
- const void* previous_data_location = storage_->GetData();
- if (storage_->available_capacity() < allocation_size) {
- NOTREACHED() <<
- "Message buffers must be fully allocated before serialization.";
- return nullptr;
- }
- char* p = static_cast<char*>(storage_->Claim(allocation_size));
- DCHECK_EQ(storage_->GetData(), previous_data_location);
- return p + padding_bytes;
-}
-
-PickleBuffer* PickleBuffer::AsPickleBuffer() { return this; }
-
-} // namespace internal
-} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/pickle_buffer.h b/chromium/mojo/public/cpp/bindings/lib/pickle_buffer.h
deleted file mode 100644
index c940b38f786..00000000000
--- a/chromium/mojo/public/cpp/bindings/lib/pickle_buffer.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2015 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_BINDINGS_LIB_PICKLE_BUFFER_H_
-#define MOJO_PUBLIC_CPP_BINDINGS_LIB_PICKLE_BUFFER_H_
-
-#include <stddef.h>
-
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/pickle.h"
-#include "mojo/public/cpp/bindings/lib/buffer.h"
-
-namespace mojo {
-namespace internal {
-
-// An implementation of Buffer which uses base::Pickle for its backing. Note
-// that this does not use Pickle's header structure at all, instead storing
-// the complete Message (including header) in the Pickle's payload.
-class PickleBuffer : public Buffer {
- public:
- PickleBuffer(size_t num_bytes, bool zero_initialized);
- ~PickleBuffer() override;
-
- const void* data() const;
-
- void* data() {
- return const_cast<void*>(static_cast<const PickleBuffer*>(this)->data());
- }
-
- size_t data_num_bytes() const;
-
- base::Pickle* pickle() const;
-
- private:
- class Storage;
-
- // Buffer implementation. Note that this cannot grow the Pickle's capacity and
- // it is an error to Allocate() more bytes in total than have been
- // pre-allocated using ReserveCapacity() or ReserveUninitializedCapacity().
- //
- // This guarantees that the returned data is aligned on an 8-byte boundary.
- void* Allocate(size_t num_bytes) override;
- PickleBuffer* AsPickleBuffer() override;
-
- scoped_ptr<Storage> storage_;
-
- DISALLOW_COPY_AND_ASSIGN(PickleBuffer);
-};
-
-} // namespace internal
-} // namespace mojo
-
-#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_PICKLE_BUFFER_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/pipe_control_message_handler.cc b/chromium/mojo/public/cpp/bindings/lib/pipe_control_message_handler.cc
index 6a5c224ed68..ae952c503f2 100644
--- a/chromium/mojo/public/cpp/bindings/lib/pipe_control_message_handler.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/pipe_control_message_handler.cc
@@ -7,6 +7,7 @@
#include "base/logging.h"
#include "mojo/public/cpp/bindings/lib/message_builder.h"
#include "mojo/public/cpp/bindings/lib/pipe_control_message_handler_delegate.h"
+#include "mojo/public/cpp/bindings/lib/serialization.h"
#include "mojo/public/cpp/bindings/lib/validation_util.h"
#include "mojo/public/interfaces/bindings/pipe_control_messages.mojom.h"
@@ -51,10 +52,11 @@ bool PipeControlMessageHandler::RunOrClosePipe(Message* message) {
reinterpret_cast<
pipe_control::internal::RunOrClosePipeMessageParams_Data*>(
message->mutable_payload());
- params->DecodePointersAndHandles(message->mutable_handles());
+ params->DecodePointers();
pipe_control::RunOrClosePipeMessageParamsPtr params_ptr;
- Deserialize_(params, &params_ptr, nullptr);
+ Deserialize<pipe_control::RunOrClosePipeMessageParamsPtr>(params, &params_ptr,
+ &context_);
if (params_ptr->input->is_peer_associated_endpoint_closed_event()) {
return delegate_->OnPeerAssociatedEndpointClosed(
diff --git a/chromium/mojo/public/cpp/bindings/lib/pipe_control_message_handler.h b/chromium/mojo/public/cpp/bindings/lib/pipe_control_message_handler.h
index 091e7c28758..c42d0bae3d1 100644
--- a/chromium/mojo/public/cpp/bindings/lib/pipe_control_message_handler.h
+++ b/chromium/mojo/public/cpp/bindings/lib/pipe_control_message_handler.h
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "mojo/public/cpp/bindings/lib/interface_id.h"
+#include "mojo/public/cpp/bindings/lib/serialization_context.h"
#include "mojo/public/cpp/bindings/message.h"
namespace mojo {
@@ -38,6 +39,7 @@ class PipeControlMessageHandler : public MessageReceiver {
bool RunOrClosePipe(Message* message);
PipeControlMessageHandlerDelegate* const delegate_;
+ SerializationContext context_;
DISALLOW_COPY_AND_ASSIGN(PipeControlMessageHandler);
};
diff --git a/chromium/mojo/public/cpp/bindings/lib/pipe_control_message_proxy.cc b/chromium/mojo/public/cpp/bindings/lib/pipe_control_message_proxy.cc
index 4ea0353e29f..492bc02d85a 100644
--- a/chromium/mojo/public/cpp/bindings/lib/pipe_control_message_proxy.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/pipe_control_message_proxy.cc
@@ -9,6 +9,7 @@
#include "base/compiler_specific.h"
#include "mojo/public/cpp/bindings/lib/message_builder.h"
+#include "mojo/public/cpp/bindings/lib/serialization.h"
#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/interfaces/bindings/pipe_control_messages.mojom.h"
@@ -17,17 +18,21 @@ namespace internal {
namespace {
void SendRunOrClosePipeMessage(MessageReceiver* receiver,
- pipe_control::RunOrClosePipeInputPtr input) {
+ pipe_control::RunOrClosePipeInputPtr input,
+ SerializationContext* context) {
pipe_control::RunOrClosePipeMessageParamsPtr params_ptr(
pipe_control::RunOrClosePipeMessageParams::New());
params_ptr->input = std::move(input);
- size_t size = GetSerializedSize_(params_ptr, nullptr);
+ size_t size =
+ PrepareToSerialize<pipe_control::RunOrClosePipeMessageParamsPtr>(
+ params_ptr, context);
MessageBuilder builder(pipe_control::kRunOrClosePipeMessageId, size);
pipe_control::internal::RunOrClosePipeMessageParams_Data* params = nullptr;
- Serialize_(std::move(params_ptr), builder.buffer(), &params, nullptr);
- params->EncodePointersAndHandles(builder.message()->mutable_handles());
+ Serialize<pipe_control::RunOrClosePipeMessageParamsPtr>(
+ params_ptr, builder.buffer(), &params, context);
+ params->EncodePointers();
builder.message()->set_interface_id(kInvalidInterfaceId);
bool ok = receiver->Accept(builder.message());
// This return value may be ignored as !ok implies the underlying message pipe
@@ -49,7 +54,7 @@ void PipeControlMessageProxy::NotifyPeerEndpointClosed(InterfaceId id) {
pipe_control::RunOrClosePipeInput::New());
input->set_peer_associated_endpoint_closed_event(std::move(event));
- SendRunOrClosePipeMessage(receiver_, std::move(input));
+ SendRunOrClosePipeMessage(receiver_, std::move(input), &context_);
}
void PipeControlMessageProxy::NotifyEndpointClosedBeforeSent(InterfaceId id) {
@@ -61,7 +66,7 @@ void PipeControlMessageProxy::NotifyEndpointClosedBeforeSent(InterfaceId id) {
pipe_control::RunOrClosePipeInput::New());
input->set_associated_endpoint_closed_before_sent_event(std::move(event));
- SendRunOrClosePipeMessage(receiver_, std::move(input));
+ SendRunOrClosePipeMessage(receiver_, std::move(input), &context_);
}
} // namespace internal
diff --git a/chromium/mojo/public/cpp/bindings/lib/pipe_control_message_proxy.h b/chromium/mojo/public/cpp/bindings/lib/pipe_control_message_proxy.h
index 3804c4ce063..87a8d478c8a 100644
--- a/chromium/mojo/public/cpp/bindings/lib/pipe_control_message_proxy.h
+++ b/chromium/mojo/public/cpp/bindings/lib/pipe_control_message_proxy.h
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "mojo/public/cpp/bindings/lib/interface_id.h"
+#include "mojo/public/cpp/bindings/lib/serialization_context.h"
namespace mojo {
@@ -26,6 +27,7 @@ class PipeControlMessageProxy {
private:
// Not owned.
MessageReceiver* receiver_;
+ SerializationContext context_;
DISALLOW_COPY_AND_ASSIGN(PipeControlMessageProxy);
};
diff --git a/chromium/mojo/public/cpp/bindings/lib/router.cc b/chromium/mojo/public/cpp/bindings/lib/router.cc
index 9e93f0cfd62..da5f34b1df5 100644
--- a/chromium/mojo/public/cpp/bindings/lib/router.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/router.cc
@@ -5,15 +5,14 @@
#include "mojo/public/cpp/bindings/lib/router.h"
#include <stdint.h>
+
#include <utility>
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
-#include "base/single_thread_task_runner.h"
+#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
-#include "base/thread_task_runner_handle.h"
namespace mojo {
namespace internal {
@@ -30,20 +29,25 @@ void DCheckIfInvalid(const base::WeakPtr<Router>& router,
class ResponderThunk : public MessageReceiverWithStatus {
public:
- explicit ResponderThunk(const base::WeakPtr<Router>& router)
- : router_(router), accept_was_invoked_(false),
- task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
+ explicit ResponderThunk(const base::WeakPtr<Router>& router,
+ scoped_refptr<base::SingleThreadTaskRunner> runner)
+ : router_(router),
+ accept_was_invoked_(false),
+ task_runner_(std::move(runner)) {}
~ResponderThunk() override {
if (!accept_was_invoked_) {
// The Mojo application handled a message that was expecting a response
// but did not send a response.
+ // We raise an error to signal the calling application that an error
+ // condition occurred. Without this the calling application would have no
+ // way of knowing it should stop waiting for a response.
if (task_runner_->RunsTasksOnCurrentThread()) {
- if (router_) {
- // We raise an error to signal the calling application that an error
- // condition occurred. Without this the calling application would have
- // no way of knowing it should stop waiting for a response.
+ // Please note that even if this code is run from a different task
+ // runner on the same thread as |task_runner_|, it is okay to directly
+ // call Router::RaiseError(), because it will raise error from the
+ // correct task runner asynchronously.
+ if (router_)
router_->RaiseError();
- }
} else {
task_runner_->PostTask(FROM_HERE,
base::Bind(&Router::RaiseError, router_));
@@ -112,10 +116,13 @@ bool Router::HandleIncomingMessageThunk::Accept(Message* message) {
Router::Router(ScopedMessagePipeHandle message_pipe,
FilterChain filters,
- bool expects_sync_requests)
+ bool expects_sync_requests,
+ scoped_refptr<base::SingleThreadTaskRunner> runner)
: thunk_(this),
filters_(std::move(filters)),
- connector_(std::move(message_pipe), Connector::SINGLE_THREADED_SEND),
+ connector_(std::move(message_pipe),
+ Connector::SINGLE_THREADED_SEND,
+ std::move(runner)),
incoming_receiver_(nullptr),
next_request_id_(0),
testing_mode_(false),
@@ -146,20 +153,21 @@ bool Router::AcceptWithResponder(Message* message, MessageReceiver* responder) {
if (request_id == 0)
request_id = next_request_id_++;
+ bool is_sync = message->has_flag(kMessageIsSync);
message->set_request_id(request_id);
if (!connector_.Accept(message))
return false;
- if (!message->has_flag(kMessageIsSync)) {
+ if (!is_sync) {
// We assume ownership of |responder|.
- async_responders_[request_id] = make_scoped_ptr(responder);
+ async_responders_[request_id] = base::WrapUnique(responder);
return true;
}
bool response_received = false;
- scoped_ptr<MessageReceiver> sync_responder(responder);
+ std::unique_ptr<MessageReceiver> sync_responder(responder);
sync_responses_.insert(std::make_pair(
- request_id, make_scoped_ptr(new SyncResponseInfo(&response_received))));
+ request_id, base::WrapUnique(new SyncResponseInfo(&response_received))));
base::WeakPtr<Router> weak_self = weak_factory_.GetWeakPtr();
connector_.SyncWatch(&response_received);
@@ -169,7 +177,7 @@ bool Router::AcceptWithResponder(Message* message, MessageReceiver* responder) {
auto iter = sync_responses_.find(request_id);
DCHECK_EQ(&response_received, iter->second->response_received);
if (response_received) {
- scoped_ptr<Message> response = std::move(iter->second->response);
+ std::unique_ptr<Message> response = std::move(iter->second->response);
ignore_result(sync_responder->Accept(response.get()));
}
sync_responses_.erase(iter);
@@ -192,13 +200,13 @@ bool Router::HandleIncomingMessage(Message* message) {
connector_.during_sync_handle_watcher_callback();
if (!message->has_flag(kMessageIsSync) &&
(during_sync_call || !pending_messages_.empty())) {
- scoped_ptr<Message> pending_message(new Message);
+ std::unique_ptr<Message> pending_message(new Message);
message->MoveTo(pending_message.get());
pending_messages_.push(std::move(pending_message));
if (!pending_task_for_messages_) {
pending_task_for_messages_ = true;
- base::MessageLoop::current()->PostTask(
+ connector_.task_runner()->PostTask(
FROM_HERE, base::Bind(&Router::HandleQueuedMessages,
weak_factory_.GetWeakPtr()));
}
@@ -215,7 +223,7 @@ void Router::HandleQueuedMessages() {
base::WeakPtr<Router> weak_self = weak_factory_.GetWeakPtr();
while (!pending_messages_.empty()) {
- scoped_ptr<Message> message(std::move(pending_messages_.front()));
+ std::unique_ptr<Message> message(std::move(pending_messages_.front()));
pending_messages_.pop();
bool result = HandleMessageInternal(message.get());
@@ -242,8 +250,8 @@ bool Router::HandleMessageInternal(Message* message) {
if (!incoming_receiver_)
return false;
- MessageReceiverWithStatus* responder =
- new ResponderThunk(weak_factory_.GetWeakPtr());
+ MessageReceiverWithStatus* responder = new ResponderThunk(
+ weak_factory_.GetWeakPtr(), connector_.task_runner());
bool ok = incoming_receiver_->AcceptWithResponder(message, responder);
if (!ok)
delete responder;
@@ -269,7 +277,7 @@ bool Router::HandleMessageInternal(Message* message) {
DCHECK(testing_mode_);
return false;
}
- scoped_ptr<MessageReceiver> responder = std::move(it->second);
+ std::unique_ptr<MessageReceiver> responder = std::move(it->second);
async_responders_.erase(it);
return responder->Accept(message);
} else {
@@ -294,7 +302,7 @@ void Router::OnConnectionError() {
if (connector_.during_sync_handle_watcher_callback()) {
// We don't want the error handler to reenter an ongoing sync call.
- base::MessageLoop::current()->PostTask(
+ connector_.task_runner()->PostTask(
FROM_HERE,
base::Bind(&Router::OnConnectionError, weak_factory_.GetWeakPtr()));
return;
diff --git a/chromium/mojo/public/cpp/bindings/lib/router.h b/chromium/mojo/public/cpp/bindings/lib/router.h
index 054bcc115a2..2f5e8e2a971 100644
--- a/chromium/mojo/public/cpp/bindings/lib/router.h
+++ b/chromium/mojo/public/cpp/bindings/lib/router.h
@@ -8,11 +8,13 @@
#include <stdint.h>
#include <map>
+#include <memory>
#include <queue>
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "mojo/public/cpp/bindings/callback.h"
#include "mojo/public/cpp/bindings/lib/connector.h"
@@ -27,7 +29,8 @@ class Router : public MessageReceiverWithResponder {
public:
Router(ScopedMessagePipeHandle message_pipe,
FilterChain filters,
- bool expects_sync_requests);
+ bool expects_sync_requests,
+ scoped_refptr<base::SingleThreadTaskRunner> runner);
~Router() override;
// Sets the receiver to handle messages read from the message pipe that do
@@ -113,14 +116,15 @@ class Router : public MessageReceiverWithResponder {
private:
// Maps from the id of a response to the MessageReceiver that handles the
// response.
- using AsyncResponderMap = std::map<uint64_t, scoped_ptr<MessageReceiver>>;
+ using AsyncResponderMap =
+ std::map<uint64_t, std::unique_ptr<MessageReceiver>>;
struct SyncResponseInfo {
public:
explicit SyncResponseInfo(bool* in_response_received);
~SyncResponseInfo();
- scoped_ptr<Message> response;
+ std::unique_ptr<Message> response;
// Points to a stack-allocated variable.
bool* response_received;
@@ -129,7 +133,7 @@ class Router : public MessageReceiverWithResponder {
DISALLOW_COPY_AND_ASSIGN(SyncResponseInfo);
};
- using SyncResponseMap = std::map<uint64_t, scoped_ptr<SyncResponseInfo>>;
+ using SyncResponseMap = std::map<uint64_t, std::unique_ptr<SyncResponseInfo>>;
class HandleIncomingMessageThunk : public MessageReceiver {
public:
@@ -157,7 +161,7 @@ class Router : public MessageReceiverWithResponder {
SyncResponseMap sync_responses_;
uint64_t next_request_id_;
bool testing_mode_;
- std::queue<scoped_ptr<Message>> pending_messages_;
+ std::queue<std::unique_ptr<Message>> pending_messages_;
// Whether a task has been posted to trigger processing of
// |pending_messages_|.
bool pending_task_for_messages_;
diff --git a/chromium/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc b/chromium/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc
index dfe4e234241..83db0d9533a 100644
--- a/chromium/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc
@@ -2,30 +2,30 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h"
+#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
#include "base/logging.h"
#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
namespace mojo {
-namespace internal {
ScopedInterfaceEndpointHandle::ScopedInterfaceEndpointHandle()
- : ScopedInterfaceEndpointHandle(kInvalidInterfaceId, true, nullptr) {}
+ : ScopedInterfaceEndpointHandle(internal::kInvalidInterfaceId, true,
+ nullptr) {}
ScopedInterfaceEndpointHandle::ScopedInterfaceEndpointHandle(
- InterfaceId id,
+ internal::InterfaceId id,
bool is_local,
- scoped_refptr<MultiplexRouter> router)
+ scoped_refptr<internal::MultiplexRouter> router)
: id_(id), is_local_(is_local), router_(std::move(router)) {
- DCHECK(!IsValidInterfaceId(id) || router_);
+ DCHECK(!internal::IsValidInterfaceId(id) || router_);
}
ScopedInterfaceEndpointHandle::ScopedInterfaceEndpointHandle(
ScopedInterfaceEndpointHandle&& other)
: id_(other.id_), is_local_(other.is_local_) {
router_.swap(other.router_);
- other.id_ = kInvalidInterfaceId;
+ other.id_ = internal::kInvalidInterfaceId;
}
ScopedInterfaceEndpointHandle::~ScopedInterfaceEndpointHandle() {
@@ -41,12 +41,12 @@ ScopedInterfaceEndpointHandle& ScopedInterfaceEndpointHandle::operator=(
}
void ScopedInterfaceEndpointHandle::reset() {
- if (!IsValidInterfaceId(id_))
+ if (!internal::IsValidInterfaceId(id_))
return;
router_->CloseEndpointHandle(id_, is_local_);
- id_ = kInvalidInterfaceId;
+ id_ = internal::kInvalidInterfaceId;
is_local_ = true;
router_ = nullptr;
}
@@ -58,15 +58,14 @@ void ScopedInterfaceEndpointHandle::swap(ScopedInterfaceEndpointHandle& other) {
swap(other.router_, router_);
}
-InterfaceId ScopedInterfaceEndpointHandle::release() {
- InterfaceId result = id_;
+internal::InterfaceId ScopedInterfaceEndpointHandle::release() {
+ internal::InterfaceId result = id_;
- id_ = kInvalidInterfaceId;
+ id_ = internal::kInvalidInterfaceId;
is_local_ = true;
router_ = nullptr;
return result;
}
-} // namespace internal
} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/serialization.h b/chromium/mojo/public/cpp/bindings/lib/serialization.h
index c3af9ffdfc7..b37cc2761e8 100644
--- a/chromium/mojo/public/cpp/bindings/lib/serialization.h
+++ b/chromium/mojo/public/cpp/bindings/lib/serialization.h
@@ -5,9 +5,15 @@
#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_H_
+#include "mojo/public/cpp/bindings/array_traits_standard.h"
+#include "mojo/public/cpp/bindings/array_traits_stl.h"
#include "mojo/public/cpp/bindings/lib/array_serialization.h"
#include "mojo/public/cpp/bindings/lib/map_serialization.h"
-#include "mojo/public/cpp/bindings/lib/native_serialization.h"
+#include "mojo/public/cpp/bindings/lib/native_struct_serialization.h"
#include "mojo/public/cpp/bindings/lib/string_serialization.h"
+#include "mojo/public/cpp/bindings/string_traits_standard.h"
+#include "mojo/public/cpp/bindings/string_traits_stl.h"
+#include "mojo/public/cpp/bindings/string_traits_string16.h"
+#include "mojo/public/cpp/bindings/string_traits_string_piece.h"
#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/serialization_context.cc b/chromium/mojo/public/cpp/bindings/lib/serialization_context.cc
new file mode 100644
index 00000000000..f0cf730f1a4
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/serialization_context.cc
@@ -0,0 +1,62 @@
+// Copyright 2016 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 "mojo/public/cpp/bindings/lib/serialization_context.h"
+
+#include <limits>
+
+#include "base/logging.h"
+#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
+#include "mojo/public/cpp/system/core.h"
+
+namespace mojo {
+namespace internal {
+
+SerializedHandleVector::SerializedHandleVector() {}
+
+SerializedHandleVector::~SerializedHandleVector() {
+ for (auto handle : handles_) {
+ if (handle.is_valid()) {
+ MojoResult rv = MojoClose(handle.value());
+ DCHECK_EQ(rv, MOJO_RESULT_OK);
+ }
+ }
+}
+
+Handle_Data SerializedHandleVector::AddHandle(mojo::Handle handle) {
+ Handle_Data data;
+ if (!handle.is_valid()) {
+ data.value = kEncodedInvalidHandleValue;
+ } else {
+ DCHECK_LT(handles_.size(), std::numeric_limits<uint32_t>::max());
+ data.value = static_cast<uint32_t>(handles_.size());
+ handles_.push_back(handle);
+ }
+ return data;
+}
+
+mojo::Handle SerializedHandleVector::TakeHandle(
+ const Handle_Data& encoded_handle) {
+ if (!encoded_handle.is_valid())
+ return mojo::Handle();
+ DCHECK_LT(encoded_handle.value, handles_.size());
+ return FetchAndReset(&handles_[encoded_handle.value]);
+}
+
+void SerializedHandleVector::Swap(std::vector<mojo::Handle>* other) {
+ handles_.swap(*other);
+}
+
+SerializationContext::SerializationContext() {}
+
+SerializationContext::SerializationContext(
+ scoped_refptr<MultiplexRouter> in_router)
+ : router(std::move(in_router)) {}
+
+SerializationContext::~SerializationContext() {
+ DCHECK(!custom_contexts || custom_contexts->empty());
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/serialization_context.h b/chromium/mojo/public/cpp/bindings/lib/serialization_context.h
new file mode 100644
index 00000000000..48d37cf713a
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/serialization_context.h
@@ -0,0 +1,75 @@
+// Copyright 2016 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_BINDINGS_LIB_BINDINGS_SERIALIZATION_CONTEXT_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_SERIALIZATION_CONTEXT_H_
+
+#include <stddef.h>
+
+#include <memory>
+#include <queue>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
+#include "mojo/public/cpp/system/handle.h"
+
+namespace mojo {
+namespace internal {
+
+class MultiplexRouter;
+
+// A container for handles during serialization/deserialization.
+class SerializedHandleVector {
+ public:
+ SerializedHandleVector();
+ ~SerializedHandleVector();
+
+ size_t size() const { return handles_.size(); }
+
+ // Adds a handle to the handle list and returns its index for encoding.
+ Handle_Data AddHandle(mojo::Handle handle);
+
+ // Takes a handle from the list of serialized handle data.
+ mojo::Handle TakeHandle(const Handle_Data& encoded_handle);
+
+ // Takes a handle from the list of serialized handle data and returns it in
+ // |*out_handle| as a specific scoped handle type.
+ template <typename T>
+ ScopedHandleBase<T> TakeHandleAs(const Handle_Data& encoded_handle) {
+ return MakeScopedHandle(T(TakeHandle(encoded_handle).value()));
+ }
+
+ // Swaps all owned handles out with another Handle vector.
+ void Swap(std::vector<mojo::Handle>* other);
+
+ private:
+ // Handles are owned by this object.
+ std::vector<mojo::Handle> handles_;
+
+ DISALLOW_COPY_AND_ASSIGN(SerializedHandleVector);
+};
+
+// Context information for serialization/deserialization routines.
+struct SerializationContext {
+ SerializationContext();
+ explicit SerializationContext(scoped_refptr<MultiplexRouter> in_router);
+
+ ~SerializationContext();
+
+ // Used to serialize/deserialize associated interface pointers and requests.
+ scoped_refptr<MultiplexRouter> router;
+
+ // Opaque context pointers returned by StringTraits::SetUpContext().
+ std::unique_ptr<std::queue<void*>> custom_contexts;
+
+ // Stashes handles encoded in a message by index.
+ SerializedHandleVector handles;
+};
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_SERIALIZATION_CONTEXT_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/serialization_forward.h b/chromium/mojo/public/cpp/bindings/lib/serialization_forward.h
index b6050498d87..266b3a89757 100644
--- a/chromium/mojo/public/cpp/bindings/lib/serialization_forward.h
+++ b/chromium/mojo/public/cpp/bindings/lib/serialization_forward.h
@@ -5,10 +5,9 @@
#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_FORWARD_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_FORWARD_H_
-#include <stddef.h>
-
-#include "mojo/public/cpp/bindings/lib/string_serialization.h"
-#include "mojo/public/cpp/bindings/lib/wtf_string_serialization.h"
+#include "mojo/public/cpp/bindings/array_traits.h"
+#include "mojo/public/cpp/bindings/string_traits.h"
+#include "mojo/public/cpp/bindings/struct_traits.h"
// This file is included by serialization implementation files to avoid circular
// includes.
@@ -16,118 +15,40 @@
// wtf_serialization.h if necessary).
namespace mojo {
-
-template <typename T>
-class Array;
-
-template <typename K, typename V>
-class Map;
-
-template <typename T>
-class WTFArray;
-
namespace internal {
-template <typename T>
-class Array_Data;
-
-class ArrayValidateParams;
-
-class Buffer;
-
-template <typename K, typename V>
-class Map_Data;
-
-struct SerializationContext;
-
-template <typename T>
-struct ShouldUseNativeSerializer;
-
-// -----------------------------------------------------------------------------
-// Forward declaration for native types.
-
-template <typename T>
-size_t GetSerializedSizeNative_(const T& value, SerializationContext* context);
-
-template <typename T>
-void SerializeNative_(const T& value,
- Buffer* buffer,
- Array_Data<uint8_t>** out,
- SerializationContext* context);
-
-template <typename T>
-bool DeserializeNative_(Array_Data<uint8_t>* data,
- T* out,
- SerializationContext* context);
+template <typename MojomType, typename MaybeConstUserType>
+struct Serializer;
+
+// PrepareToSerialize() must be matched by a Serialize() for the same input
+// later. Moreover, within the same SerializationContext if PrepareToSerialize()
+// is called for |input_1|, ..., |input_n|, Serialize() must be called for
+// those objects in the exact same order.
+template <typename MojomType, typename InputUserType, typename... Args>
+size_t PrepareToSerialize(InputUserType&& input, Args&&... args) {
+ return Serializer<MojomType,
+ typename std::remove_reference<InputUserType>::type>::
+ PrepareToSerialize(std::forward<InputUserType>(input),
+ std::forward<Args>(args)...);
+}
+
+template <typename MojomType, typename InputUserType, typename... Args>
+void Serialize(InputUserType&& input, Args&&... args) {
+ Serializer<MojomType, typename std::remove_reference<InputUserType>::type>::
+ Serialize(std::forward<InputUserType>(input),
+ std::forward<Args>(args)...);
+}
+
+template <typename MojomType,
+ typename DataType,
+ typename InputUserType,
+ typename... Args>
+bool Deserialize(DataType&& input, InputUserType* output, Args&&... args) {
+ return Serializer<MojomType, InputUserType>::Deserialize(
+ std::forward<DataType>(input), output, std::forward<Args>(args)...);
+}
} // namespace internal
-
-// -----------------------------------------------------------------------------
-// Forward declaration for Array.
-
-template <typename E>
-inline size_t GetSerializedSize_(const Array<E>& input,
- internal::SerializationContext* context);
-
-template <typename E, typename F>
-inline void SerializeArray_(
- Array<E> input,
- internal::Buffer* buf,
- internal::Array_Data<F>** output,
- const internal::ArrayValidateParams* validate_params,
- internal::SerializationContext* context);
-
-template <typename E, typename F>
-inline bool Deserialize_(internal::Array_Data<F>* input,
- Array<E>* output,
- internal::SerializationContext* context);
-
-// -----------------------------------------------------------------------------
-// Forward declaration for WTFArray.
-
-template <typename E>
-inline size_t GetSerializedSize_(const WTFArray<E>& input,
- internal::SerializationContext* context);
-
-template <typename E, typename F>
-inline void SerializeArray_(
- WTFArray<E> input,
- internal::Buffer* buf,
- internal::Array_Data<F>** output,
- const internal::ArrayValidateParams* validate_params,
- internal::SerializationContext* context);
-
-template <typename E, typename F>
-inline bool Deserialize_(internal::Array_Data<F>* input,
- WTFArray<E>* output,
- internal::SerializationContext* context);
-
-// -----------------------------------------------------------------------------
-// Forward declaration for Map.
-
-template <typename MapKey, typename MapValue>
-inline size_t GetSerializedSize_(const Map<MapKey, MapValue>& input,
- internal::SerializationContext* context);
-
-template <typename MapKey,
- typename MapValue,
- typename DataKey,
- typename DataValue>
-inline void SerializeMap_(
- Map<MapKey, MapValue> input,
- internal::Buffer* buf,
- internal::Map_Data<DataKey, DataValue>** output,
- const internal::ArrayValidateParams* value_validate_params,
- internal::SerializationContext* context);
-
-template <typename MapKey,
- typename MapValue,
- typename DataKey,
- typename DataValue>
-inline bool Deserialize_(internal::Map_Data<DataKey, DataValue>* input,
- Map<MapKey, MapValue>* output,
- internal::SerializationContext* context);
-
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_FORWARD_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/serialization_util.cc b/chromium/mojo/public/cpp/bindings/lib/serialization_util.cc
new file mode 100644
index 00000000000..d672243b779
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/serialization_util.cc
@@ -0,0 +1,53 @@
+// Copyright 2013 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 "mojo/public/cpp/bindings/lib/serialization_util.h"
+
+namespace mojo {
+namespace internal {
+
+namespace {
+
+const size_t kAlignment = 8;
+
+template <typename T>
+T AlignImpl(T t) {
+ return t + (kAlignment - (t % kAlignment)) % kAlignment;
+}
+
+} // namespace
+
+size_t Align(size_t size) {
+ return AlignImpl(size);
+}
+
+char* AlignPointer(char* ptr) {
+ return reinterpret_cast<char*>(AlignImpl(reinterpret_cast<uintptr_t>(ptr)));
+}
+
+bool IsAligned(const void* ptr) {
+ return !(reinterpret_cast<uintptr_t>(ptr) % kAlignment);
+}
+
+void EncodePointer(const void* ptr, uint64_t* offset) {
+ if (!ptr) {
+ *offset = 0;
+ return;
+ }
+
+ const char* p_obj = reinterpret_cast<const char*>(ptr);
+ const char* p_slot = reinterpret_cast<const char*>(offset);
+ DCHECK(p_obj > p_slot);
+
+ *offset = static_cast<uint64_t>(p_obj - p_slot);
+}
+
+const void* DecodePointerRaw(const uint64_t* offset) {
+ if (!*offset)
+ return nullptr;
+ return reinterpret_cast<const char*>(offset) + *offset;
+}
+
+} // namespace internal
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/serialization_util.h b/chromium/mojo/public/cpp/bindings/lib/serialization_util.h
new file mode 100644
index 00000000000..698e90d9628
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/serialization_util.h
@@ -0,0 +1,233 @@
+// Copyright 2013 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_BINDINGS_LIB_SERIALIZATION_UTIL_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_UTIL_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <queue>
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
+#include "mojo/public/cpp/bindings/interface_ptr.h"
+#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
+#include "mojo/public/cpp/bindings/lib/serialization_context.h"
+#include "mojo/public/cpp/system/handle.h"
+
+namespace mojo {
+namespace internal {
+
+class MultiplexRouter;
+
+size_t Align(size_t size);
+char* AlignPointer(char* ptr);
+
+bool IsAligned(const void* ptr);
+
+// Pointers are encoded as relative offsets. The offsets are relative to the
+// address of where the offset value is stored, such that the pointer may be
+// recovered with the expression:
+//
+// ptr = reinterpret_cast<char*>(offset) + *offset
+//
+// A null pointer is encoded as an offset value of 0.
+//
+void EncodePointer(const void* ptr, uint64_t* offset);
+// Note: This function doesn't validate the encoded pointer value.
+const void* DecodePointerRaw(const uint64_t* offset);
+
+// Note: This function doesn't validate the encoded pointer value.
+template <typename T>
+inline void DecodePointer(const uint64_t* offset, T** ptr) {
+ *ptr = reinterpret_cast<T*>(const_cast<void*>(DecodePointerRaw(offset)));
+}
+
+// The following 2 functions are used to encode/decode all objects (structs and
+// arrays) in a consistent manner.
+
+template <typename T>
+inline void Encode(T* obj) {
+ if (obj->ptr)
+ obj->ptr->EncodePointers();
+ EncodePointer(obj->ptr, &obj->offset);
+}
+
+// Note: This function doesn't validate the encoded pointer and handle values.
+template <typename T>
+inline void Decode(T* obj) {
+ DecodePointer(&obj->offset, &obj->ptr);
+ if (obj->ptr)
+ obj->ptr->DecodePointers();
+}
+
+template <typename T>
+inline void AssociatedInterfacePtrInfoToData(
+ AssociatedInterfacePtrInfo<T> input,
+ AssociatedInterface_Data* output) {
+ output->version = input.version();
+ output->interface_id = input.PassHandle().release();
+}
+
+template <typename T>
+inline void AssociatedInterfaceDataToPtrInfo(
+ AssociatedInterface_Data* input,
+ AssociatedInterfacePtrInfo<T>* output,
+ MultiplexRouter* router) {
+ output->set_handle(
+ router->CreateLocalEndpointHandle(FetchAndReset(&input->interface_id)));
+ output->set_version(input->version);
+}
+
+template <typename T>
+inline void InterfacePointerToData(InterfacePtr<T> input,
+ Interface_Data* output,
+ SerializationContext* context) {
+ InterfacePtrInfo<T> info = input.PassInterface();
+ output->handle = context->handles.AddHandle(info.PassHandle().release());
+ output->version = info.version();
+}
+
+template <typename T>
+inline void InterfaceDataToPointer(Interface_Data* input,
+ InterfacePtr<T>* output,
+ SerializationContext* context) {
+ output->Bind(InterfacePtrInfo<T>(
+ context->handles.TakeHandleAs<mojo::MessagePipeHandle>(input->handle),
+ input->version));
+}
+
+template <typename T>
+struct HasIsNullMethod {
+ template <typename U>
+ static char Test(decltype(U::IsNull)*);
+ template <typename U>
+ static int Test(...);
+ static const bool value = sizeof(Test<T>(0)) == sizeof(char);
+
+ private:
+ EnsureTypeIsComplete<T> check_t_;
+};
+
+template <
+ typename Traits,
+ typename UserType,
+ typename std::enable_if<HasIsNullMethod<Traits>::value>::type* = nullptr>
+bool CallIsNullIfExists(const UserType& input) {
+ return Traits::IsNull(input);
+}
+
+template <
+ typename Traits,
+ typename UserType,
+ typename std::enable_if<!HasIsNullMethod<Traits>::value>::type* = nullptr>
+bool CallIsNullIfExists(const UserType& input) {
+ return false;
+}
+template <typename T>
+struct HasSetToNullMethod {
+ template <typename U>
+ static char Test(decltype(U::SetToNull)*);
+ template <typename U>
+ static int Test(...);
+ static const bool value = sizeof(Test<T>(0)) == sizeof(char);
+
+ private:
+ EnsureTypeIsComplete<T> check_t_;
+};
+
+template <
+ typename Traits,
+ typename UserType,
+ typename std::enable_if<HasSetToNullMethod<Traits>::value>::type* = nullptr>
+bool CallSetToNullIfExists(UserType* output) {
+ Traits::SetToNull(output);
+ return true;
+}
+
+template <typename Traits,
+ typename UserType,
+ typename std::enable_if<!HasSetToNullMethod<Traits>::value>::type* =
+ nullptr>
+bool CallSetToNullIfExists(UserType* output) {
+ LOG(ERROR) << "A null value is received. But the Struct/Array/StringTraits "
+ << "class doesn't define a SetToNull() function and therefore is "
+ << "unable to deserialize the value.";
+ return false;
+}
+
+template <typename T>
+struct HasSetUpContextMethod {
+ template <typename U>
+ static char Test(decltype(U::SetUpContext)*);
+ template <typename U>
+ static int Test(...);
+ static const bool value = sizeof(Test<T>(0)) == sizeof(char);
+
+ private:
+ EnsureTypeIsComplete<T> check_t_;
+};
+
+template <typename Traits,
+ bool has_context = HasSetUpContextMethod<Traits>::value>
+struct CustomContextHelper;
+
+template <typename Traits>
+struct CustomContextHelper<Traits, true> {
+ template <typename MaybeConstUserType>
+ static void* SetUp(MaybeConstUserType& input, SerializationContext* context) {
+ void* custom_context = Traits::SetUpContext(input);
+ if (!context->custom_contexts)
+ context->custom_contexts.reset(new std::queue<void*>());
+ context->custom_contexts->push(custom_context);
+ return custom_context;
+ }
+
+ static void* GetNext(SerializationContext* context) {
+ void* custom_context = context->custom_contexts->front();
+ context->custom_contexts->pop();
+ return custom_context;
+ }
+
+ template <typename MaybeConstUserType>
+ static void TearDown(MaybeConstUserType& input, void* custom_context) {
+ Traits::TearDownContext(input, custom_context);
+ }
+};
+
+template <typename Traits>
+struct CustomContextHelper<Traits, false> {
+ template <typename MaybeConstUserType>
+ static void* SetUp(MaybeConstUserType& input, SerializationContext* context) {
+ return nullptr;
+ }
+
+ static void* GetNext(SerializationContext* context) { return nullptr; }
+
+ template <typename MaybeConstUserType>
+ static void TearDown(MaybeConstUserType& input, void* custom_context) {
+ DCHECK(!custom_context);
+ }
+};
+
+template <typename ReturnType, typename ParamType, typename MaybeConstUserType>
+ReturnType CallWithContext(ReturnType (*f)(ParamType, void*),
+ MaybeConstUserType& input,
+ void* context) {
+ return f(input, context);
+}
+
+template <typename ReturnType, typename ParamType, typename MaybeConstUserType>
+ReturnType CallWithContext(ReturnType (*f)(ParamType),
+ MaybeConstUserType& input,
+ void* context) {
+ return f(input);
+}
+
+} // namespace internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_UTIL_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/string_serialization.cc b/chromium/mojo/public/cpp/bindings/lib/string_serialization.cc
deleted file mode 100644
index 6b9f741457c..00000000000
--- a/chromium/mojo/public/cpp/bindings/lib/string_serialization.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2014 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 "mojo/public/cpp/bindings/lib/string_serialization.h"
-
-#include <stddef.h>
-#include <string.h>
-
-namespace mojo {
-
-size_t GetSerializedSize_(const String& input,
- internal::SerializationContext* context) {
- if (!input)
- return 0;
- return internal::Align(sizeof(internal::String_Data) + input.size());
-}
-
-void Serialize_(const String& input,
- internal::Buffer* buf,
- internal::String_Data** output,
- internal::SerializationContext* context) {
- if (input) {
- internal::String_Data* result =
- internal::String_Data::New(input.size(), buf);
- if (result)
- memcpy(result->storage(), input.data(), input.size());
- *output = result;
- } else {
- *output = nullptr;
- }
-}
-
-bool Deserialize_(internal::String_Data* input,
- String* output,
- internal::SerializationContext* context) {
- if (input) {
- String result(input->storage(), input->size());
- result.Swap(output);
- } else {
- *output = nullptr;
- }
- return true;
-}
-
-} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/string_serialization.h b/chromium/mojo/public/cpp/bindings/lib/string_serialization.h
index a1ae951bdb2..5e65891ef5e 100644
--- a/chromium/mojo/public/cpp/bindings/lib/string_serialization.h
+++ b/chromium/mojo/public/cpp/bindings/lib/string_serialization.h
@@ -6,22 +6,65 @@
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_STRING_SERIALIZATION_H_
#include <stddef.h>
+#include <string.h>
#include "mojo/public/cpp/bindings/lib/array_internal.h"
+#include "mojo/public/cpp/bindings/lib/serialization_forward.h"
+#include "mojo/public/cpp/bindings/lib/serialization_util.h"
#include "mojo/public/cpp/bindings/string.h"
+#include "mojo/public/cpp/bindings/string_traits.h"
namespace mojo {
+namespace internal {
-size_t GetSerializedSize_(const String& input,
- internal::SerializationContext* context);
-void Serialize_(const String& input,
- internal::Buffer* buffer,
- internal::String_Data** output,
- internal::SerializationContext* context);
-bool Deserialize_(internal::String_Data* input,
- String* output,
- internal::SerializationContext* context);
+template <typename MaybeConstUserType>
+struct Serializer<String, MaybeConstUserType> {
+ using UserType = typename std::remove_const<MaybeConstUserType>::type;
+ using Traits = StringTraits<UserType>;
+ static size_t PrepareToSerialize(MaybeConstUserType& input,
+ SerializationContext* context) {
+ if (CallIsNullIfExists<Traits>(input))
+ return 0;
+
+ void* custom_context = CustomContextHelper<Traits>::SetUp(input, context);
+ return Align(sizeof(String_Data) +
+ CallWithContext(Traits::GetSize, input, custom_context));
+ }
+
+ static void Serialize(MaybeConstUserType& input,
+ Buffer* buffer,
+ String_Data** output,
+ SerializationContext* context) {
+ if (CallIsNullIfExists<Traits>(input)) {
+ *output = nullptr;
+ return;
+ }
+
+ void* custom_context = CustomContextHelper<Traits>::GetNext(context);
+
+ String_Data* result = String_Data::New(
+ CallWithContext(Traits::GetSize, input, custom_context), buffer);
+ if (result) {
+ memcpy(result->storage(),
+ CallWithContext(Traits::GetData, input, custom_context),
+ CallWithContext(Traits::GetSize, input, custom_context));
+ }
+ *output = result;
+
+ CustomContextHelper<Traits>::TearDown(input, custom_context);
+ }
+
+ static bool Deserialize(String_Data* input,
+ UserType* output,
+ SerializationContext* context) {
+ if (!input)
+ return CallSetToNullIfExists<Traits>(output);
+ return Traits::Read(StringDataView(input), output);
+ }
+};
+
+} // namespace internal
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_STRING_SERIALIZATION_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/string_traits_string16.cc b/chromium/mojo/public/cpp/bindings/lib/string_traits_string16.cc
new file mode 100644
index 00000000000..95ff6ccf257
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/string_traits_string16.cc
@@ -0,0 +1,42 @@
+// Copyright 2016 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 "mojo/public/cpp/bindings/string_traits_string16.h"
+
+#include <string>
+
+#include "base/strings/utf_string_conversions.h"
+
+namespace mojo {
+
+// static
+void* StringTraits<base::string16>::SetUpContext(const base::string16& input) {
+ return new std::string(base::UTF16ToUTF8(input));
+}
+
+// static
+void StringTraits<base::string16>::TearDownContext(const base::string16& input,
+ void* context) {
+ delete static_cast<std::string*>(context);
+}
+
+// static
+size_t StringTraits<base::string16>::GetSize(const base::string16& input,
+ void* context) {
+ return static_cast<std::string*>(context)->size();
+}
+
+// static
+const char* StringTraits<base::string16>::GetData(const base::string16& input,
+ void* context) {
+ return static_cast<std::string*>(context)->data();
+}
+
+// static
+bool StringTraits<base::string16>::Read(StringDataView input,
+ base::string16* output) {
+ return base::UTF8ToUTF16(input.storage(), input.size(), output);
+}
+
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/string_traits_wtf.cc b/chromium/mojo/public/cpp/bindings/lib/string_traits_wtf.cc
new file mode 100644
index 00000000000..19fa9074483
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/lib/string_traits_wtf.cc
@@ -0,0 +1,85 @@
+// Copyright 2016 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 "mojo/public/cpp/bindings/string_traits_wtf.h"
+
+#include <string.h>
+
+#include "base/logging.h"
+#include "mojo/public/cpp/bindings/lib/array_internal.h"
+#include "third_party/WebKit/Source/wtf/text/StringUTF8Adaptor.h"
+
+namespace mojo {
+namespace {
+
+struct UTF8AdaptorInfo {
+ explicit UTF8AdaptorInfo(const WTF::String& input) : utf8_adaptor(input) {
+#if DCHECK_IS_ON()
+ original_size_in_bytes = static_cast<size_t>(input.sizeInBytes());
+#endif
+ }
+
+ ~UTF8AdaptorInfo() {}
+
+ WTF::StringUTF8Adaptor utf8_adaptor;
+
+#if DCHECK_IS_ON()
+ // For sanity check only.
+ size_t original_size_in_bytes;
+#endif
+};
+
+UTF8AdaptorInfo* ToAdaptor(const WTF::String& input, void* context) {
+ UTF8AdaptorInfo* adaptor = static_cast<UTF8AdaptorInfo*>(context);
+
+#if DCHECK_IS_ON()
+ DCHECK_EQ(adaptor->original_size_in_bytes,
+ static_cast<size_t>(input.sizeInBytes()));
+#endif
+ return adaptor;
+}
+
+} // namespace
+
+// static
+void StringTraits<WTF::String>::SetToNull(WTF::String* output) {
+ if (output->isNull())
+ return;
+
+ WTF::String result;
+ output->swap(result);
+}
+
+// static
+void* StringTraits<WTF::String>::SetUpContext(const WTF::String& input) {
+ return new UTF8AdaptorInfo(input);
+}
+
+// static
+void StringTraits<WTF::String>::TearDownContext(const WTF::String& input,
+ void* context) {
+ delete ToAdaptor(input, context);
+}
+
+// static
+size_t StringTraits<WTF::String>::GetSize(const WTF::String& input,
+ void* context) {
+ return ToAdaptor(input, context)->utf8_adaptor.length();
+}
+
+// static
+const char* StringTraits<WTF::String>::GetData(const WTF::String& input,
+ void* context) {
+ return ToAdaptor(input, context)->utf8_adaptor.data();
+}
+
+// static
+bool StringTraits<WTF::String>::Read(StringDataView input,
+ WTF::String* output) {
+ WTF::String result = WTF::String::fromUTF8(input.storage(), input.size());
+ output->swap(result);
+ return true;
+}
+
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/sync_handle_registry.cc b/chromium/mojo/public/cpp/bindings/lib/sync_handle_registry.cc
index 3d88ec96da7..e4b49557937 100644
--- a/chromium/mojo/public/cpp/bindings/lib/sync_handle_registry.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/sync_handle_registry.cc
@@ -20,11 +20,12 @@ base::LazyInstance<base::ThreadLocalPointer<SyncHandleRegistry>>
} // namespace
// static
-SyncHandleRegistry* SyncHandleRegistry::current() {
- SyncHandleRegistry* result = g_current_sync_handle_watcher.Pointer()->Get();
+scoped_refptr<SyncHandleRegistry> SyncHandleRegistry::current() {
+ scoped_refptr<SyncHandleRegistry> result(
+ g_current_sync_handle_watcher.Pointer()->Get());
if (!result) {
result = new SyncHandleRegistry();
- DCHECK_EQ(result, g_current_sync_handle_watcher.Pointer()->Get());
+ DCHECK_EQ(result.get(), g_current_sync_handle_watcher.Pointer()->Get());
}
return result;
}
@@ -66,10 +67,8 @@ bool SyncHandleRegistry::WatchAllHandles(const bool* should_stop[],
MojoHandle ready_handle;
MojoResult ready_handle_result;
- // This object may be destroyed during a callback. So we have to preserve
- // the boolean.
- scoped_refptr<base::RefCountedData<bool>> destroyed = destroyed_;
- while (!destroyed->data) {
+ scoped_refptr<SyncHandleRegistry> preserver(this);
+ while (true) {
for (size_t i = 0; i < count; ++i)
if (*should_stop[i])
return true;
@@ -96,8 +95,7 @@ bool SyncHandleRegistry::WatchAllHandles(const bool* should_stop[],
return false;
}
-SyncHandleRegistry::SyncHandleRegistry()
- : destroyed_(new base::RefCountedData<bool>(false)) {
+SyncHandleRegistry::SyncHandleRegistry() {
MojoHandle handle;
MojoResult result = MojoCreateWaitSet(&handle);
CHECK_EQ(MOJO_RESULT_OK, result);
@@ -106,24 +104,12 @@ SyncHandleRegistry::SyncHandleRegistry()
DCHECK(!g_current_sync_handle_watcher.Pointer()->Get());
g_current_sync_handle_watcher.Pointer()->Set(this);
-
- base::MessageLoop::current()->AddDestructionObserver(this);
}
SyncHandleRegistry::~SyncHandleRegistry() {
DCHECK(thread_checker_.CalledOnValidThread());
- destroyed_->data = true;
g_current_sync_handle_watcher.Pointer()->Set(nullptr);
}
-void SyncHandleRegistry::WillDestroyCurrentMessageLoop() {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK_EQ(this, g_current_sync_handle_watcher.Pointer()->Get());
-
- base::MessageLoop::current()->RemoveDestructionObserver(this);
-
- delete this;
-}
-
} // namespace internal
} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/sync_handle_registry.h b/chromium/mojo/public/cpp/bindings/lib/sync_handle_registry.h
index df927dbb543..d6b8c38e0ce 100644
--- a/chromium/mojo/public/cpp/bindings/lib/sync_handle_registry.h
+++ b/chromium/mojo/public/cpp/bindings/lib/sync_handle_registry.h
@@ -9,7 +9,7 @@
#include "base/callback.h"
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
+#include "base/memory/ref_counted.h"
#include "base/threading/thread_checker.h"
#include "mojo/public/cpp/system/core.h"
@@ -20,10 +20,10 @@ namespace internal {
// be watched together.
//
// This class is not thread safe.
-class SyncHandleRegistry : public base::MessageLoop::DestructionObserver {
+class SyncHandleRegistry : public base::RefCounted<SyncHandleRegistry> {
public:
// Returns a thread-local object.
- static SyncHandleRegistry* current();
+ static scoped_refptr<SyncHandleRegistry> current();
using HandleCallback = base::Callback<void(MojoResult)>;
bool RegisterHandle(const Handle& handle,
@@ -40,6 +40,8 @@ class SyncHandleRegistry : public base::MessageLoop::DestructionObserver {
bool WatchAllHandles(const bool* should_stop[], size_t count);
private:
+ friend class base::RefCounted<SyncHandleRegistry>;
+
struct HandleHasher {
size_t operator()(const Handle& handle) const {
return std::hash<uint32_t>()(static_cast<uint32_t>(handle.value()));
@@ -48,17 +50,12 @@ class SyncHandleRegistry : public base::MessageLoop::DestructionObserver {
using HandleMap = std::unordered_map<Handle, HandleCallback, HandleHasher>;
SyncHandleRegistry();
- ~SyncHandleRegistry() override;
-
- // base::MessageLoop::DestructionObserver implementation:
- void WillDestroyCurrentMessageLoop() override;
+ ~SyncHandleRegistry();
HandleMap handles_;
ScopedHandle wait_set_handle_;
- scoped_refptr<base::RefCountedData<bool>> destroyed_;
-
base::ThreadChecker thread_checker_;
DISALLOW_COPY_AND_ASSIGN(SyncHandleRegistry);
diff --git a/chromium/mojo/public/cpp/bindings/lib/sync_handle_watcher.cc b/chromium/mojo/public/cpp/bindings/lib/sync_handle_watcher.cc
index e259578634b..44092038e78 100644
--- a/chromium/mojo/public/cpp/bindings/lib/sync_handle_watcher.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/sync_handle_watcher.cc
@@ -18,12 +18,13 @@ SyncHandleWatcher::SyncHandleWatcher(
callback_(callback),
registered_(false),
register_request_count_(0),
+ registry_(SyncHandleRegistry::current()),
destroyed_(new base::RefCountedData<bool>(false)) {}
SyncHandleWatcher::~SyncHandleWatcher() {
DCHECK(thread_checker_.CalledOnValidThread());
if (registered_)
- SyncHandleRegistry::current()->UnregisterHandle(handle_);
+ registry_->UnregisterHandle(handle_);
destroyed_->data = true;
}
@@ -45,8 +46,7 @@ bool SyncHandleWatcher::SyncWatch(const bool* should_stop) {
// to preserve the boolean that WatchAllHandles uses.
auto destroyed = destroyed_;
const bool* should_stop_array[] = {should_stop, &destroyed->data};
- bool result =
- SyncHandleRegistry::current()->WatchAllHandles(should_stop_array, 2);
+ bool result = registry_->WatchAllHandles(should_stop_array, 2);
// This object has been destroyed.
if (destroyed->data)
@@ -59,8 +59,8 @@ bool SyncHandleWatcher::SyncWatch(const bool* should_stop) {
void SyncHandleWatcher::IncrementRegisterCount() {
register_request_count_++;
if (!registered_) {
- registered_ = SyncHandleRegistry::current()->RegisterHandle(
- handle_, handle_signals_, callback_);
+ registered_ =
+ registry_->RegisterHandle(handle_, handle_signals_, callback_);
}
}
@@ -69,7 +69,7 @@ void SyncHandleWatcher::DecrementRegisterCount() {
register_request_count_--;
if (register_request_count_ == 0 && registered_) {
- SyncHandleRegistry::current()->UnregisterHandle(handle_);
+ registry_->UnregisterHandle(handle_);
registered_ = false;
}
}
diff --git a/chromium/mojo/public/cpp/bindings/lib/sync_handle_watcher.h b/chromium/mojo/public/cpp/bindings/lib/sync_handle_watcher.h
index 8d4fd5510a5..93d527bdc83 100644
--- a/chromium/mojo/public/cpp/bindings/lib/sync_handle_watcher.h
+++ b/chromium/mojo/public/cpp/bindings/lib/sync_handle_watcher.h
@@ -61,6 +61,8 @@ class SyncHandleWatcher {
// If non-zero, |handle_| should be registered with SyncHandleRegistry.
size_t register_request_count_;
+ scoped_refptr<SyncHandleRegistry> registry_;
+
scoped_refptr<base::RefCountedData<bool>> destroyed_;
base::ThreadChecker thread_checker_;
diff --git a/chromium/mojo/public/cpp/bindings/lib/validate_params.h b/chromium/mojo/public/cpp/bindings/lib/validate_params.h
index 78c05892f4f..2509b6bb0a6 100644
--- a/chromium/mojo/public/cpp/bindings/lib/validate_params.h
+++ b/chromium/mojo/public/cpp/bindings/lib/validate_params.h
@@ -12,6 +12,8 @@
namespace mojo {
namespace internal {
+using ValidateEnumFunc = bool (*)(int32_t);
+
class ArrayValidateParams {
public:
// ArrayValidateParams takes ownership of |in_element_validate params|.
@@ -20,15 +22,22 @@ class ArrayValidateParams {
ArrayValidateParams* in_element_validate_params)
: expected_num_elements(in_expected_num_elements),
element_is_nullable(in_element_is_nullable),
- element_validate_params(in_element_validate_params) {}
+ element_validate_params(in_element_validate_params),
+ validate_enum_func(nullptr) {}
+
+ // Validates an array of enums.
+ ArrayValidateParams(uint32_t in_expected_num_elements,
+ ValidateEnumFunc in_validate_enum_func)
+ : expected_num_elements(in_expected_num_elements),
+ element_is_nullable(false),
+ element_validate_params(nullptr),
+ validate_enum_func(in_validate_enum_func) {}
~ArrayValidateParams() {
if (element_validate_params)
delete element_validate_params;
}
- // TODO(vtl): The members of this class shouldn't be public.
-
// If |expected_num_elements| is not 0, the array is expected to have exactly
// that number of elements.
uint32_t expected_num_elements;
@@ -41,6 +50,9 @@ class ArrayValidateParams {
// nullptr. In the case of maps, this is used to validate the value array.
ArrayValidateParams* element_validate_params;
+ // Validation function for enum elements.
+ ValidateEnumFunc validate_enum_func;
+
private:
DISALLOW_COPY_AND_ASSIGN(ArrayValidateParams);
};
diff --git a/chromium/mojo/public/cpp/bindings/lib/validation_util.cc b/chromium/mojo/public/cpp/bindings/lib/validation_util.cc
index 70dcb29c5e2..28d52884cdc 100644
--- a/chromium/mojo/public/cpp/bindings/lib/validation_util.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/validation_util.cc
@@ -8,8 +8,8 @@
#include <limits>
-#include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
#include "mojo/public/cpp/bindings/lib/message_internal.h"
+#include "mojo/public/cpp/bindings/lib/serialization_util.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
#include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h"
@@ -52,6 +52,26 @@ bool ValidateStructHeaderAndClaimMemory(const void* data,
return true;
}
+bool ValidateUnionHeaderAndClaimMemory(const void* data,
+ bool inlined,
+ BoundsChecker* bounds_checker) {
+ if (!IsAligned(data)) {
+ ReportValidationError(VALIDATION_ERROR_MISALIGNED_OBJECT);
+ return false;
+ }
+
+ // If the union is inlined in another structure its memory was already
+ // claimed.
+ // This ONLY applies to the union itself, NOT anything which the union points
+ // to.
+ if (!inlined && !bounds_checker->ClaimMemory(data, kUnionDataSize)) {
+ ReportValidationError(VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
+ return false;
+ }
+
+ return true;
+}
+
bool ValidateMessageIsRequestWithoutResponse(const Message* message) {
if (message->has_flag(kMessageIsResponse) ||
message->has_flag(kMessageExpectsResponse)) {
@@ -101,8 +121,9 @@ bool ValidateControlResponse(const Message* message) {
return false;
}
-bool ValidateHandleNonNullable(const Handle& input, const char* error_message) {
- if (input.value() != kEncodedInvalidHandleValue)
+bool ValidateHandleNonNullable(const Handle_Data& input,
+ const char* error_message) {
+ if (input.is_valid())
return true;
ReportValidationError(VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
@@ -120,7 +141,7 @@ bool ValidateInterfaceIdNonNullable(InterfaceId input,
return false;
}
-bool ValidateHandle(const Handle& input, BoundsChecker* bounds_checker) {
+bool ValidateHandle(const Handle_Data& input, BoundsChecker* bounds_checker) {
if (bounds_checker->ClaimHandle(input))
return true;
diff --git a/chromium/mojo/public/cpp/bindings/lib/validation_util.h b/chromium/mojo/public/cpp/bindings/lib/validation_util.h
index 5314a362702..6189ffda40b 100644
--- a/chromium/mojo/public/cpp/bindings/lib/validation_util.h
+++ b/chromium/mojo/public/cpp/bindings/lib/validation_util.h
@@ -9,6 +9,7 @@
#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
#include "mojo/public/cpp/bindings/lib/bounds_checker.h"
+#include "mojo/public/cpp/bindings/lib/serialization_util.h"
#include "mojo/public/cpp/bindings/lib/validate_params.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
#include "mojo/public/cpp/bindings/message.h"
@@ -30,6 +31,14 @@ bool ValidateEncodedPointer(const uint64_t* offset);
bool ValidateStructHeaderAndClaimMemory(const void* data,
BoundsChecker* bounds_checker);
+// Validates that |data| contains a valid union header, in terms of alignment
+// and size. If not inlined, it checks that the memory range
+// [data, data + num_bytes) is not marked as occupied by other objects in
+// |bounds_checker|. On success, the memory range is marked as occupied.
+bool ValidateUnionHeaderAndClaimMemory(const void* data,
+ bool inlined,
+ BoundsChecker* bounds_checker);
+
// Validates that the message is a request which doesn't expect a response.
bool ValidateMessageIsRequestWithoutResponse(const Message* message);
// Validates that the message is a request expecting a response.
@@ -73,13 +82,14 @@ bool ValidateInlinedUnionNonNullable(const T& input,
return false;
}
-bool ValidateHandleNonNullable(const Handle& input, const char* error_message);
+bool ValidateHandleNonNullable(const Handle_Data& input,
+ const char* error_message);
bool ValidateInterfaceIdNonNullable(InterfaceId input,
const char* error_message);
template <typename T>
-bool ValidateArray(const ArrayPointer<T>& input,
+bool ValidateArray(const Pointer<Array_Data<T>>& input,
BoundsChecker* bounds_checker,
const ArrayValidateParams* validate_params) {
if (!ValidateEncodedPointer(&input.offset)) {
@@ -92,7 +102,7 @@ bool ValidateArray(const ArrayPointer<T>& input,
}
template <typename T>
-bool ValidateMap(const StructPointer<T>& input,
+bool ValidateMap(const Pointer<T>& input,
BoundsChecker* bounds_checker,
const ArrayValidateParams* value_validate_params) {
if (!ValidateEncodedPointer(&input.offset)) {
@@ -105,8 +115,7 @@ bool ValidateMap(const StructPointer<T>& input,
}
template <typename T>
-bool ValidateStruct(const StructPointer<T>& input,
- BoundsChecker* bounds_checker) {
+bool ValidateStruct(const Pointer<T>& input, BoundsChecker* bounds_checker) {
if (!ValidateEncodedPointer(&input.offset)) {
ReportValidationError(VALIDATION_ERROR_ILLEGAL_POINTER);
return false;
@@ -120,25 +129,21 @@ bool ValidateInlinedUnion(const T& input, BoundsChecker* bounds_checker) {
return T::Validate(&input, bounds_checker, true);
}
-bool ValidateHandle(const Handle& input, BoundsChecker* bounds_checker);
-
-bool ValidateAssociatedInterfaceId(InterfaceId input);
-
-// Checks whether the given enum value is valid. Please note that any value is
-// valid for an extensible enum, although it may be from a newer version and
-// thus unknown.
template <typename T>
-bool ValidateEnum(const T& input) {
- if (T::kIsExtensible)
- return true;
-
- if (T::IsKnownValue(input.value))
- return true;
+bool ValidateNonInlinedUnion(const Pointer<T>& input,
+ BoundsChecker* bounds_checker) {
+ if (!ValidateEncodedPointer(&input.offset)) {
+ ReportValidationError(VALIDATION_ERROR_ILLEGAL_POINTER);
+ return false;
+ }
- ReportValidationError(VALIDATION_ERROR_UNKNOWN_ENUM_VALUE);
- return false;
+ return T::Validate(DecodePointerRaw(&input.offset), bounds_checker, false);
}
+bool ValidateHandle(const Handle_Data& input, BoundsChecker* bounds_checker);
+
+bool ValidateAssociatedInterfaceId(InterfaceId input);
+
} // namespace internal
} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/lib/wtf_array_serialization.h b/chromium/mojo/public/cpp/bindings/lib/wtf_array_serialization.h
deleted file mode 100644
index 70edbf1fe6b..00000000000
--- a/chromium/mojo/public/cpp/bindings/lib/wtf_array_serialization.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2016 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_BINDINGS_LIB_WTF_ARRAY_SERIALIZATION_H_
-#define MOJO_PUBLIC_CPP_BINDINGS_LIB_WTF_ARRAY_SERIALIZATION_H_
-
-#include <stddef.h>
-
-#include "mojo/public/cpp/bindings/lib/array_serialization_traits.h"
-#include "mojo/public/cpp/bindings/wtf_array.h"
-
-namespace mojo {
-
-template <typename E>
-inline size_t GetSerializedSize_(const WTFArray<E>& input,
- internal::SerializationContext* context) {
- return internal::ArraySerializationImpl<WTFArray<E>>::GetSerializedSize(
- input, context);
-}
-
-template <typename E, typename F>
-inline void SerializeArray_(
- WTFArray<E> input,
- internal::Buffer* buf,
- internal::Array_Data<F>** output,
- const internal::ArrayValidateParams* validate_params,
- internal::SerializationContext* context) {
- return internal::ArraySerializationImpl<WTFArray<E>>::template Serialize<F>(
- std::move(input), buf, output, validate_params, context);
-}
-
-template <typename E, typename F>
-inline bool Deserialize_(internal::Array_Data<F>* input,
- WTFArray<E>* output,
- internal::SerializationContext* context) {
- return internal::ArraySerializationImpl<WTFArray<E>>::template Deserialize<F>(
- input, output, context);
-}
-
-} // namespace mojo
-
-#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_WTF_ARRAY_SERIALIZATION_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/wtf_serialization.h b/chromium/mojo/public/cpp/bindings/lib/wtf_serialization.h
index 318d1522231..dbb3f9edbca 100644
--- a/chromium/mojo/public/cpp/bindings/lib/wtf_serialization.h
+++ b/chromium/mojo/public/cpp/bindings/lib/wtf_serialization.h
@@ -5,7 +5,8 @@
#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_WTF_SERIALIZATION_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_WTF_SERIALIZATION_H_
-#include "mojo/public/cpp/bindings/lib/wtf_array_serialization.h"
-#include "mojo/public/cpp/bindings/lib/wtf_string_serialization.h"
+#include "mojo/public/cpp/bindings/array_traits_wtf.h"
+#include "mojo/public/cpp/bindings/array_traits_wtf_vector.h"
+#include "mojo/public/cpp/bindings/string_traits_wtf.h"
#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_WTF_SERIALIZATION_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/wtf_string_serialization.cc b/chromium/mojo/public/cpp/bindings/lib/wtf_string_serialization.cc
deleted file mode 100644
index febd073ff5e..00000000000
--- a/chromium/mojo/public/cpp/bindings/lib/wtf_string_serialization.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2016 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 "mojo/public/cpp/bindings/lib/wtf_string_serialization.h"
-
-#include <string.h>
-
-#include <queue>
-
-#include "base/logging.h"
-#include "third_party/WebKit/Source/wtf/text/StringUTF8Adaptor.h"
-#include "third_party/WebKit/Source/wtf/text/WTFString.h"
-
-namespace WTF {
-namespace {
-
-struct UTF8AdaptorInfo {
- explicit UTF8AdaptorInfo(const WTF::String& input) : utf8_adaptor(input) {
-#if DCHECK_IS_ON()
- original_size_in_bytes = static_cast<size_t>(input.sizeInBytes());
-#endif
- }
-
- ~UTF8AdaptorInfo() {}
-
- WTF::StringUTF8Adaptor utf8_adaptor;
-
-#if DCHECK_IS_ON()
- // For sanity check only.
- size_t original_size_in_bytes;
-#endif
-};
-
-class WTFStringContextImpl : public mojo::internal::WTFStringContext {
- public:
- WTFStringContextImpl() {}
- ~WTFStringContextImpl() override {}
-
- std::queue<UTF8AdaptorInfo>& utf8_adaptors() { return utf8_adaptors_; }
-
- private:
- // When serializing an object, we call GetSerializedSize_() recursively on
- // all its elements/members to compute the total size, and then call
- // Serialize*_() recursively in the same order to do the actual
- // serialization. If some WTF::Strings need to be converted to UTF8, we don't
- // want to do that twice. Therefore, we store a WTF::StringUTF8Adaptor for
- // each in the first pass, and reuse it in the second pass.
- std::queue<UTF8AdaptorInfo> utf8_adaptors_;
-
- DISALLOW_COPY_AND_ASSIGN(WTFStringContextImpl);
-};
-
-} // namespace
-
-size_t GetSerializedSize_(const WTF::String& input,
- mojo::internal::SerializationContext* context) {
- if (input.isNull())
- return 0;
-
- if (!context->wtf_string_context)
- context->wtf_string_context.reset(new WTFStringContextImpl);
-
- auto& utf8_adaptors =
- static_cast<WTFStringContextImpl*>(context->wtf_string_context.get())
- ->utf8_adaptors();
-
- utf8_adaptors.emplace(input);
-
- return mojo::internal::Align(sizeof(mojo::internal::String_Data) +
- utf8_adaptors.back().utf8_adaptor.length());
-}
-
-void Serialize_(const WTF::String& input,
- mojo::internal::Buffer* buf,
- mojo::internal::String_Data** output,
- mojo::internal::SerializationContext* context) {
- if (input.isNull()) {
- *output = nullptr;
- return;
- }
-
- auto& utf8_adaptors =
- static_cast<WTFStringContextImpl*>(context->wtf_string_context.get())
- ->utf8_adaptors();
-
- DCHECK(!utf8_adaptors.empty());
-#if DCHECK_IS_ON()
- DCHECK_EQ(utf8_adaptors.front().original_size_in_bytes,
- static_cast<size_t>(input.sizeInBytes()));
-#endif
-
- const WTF::StringUTF8Adaptor& adaptor = utf8_adaptors.front().utf8_adaptor;
-
- mojo::internal::String_Data* result =
- mojo::internal::String_Data::New(adaptor.length(), buf);
- if (result)
- memcpy(result->storage(), adaptor.data(), adaptor.length());
-
- utf8_adaptors.pop();
-
- *output = result;
-}
-
-bool Deserialize_(mojo::internal::String_Data* input,
- WTF::String* output,
- mojo::internal::SerializationContext* context) {
- if (input) {
- WTF::String result = WTF::String::fromUTF8(input->storage(), input->size());
- output->swap(result);
- } else if (!output->isNull()) {
- WTF::String result;
- output->swap(result);
- }
- return true;
-}
-
-} // namespace WTF
diff --git a/chromium/mojo/public/cpp/bindings/lib/wtf_string_serialization.h b/chromium/mojo/public/cpp/bindings/lib/wtf_string_serialization.h
deleted file mode 100644
index a1102654dcd..00000000000
--- a/chromium/mojo/public/cpp/bindings/lib/wtf_string_serialization.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 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_BINDINGS_LIB_WTF_STRING_SERIALIZATION_H_
-#define MOJO_PUBLIC_CPP_BINDINGS_LIB_WTF_STRING_SERIALIZATION_H_
-
-#include <stddef.h>
-
-#include "mojo/public/cpp/bindings/lib/array_internal.h"
-#include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
-
-namespace WTF {
-class String;
-
-size_t GetSerializedSize_(const WTF::String& input,
- mojo::internal::SerializationContext* context);
-void Serialize_(const WTF::String& input,
- mojo::internal::Buffer* buffer,
- mojo::internal::String_Data** output,
- mojo::internal::SerializationContext* context);
-bool Deserialize_(mojo::internal::String_Data* input,
- WTF::String* output,
- mojo::internal::SerializationContext* context);
-
-} // namespace WTF
-
-#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_WTF_STRING_SERIALIZATION_H_
diff --git a/chromium/mojo/public/cpp/bindings/map.h b/chromium/mojo/public/cpp/bindings/map.h
index 6d0d57d6793..f1cdd41ae7c 100644
--- a/chromium/mojo/public/cpp/bindings/map.h
+++ b/chromium/mojo/public/cpp/bindings/map.h
@@ -24,20 +24,23 @@ namespace mojo {
// - There can only be one entry per unique key.
// - Values of move-only types will be moved into the Map when they are added
// using the insert() method.
-template <typename Key, typename Value>
+template <typename K, typename V>
class Map {
MOVE_ONLY_TYPE_FOR_CPP_03(Map);
public:
+ using Key = K;
+ using Value = V;
+
// Map keys cannot be move only classes.
static_assert(!internal::IsMoveOnlyType<Key>::value,
"Map keys cannot be move only types.");
using ConstIterator = typename std::map<Key, Value>::const_iterator;
- using Data_ =
- internal::Map_Data<typename internal::WrapperTraits<Key>::DataType,
- typename internal::WrapperTraits<Value>::DataType>;
+ using Data_ = internal::Map_Data<
+ typename internal::GetDataTypeAsArrayElement<Key>::Data,
+ typename internal::GetDataTypeAsArrayElement<Value>::Data>;
// Constructs an empty map.
Map() : is_null_(false) {}
diff --git a/chromium/mojo/public/cpp/bindings/message.h b/chromium/mojo/public/cpp/bindings/message.h
index 51636693c71..d8eed2bfc3e 100644
--- a/chromium/mojo/public/cpp/bindings/message.h
+++ b/chromium/mojo/public/cpp/bindings/message.h
@@ -9,12 +9,13 @@
#include <stdint.h>
#include <limits>
+#include <memory>
#include <vector>
#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
+#include "mojo/public/cpp/bindings/lib/message_buffer.h"
#include "mojo/public/cpp/bindings/lib/message_internal.h"
-#include "mojo/public/cpp/bindings/lib/pickle_buffer.h"
+#include "mojo/public/cpp/system/message.h"
namespace mojo {
@@ -27,15 +28,18 @@ class Message {
Message();
~Message();
+ // Initializes a Message with enough space for |capacity| bytes.
void Initialize(size_t capacity, bool zero_initialized);
+ // Initializes a Message from an existing Mojo MessageHandle.
+ void InitializeFromMojoMessage(ScopedMessageHandle message,
+ uint32_t num_bytes,
+ std::vector<Handle>* handles);
+
// Transfers data and handles to |destination|.
void MoveTo(Message* destination);
- uint32_t data_num_bytes() const {
- DCHECK(buffer_->data_num_bytes() <= std::numeric_limits<uint32_t>::max());
- return static_cast<uint32_t>(buffer_->data_num_bytes());
- }
+ uint32_t data_num_bytes() const { return buffer_->data_num_bytes(); }
// Access the raw bytes of the message.
const uint8_t* data() const {
@@ -90,10 +94,15 @@ class Message {
// Access the underlying Buffer interface.
internal::Buffer* buffer() { return buffer_.get(); }
+ // Takes a scoped MessageHandle which may be passed to |WriteMessageNew()| for
+ // transmission. Note that this invalidates this Message object, taking
+ // ownership of its internal storage and any attached handles.
+ ScopedMessageHandle TakeMojoMessage();
+
private:
void CloseHandles();
- scoped_ptr<internal::PickleBuffer> buffer_;
+ std::unique_ptr<internal::MessageBuffer> buffer_;
std::vector<Handle> handles_;
DISALLOW_COPY_AND_ASSIGN(Message);
@@ -122,7 +131,8 @@ class MessageReceiverWithResponder : public MessageReceiver {
// |responder| and will delete it after calling |responder->Accept| or upon
// its own destruction.
//
- // TODO(yzshen): consider changing |responder| to scoped_ptr<MessageReceiver>.
+ // TODO(yzshen): consider changing |responder| to
+ // std::unique_ptr<MessageReceiver>.
virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder)
WARN_UNUSED_RESULT = 0;
};
@@ -160,7 +170,8 @@ class MessageReceiverWithResponderStatus : public MessageReceiver {
// |responder| and will delete it after calling |responder->Accept| or upon
// its own destruction.
//
- // TODO(yzshen): consider changing |responder| to scoped_ptr<MessageReceiver>.
+ // TODO(yzshen): consider changing |responder| to
+ // std::unique_ptr<MessageReceiver>.
virtual bool AcceptWithResponder(Message* message,
MessageReceiverWithStatus* responder)
WARN_UNUSED_RESULT = 0;
diff --git a/chromium/mojo/public/cpp/bindings/native_struct.h b/chromium/mojo/public/cpp/bindings/native_struct.h
new file mode 100644
index 00000000000..882c970ce25
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/native_struct.h
@@ -0,0 +1,47 @@
+// Copyright 2016 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_BINDINGS_NATIVE_STRUCT_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_NATIVE_STRUCT_H_
+
+#include "mojo/public/cpp/bindings/array.h"
+#include "mojo/public/cpp/bindings/lib/native_struct_data.h"
+#include "mojo/public/cpp/bindings/struct_ptr.h"
+#include "mojo/public/cpp/bindings/type_converter.h"
+
+namespace mojo {
+
+class NativeStruct;
+using NativeStructPtr = StructPtr<NativeStruct>;
+
+// Native-only structs correspond to "[Native] struct Foo;" definitions in
+// mojom.
+class NativeStruct {
+ public:
+ using Data_ = internal::NativeStruct_Data;
+
+ static NativeStructPtr New();
+
+ template <typename U>
+ static NativeStructPtr From(const U& u) {
+ return TypeConverter<NativeStructPtr, U>::Convert(u);
+ }
+
+ template <typename U>
+ U To() const {
+ return TypeConverter<U, NativeStruct>::Convert(*this);
+ }
+
+ NativeStruct();
+ ~NativeStruct();
+
+ NativeStructPtr Clone() const;
+ bool Equals(const NativeStruct& other) const;
+
+ Array<uint8_t> data;
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_NATIVE_STRUCT_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h b/chromium/mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h
index cb941812071..d13676470f0 100644
--- a/chromium/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h
+++ b/chromium/mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_SCOPED_INTERFACE_ENDPOINT_HANDLE_H_
-#define MOJO_PUBLIC_CPP_BINDINGS_LIB_SCOPED_INTERFACE_ENDPOINT_HANDLE_H_
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_SCOPED_INTERFACE_ENDPOINT_HANDLE_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_SCOPED_INTERFACE_ENDPOINT_HANDLE_H_
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -11,9 +11,10 @@
#include "mojo/public/cpp/bindings/lib/interface_id.h"
namespace mojo {
-namespace internal {
+namespace internal {
class MultiplexRouter;
+}
// ScopedInterfaceEndpointHandle refers to one end of an interface, either the
// implementation side or the client side.
@@ -24,14 +25,6 @@ class ScopedInterfaceEndpointHandle {
// Creates an invalid endpoint handle.
ScopedInterfaceEndpointHandle();
- // This is supposed to be used by MultiplexRouter only.
- // |id| is the corresponding interface ID.
- // If |is_local| is false, this handle is meant to be passed over |router| to
- // the remote side.
- ScopedInterfaceEndpointHandle(InterfaceId id,
- bool is_local,
- scoped_refptr<MultiplexRouter> router);
-
ScopedInterfaceEndpointHandle(ScopedInterfaceEndpointHandle&& other);
~ScopedInterfaceEndpointHandle();
@@ -39,25 +32,39 @@ class ScopedInterfaceEndpointHandle {
ScopedInterfaceEndpointHandle& operator=(
ScopedInterfaceEndpointHandle&& other);
- bool is_valid() const { return IsValidInterfaceId(id_); }
+ bool is_valid() const { return internal::IsValidInterfaceId(id_); }
- InterfaceId id() const { return id_; }
bool is_local() const { return is_local_; }
- MultiplexRouter* router() const { return router_.get(); }
void reset();
void swap(ScopedInterfaceEndpointHandle& other);
+ // DO NOT USE METHODS BELOW THIS LINE. These are for internal use and testing.
+
+ internal::InterfaceId id() const { return id_; }
+
+ internal::MultiplexRouter* router() const { return router_.get(); }
+
// Releases the handle without closing it.
- InterfaceId release();
+ internal::InterfaceId release();
private:
- InterfaceId id_;
+ friend class internal::MultiplexRouter;
+
+ // This is supposed to be used by MultiplexRouter only.
+ // |id| is the corresponding interface ID.
+ // If |is_local| is false, this handle is meant to be passed over |router| to
+ // the remote side.
+ ScopedInterfaceEndpointHandle(
+ internal::InterfaceId id,
+ bool is_local,
+ scoped_refptr<internal::MultiplexRouter> router);
+
+ internal::InterfaceId id_;
bool is_local_;
- scoped_refptr<MultiplexRouter> router_;
+ scoped_refptr<internal::MultiplexRouter> router_;
};
-} // namespace internal
} // namespace mojo
-#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SCOPED_INTERFACE_ENDPOINT_HANDLE_H_
+#endif // MOJO_PUBLIC_CPP_BINDINGS_SCOPED_INTERFACE_ENDPOINT_HANDLE_H_
diff --git a/chromium/mojo/public/cpp/bindings/string_traits.h b/chromium/mojo/public/cpp/bindings/string_traits.h
new file mode 100644
index 00000000000..a6ade6fdf68
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/string_traits.h
@@ -0,0 +1,69 @@
+// Copyright 2016 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_BINDINGS_STRING_TRAITS_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_STRING_TRAITS_H_
+
+#include "base/logging.h"
+#include "mojo/public/cpp/bindings/lib/array_internal.h"
+
+namespace mojo {
+
+// Access to the contents of a serialized string.
+class StringDataView {
+ public:
+ explicit StringDataView(internal::String_Data* data) : data_(data) {
+ DCHECK(data_);
+ }
+
+ const char* storage() const { return data_->storage(); }
+
+ size_t size() const { return data_->size(); }
+
+ private:
+ internal::String_Data* data_;
+};
+
+// This must be specialized for any type |T| to be serialized/deserialized as
+// a mojom string.
+//
+// Imagine you want to specialize it for CustomString, usually you need to
+// implement:
+//
+// template <T>
+// struct StringTraits<CustomString> {
+// // These two methods are optional. Please see comments in struct_traits.h
+// static bool IsNull(const CustomString& input);
+// static void SetToNull(CustomString* output);
+//
+// static size_t GetSize(const CustomString& input);
+// static const char* GetData(const CustomString& input);
+//
+// static bool Read(StringDataView input, CustomString* output);
+// };
+//
+// In some cases, you may need to do conversion before you can return the size
+// and data as 8-bit characters for serialization. (For example, CustomString is
+// UTF-16 string). In that case, you can add two optional methods:
+//
+// static void* SetUpContext(const CustomString& input);
+// static void TearDownContext(const CustomString& input, void* context);
+//
+// And then you append a second parameter, void* context, to GetSize() and
+// GetData():
+//
+// static size_t GetSize(const CustomString& input, void* context);
+// static const char* GetData(const CustomString& input, void* context);
+//
+// If a CustomString instance is not null, the serialization code will call
+// SetUpContext() at the beginning, and pass the resulting context pointer to
+// GetSize()/GetData(). After serialization is done, it calls TearDownContext()
+// so that you can do any necessary cleanup.
+//
+template <typename T>
+struct StringTraits;
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_STRING_TRAITS_H_
diff --git a/chromium/mojo/public/cpp/bindings/string_traits_standard.h b/chromium/mojo/public/cpp/bindings/string_traits_standard.h
new file mode 100644
index 00000000000..9b78d2473ec
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/string_traits_standard.h
@@ -0,0 +1,31 @@
+// Copyright 2016 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_BINDINGS_STRING_TRAITS_STANDARD_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_STRING_TRAITS_STANDARD_H_
+
+#include "mojo/public/cpp/bindings/string.h"
+#include "mojo/public/cpp/bindings/string_traits.h"
+
+namespace mojo {
+
+template <>
+struct StringTraits<String> {
+ static bool IsNull(const String& input) { return input.is_null(); }
+ static void SetToNull(String* output) { *output = nullptr; }
+
+ static size_t GetSize(const String& input) { return input.size(); }
+
+ static const char* GetData(const String& input) { return input.data(); }
+
+ static bool Read(StringDataView input, String* output) {
+ String result(input.storage(), input.size());
+ result.Swap(output);
+ return true;
+ }
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_STRING_TRAITS_STANDARD_H_
diff --git a/chromium/mojo/public/cpp/bindings/string_traits_stl.h b/chromium/mojo/public/cpp/bindings/string_traits_stl.h
new file mode 100644
index 00000000000..f6cc8ad098f
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/string_traits_stl.h
@@ -0,0 +1,38 @@
+// Copyright 2016 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_BINDINGS_STRING_TRAITS_STL_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_STRING_TRAITS_STL_H_
+
+#include <string>
+
+#include "mojo/public/cpp/bindings/string_traits.h"
+
+namespace mojo {
+
+template <>
+struct StringTraits<std::string> {
+ static bool IsNull(const std::string& input) {
+ // std::string is always converted to non-null mojom string.
+ return false;
+ }
+
+ static void SetToNull(std::string* output) {
+ // std::string doesn't support null state. Set it to empty instead.
+ output->clear();
+ }
+
+ static size_t GetSize(const std::string& input) { return input.size(); }
+
+ static const char* GetData(const std::string& input) { return input.data(); }
+
+ static bool Read(StringDataView input, std::string* output) {
+ output->assign(input.storage(), input.size());
+ return true;
+ }
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_STRING_TRAITS_STL_H_
diff --git a/chromium/mojo/public/cpp/bindings/string_traits_string16.h b/chromium/mojo/public/cpp/bindings/string_traits_string16.h
new file mode 100644
index 00000000000..5a089080bd0
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/string_traits_string16.h
@@ -0,0 +1,36 @@
+// Copyright 2016 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_BINDINGS_STRING_TRAITS_STRING16_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_STRING_TRAITS_STRING16_H_
+
+#include "base/strings/string16.h"
+#include "mojo/public/cpp/bindings/string_traits.h"
+
+namespace mojo {
+
+template <>
+struct StringTraits<base::string16> {
+ static bool IsNull(const base::string16& input) {
+ // base::string16 is always converted to non-null mojom string.
+ return false;
+ }
+
+ static void SetToNull(base::string16* output) {
+ // Convert null to an "empty" base::string16.
+ output->clear();
+ }
+
+ static void* SetUpContext(const base::string16& input);
+ static void TearDownContext(const base::string16& input, void* context);
+
+ static size_t GetSize(const base::string16& input, void* context);
+ static const char* GetData(const base::string16& input, void* context);
+
+ static bool Read(StringDataView input, base::string16* output);
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_STRING_TRAITS_STRING16_H_
diff --git a/chromium/mojo/public/cpp/bindings/string_traits_string_piece.h b/chromium/mojo/public/cpp/bindings/string_traits_string_piece.h
new file mode 100644
index 00000000000..af6be893ac0
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/string_traits_string_piece.h
@@ -0,0 +1,43 @@
+// Copyright 2016 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_BINDINGS_STRING_TRAITS_STRING_PIECE_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_STRING_TRAITS_STRING_PIECE_H_
+
+#include "base/strings/string_piece.h"
+#include "mojo/public/cpp/bindings/string_traits.h"
+
+namespace mojo {
+
+template <>
+struct StringTraits<base::StringPiece> {
+ static bool IsNull(const base::StringPiece& input) {
+ // base::StringPiece is always converted to non-null mojom string. We could
+ // have let StringPiece containing a null data pointer map to null mojom
+ // string, but StringPiece::empty() returns true in this case. It seems
+ // confusing to mix the concept of empty and null strings, especially
+ // because they mean different things in mojom.
+ return false;
+ }
+
+ static void SetToNull(base::StringPiece* output) {
+ // Convert null to an "empty" base::StringPiece.
+ output->set(nullptr, 0);
+ }
+
+ static size_t GetSize(const base::StringPiece& input) { return input.size(); }
+
+ static const char* GetData(const base::StringPiece& input) {
+ return input.data();
+ }
+
+ static bool Read(StringDataView input, base::StringPiece* output) {
+ output->set(input.storage(), input.size());
+ return true;
+ }
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_STRING_TRAITS_STRING_PIECE_H_
diff --git a/chromium/mojo/public/cpp/bindings/string_traits_wtf.h b/chromium/mojo/public/cpp/bindings/string_traits_wtf.h
new file mode 100644
index 00000000000..238c2eb1199
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/string_traits_wtf.h
@@ -0,0 +1,31 @@
+// Copyright 2016 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_BINDINGS_STRING_TRAITS_WTF_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_STRING_TRAITS_WTF_H_
+
+#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
+#include "mojo/public/cpp/bindings/string_traits.h"
+#include "third_party/WebKit/Source/wtf/text/WTFString.h"
+
+namespace mojo {
+
+template <>
+struct StringTraits<WTF::String> {
+ static bool IsNull(const WTF::String& input) { return input.isNull(); }
+ static void SetToNull(WTF::String* output);
+
+ static void* SetUpContext(const WTF::String& input);
+ static void TearDownContext(const WTF::String& input, void* context);
+
+ static size_t GetSize(const WTF::String& input, void* context);
+
+ static const char* GetData(const WTF::String& input, void* context);
+
+ static bool Read(StringDataView input, WTF::String* output);
+};
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_STRING_TRAITS_WTF_H_
diff --git a/chromium/mojo/public/cpp/bindings/struct_traits.h b/chromium/mojo/public/cpp/bindings/struct_traits.h
index fb7290b20ab..ee9a336ba18 100644
--- a/chromium/mojo/public/cpp/bindings/struct_traits.h
+++ b/chromium/mojo/public/cpp/bindings/struct_traits.h
@@ -10,22 +10,97 @@ namespace mojo {
// This must be specialized for any type |T| to be serialized/deserialized as
// a mojom struct of type |MojomType|.
//
-// Each specialization must implement a few things:
-//
+// Each specialization needs to implement a few things:
// 1. Static getters for each field in the Mojom type. These should be
// of the form:
//
-// static <return type> <field name>(const T&)
+// static <return type> <field name>(const T& input);
//
// and should return a serializable form of the named field as extracted
-// from the referenced |T| instance.
+// from |input|.
+//
+// Serializable form of a field:
+// Value or reference of the same type used in |MojomType|, or the
+// following alternatives:
+// - string:
+// Value or reference of any type that has a StringTraits defined.
+// Supported by default: base::StringPiece, std::string.
+//
+// - array:
+// Value or reference of any type that has an ArrayTraits defined.
+// Supported by default: std::vector, WTF::Vector (in blink).
+//
+// - struct:
+// Value or reference of any type that has a StructTraits defined.
+//
+// 2. A static Read() method to set the contents of a |T| instance from a
+// |MojomType|DataView (e.g., if |MojomType| is test::Example, the data
+// view will be test::ExampleDataView).
+//
+// static bool Read(|MojomType|DataView data, T* output);
+//
+// The generated |MojomType|DataView type provides a convenient,
+// inexpensive view of a serialized struct's field data.
+//
+// Returning false indicates invalid incoming data and causes the message
+// pipe receiving it to be disconnected. Therefore, you can do custom
+// validation for |T| in this method.
+//
+// 3. [Optional] A static IsNull() method indicating whether a given |T|
+// instance is null:
+//
+// static bool IsNull(const T& input);
+//
+// If this method returns true, it is guaranteed that none of the getters
+// (described in section 1) will be called for the same |input|. So you
+// don't have to check whether |input| is null in those getters.
+//
+// If it is not defined, |T| instances are always considered non-null.
+//
+// [Optional] A static SetToNull() method to set the contents of a given
+// |T| instance to null.
+//
+// static void SetToNull(T* output);
+//
+// When a null serialized struct is received, the deserialization code
+// calls this method instead of Read().
+//
+// NOTE: It is to set |*output|'s contents to a null state, not to set the
+// |output| pointer itself to null. "Null state" means whatever state you
+// think it makes sense to map a null serialized struct to.
+//
+// If it is not defined, null is not allowed to be converted to |T|. In
+// that case, an incoming null value is considered invalid and causes the
+// message pipe to be disconnected.
+//
+// EXAMPLE:
+//
+// Mojom definition:
+// struct Bar {};
+// struct Foo {
+// int32 f_integer;
+// string f_string;
+// array<string> f_string_array;
+// Bar f_bar;
+// };
//
-// 2. A static Read method to initialize a new |T| from a MojomType::Reader:
+// StructTraits for Foo:
+// template <>
+// struct StructTraits<Foo, CustomFoo> {
+// // Optional methods dealing with null:
+// static bool IsNull(const CustomFoo& input);
+// static void SetToNull(CustomFoo* output);
//
-// static bool Read(MojomType::Reader r, T* out);
+// // Field getters:
+// static int32_t f_integer(const CustomFoo& input);
+// static const std::string& f_string(const CustomFoo& input);
+// static const std::vector<std::string>& f_string_array(
+// const CustomFoo& input);
+// // Assuming there is a StructTraits<Bar, CustomBar> defined.
+// static const CustomBar& f_bar(const CustomFoo& input);
//
-// The generated MojomType::Reader type provides a convenient, inexpensive
-// view of a serialized struct's field data.
+// static bool Read(FooDataView data, CustomFoo* output);
+// };
//
template <typename MojomType, typename T>
struct StructTraits;
diff --git a/chromium/mojo/public/cpp/bindings/wtf_array.h b/chromium/mojo/public/cpp/bindings/wtf_array.h
index b5d1a30c363..06c910d5996 100644
--- a/chromium/mojo/public/cpp/bindings/wtf_array.h
+++ b/chromium/mojo/public/cpp/bindings/wtf_array.h
@@ -29,9 +29,9 @@ class WTFArray {
MOVE_ONLY_TYPE_FOR_CPP_03(WTFArray);
public:
- using Data_ =
- internal::Array_Data<typename internal::WrapperTraits<T>::DataType>;
- using ElementType = T;
+ using Data_ = internal::Array_Data<
+ typename internal::GetDataTypeAsArrayElement<T>::Data>;
+ using Element = T;
// Constructs an empty array.
WTFArray() : is_null_(false) {}