summaryrefslogtreecommitdiff
path: root/chromium/ipc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-09-18 14:34:04 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-10-04 11:15:27 +0000
commite6430e577f105ad8813c92e75c54660c4985026e (patch)
tree88115e5d1fb471fea807111924dcccbeadbf9e4f /chromium/ipc
parent53d399fe6415a96ea6986ec0d402a9c07da72453 (diff)
downloadqtwebengine-chromium-e6430e577f105ad8813c92e75c54660c4985026e.tar.gz
BASELINE: Update Chromium to 61.0.3163.99
Change-Id: I8452f34574d88ca2b27af9bd56fc9ff3f16b1367 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/ipc')
-rw-r--r--chromium/ipc/BUILD.gn46
-rw-r--r--chromium/ipc/DEPS6
-rw-r--r--chromium/ipc/OWNERS2
-rw-r--r--chromium/ipc/README.md2
-rw-r--r--chromium/ipc/handle_attachment_fuchsia.cc43
-rw-r--r--chromium/ipc/handle_attachment_fuchsia.h59
-rw-r--r--chromium/ipc/handle_fuchsia.cc57
-rw-r--r--chromium/ipc/handle_fuchsia.h61
-rw-r--r--chromium/ipc/ipc.mojom1
-rw-r--r--chromium/ipc/ipc_channel.cc2
-rw-r--r--chromium/ipc/ipc_channel_mojo_unittest.cc59
-rw-r--r--chromium/ipc/ipc_channel_proxy.cc19
-rw-r--r--chromium/ipc/ipc_channel_proxy.h10
-rw-r--r--chromium/ipc/ipc_channel_proxy_unittest.cc24
-rw-r--r--chromium/ipc/ipc_channel_proxy_unittest_messages.h6
-rw-r--r--chromium/ipc/ipc_descriptors.h15
-rw-r--r--chromium/ipc/ipc_fuzzing_tests.cc14
-rw-r--r--chromium/ipc/ipc_message.cc2
-rw-r--r--chromium/ipc/ipc_message_attachment_set.cc1
-rw-r--r--chromium/ipc/ipc_message_pipe_reader.h2
-rw-r--r--chromium/ipc/ipc_message_protobuf_utils.h72
-rw-r--r--chromium/ipc/ipc_message_protobuf_utils_unittest.cc193
-rw-r--r--chromium/ipc/ipc_message_start.h2
-rw-r--r--chromium/ipc/ipc_message_unittest.cc17
-rw-r--r--chromium/ipc/ipc_message_utils.cc13
-rw-r--r--chromium/ipc/ipc_message_utils.h166
-rw-r--r--chromium/ipc/ipc_mojo_bootstrap.cc41
-rw-r--r--chromium/ipc/ipc_mojo_perftest.cc435
-rw-r--r--chromium/ipc/ipc_param_traits.h11
-rw-r--r--chromium/ipc/ipc_sync_channel.cc22
-rw-r--r--chromium/ipc/ipc_sync_channel_unittest.cc45
-rw-r--r--chromium/ipc/ipc_sync_message.cc2
-rw-r--r--chromium/ipc/ipc_sync_message_filter.cc11
-rw-r--r--chromium/ipc/ipc_test.mojom2
-rw-r--r--chromium/ipc/test_proto.proto20
35 files changed, 975 insertions, 508 deletions
diff --git a/chromium/ipc/BUILD.gn b/chromium/ipc/BUILD.gn
index a3aaaa3e990..5c2e20959df 100644
--- a/chromium/ipc/BUILD.gn
+++ b/chromium/ipc/BUILD.gn
@@ -7,6 +7,7 @@ import("//build/config/nacl/config.gni")
import("//mojo/public/tools/bindings/mojom.gni")
import("//testing/test.gni")
import("//tools/ipc_fuzzer/ipc_fuzzer.gni")
+import("//third_party/protobuf/proto_library.gni")
declare_args() {
# Enabling debug builds automatically sets enable_ipc_logging to true.
@@ -40,7 +41,6 @@ component("ipc") {
"ipc_channel_proxy.h",
"ipc_channel_reader.cc",
"ipc_channel_reader.h",
- "ipc_descriptors.h",
"ipc_export.h",
"ipc_listener.h",
"ipc_logging.cc",
@@ -105,6 +105,15 @@ component("ipc") {
]
}
+ if (is_fuchsia) {
+ sources += [
+ "handle_attachment_fuchsia.cc",
+ "handle_attachment_fuchsia.h",
+ "handle_fuchsia.cc",
+ "handle_fuchsia.h",
+ ]
+ }
+
defines = [ "IPC_IMPLEMENTATION" ]
public_deps = [
@@ -114,6 +123,17 @@ component("ipc") {
"//mojo/public/cpp/bindings",
"//mojo/public/cpp/system",
]
+
+ if (!is_nacl_nonsfi) {
+ sources += [
+ "ipc_message_protobuf_utils.h",
+ ]
+
+ public_deps += [
+ "//third_party/protobuf:protobuf_lite",
+ ]
+ }
+
deps = [
"//base",
]
@@ -142,9 +162,7 @@ mojom("test_interfaces") {
sources = [
"ipc_test.mojom",
]
-
- # TODO(crbug.com/714018): Convert the implementation to use OnceCallback.
- use_once_callback = false
+ support_lazy_serialization = true
}
# This is provided as a separate target so other targets can provide param
@@ -171,6 +189,12 @@ if (!is_ios) {
]
}
+ proto_library("test_proto") {
+ sources = [
+ "test_proto.proto",
+ ]
+ }
+
test("ipc_tests") {
sources = [
"ipc_channel_mojo_unittest.cc",
@@ -198,6 +222,7 @@ if (!is_ios) {
":ipc",
":run_all_unittests",
":test_interfaces",
+ ":test_proto",
":test_support",
"//base",
"//base:i18n",
@@ -211,6 +236,19 @@ if (!is_ios) {
if (is_mac) {
deps += [ "//sandbox/mac:seatbelt" ]
}
+
+ if (is_fuchsia) {
+ sources -= [
+ # No AF_UNIX domain sockets on Fuchsia.
+ "sync_socket_unittest.cc",
+ ]
+ }
+
+ if (!is_nacl_nonsfi) {
+ sources += [
+ "ipc_message_protobuf_utils_unittest.cc",
+ ]
+ }
}
test("ipc_perftests") {
diff --git a/chromium/ipc/DEPS b/chromium/ipc/DEPS
index 5f929e98738..f8d30bb7b47 100644
--- a/chromium/ipc/DEPS
+++ b/chromium/ipc/DEPS
@@ -20,5 +20,9 @@ specific_include_rules = {
"run_all_(unit|perf)tests\.cc": [
"+mojo/edk/embedder",
"+mojo/edk/test",
- ]
+ ],
+ "ipc_message_protobuf_utils\.h": [
+ # Support serializing RepeatedField / RepeatedPtrField:
+ "+third_party/protobuf/src/google/protobuf/repeated_field.h",
+ ],
}
diff --git a/chromium/ipc/OWNERS b/chromium/ipc/OWNERS
index b8baa34ff13..0617e7bf9d3 100644
--- a/chromium/ipc/OWNERS
+++ b/chromium/ipc/OWNERS
@@ -8,6 +8,8 @@ tsepez@chromium.org
# new sandbox escapes.
per-file ipc_message_start.h=set noparent
per-file ipc_message_start.h=file://ipc/SECURITY_OWNERS
+per-file *_messages*.h=set noparent
+per-file *_messages*.h=file://ipc/SECURITY_OWNERS
per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
per-file *_param_traits*.*=set noparent
diff --git a/chromium/ipc/README.md b/chromium/ipc/README.md
index 2b1f9f20b14..be5624dca39 100644
--- a/chromium/ipc/README.md
+++ b/chromium/ipc/README.md
@@ -604,7 +604,7 @@ and add a typemap like [url_request.typemap](https://cs.chromium.org/chromium/sr
to define the mapping:
```
-mojom = "//content/common/url_loader.mojom"
+mojom = "//content/public/common/url_loader.mojom"
public_headers = [ "//content/common/resource_request.h" ]
traits_headers = [ "//content/common/resource_messages.h" ]
...
diff --git a/chromium/ipc/handle_attachment_fuchsia.cc b/chromium/ipc/handle_attachment_fuchsia.cc
new file mode 100644
index 00000000000..2778002b1ae
--- /dev/null
+++ b/chromium/ipc/handle_attachment_fuchsia.cc
@@ -0,0 +1,43 @@
+// Copyright 2017 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 "ipc/handle_attachment_fuchsia.h"
+
+#include <magenta/syscalls.h>
+#include <magenta/types.h>
+
+namespace IPC {
+namespace internal {
+
+HandleAttachmentFuchsia::HandleAttachmentFuchsia(
+ const mx_handle_t& handle,
+ HandleFuchsia::Permissions permissions)
+ : handle_(MX_HANDLE_INVALID),
+ permissions_(HandleFuchsia::INVALID),
+ owns_handle_(true) {
+ mx_handle_t duplicated_handle;
+ if (mx_handle_duplicate(handle, MX_RIGHT_SAME_RIGHTS, &duplicated_handle) ==
+ MX_OK) {
+ handle_ = duplicated_handle;
+ permissions_ = permissions;
+ }
+}
+
+HandleAttachmentFuchsia::HandleAttachmentFuchsia(const mx_handle_t& handle,
+ FromWire from_wire)
+ : handle_(handle),
+ permissions_(HandleFuchsia::INVALID),
+ owns_handle_(true) {}
+
+HandleAttachmentFuchsia::~HandleAttachmentFuchsia() {
+ if (handle_ != MX_HANDLE_INVALID && owns_handle_)
+ mx_handle_close(handle_);
+}
+
+MessageAttachment::Type HandleAttachmentFuchsia::GetType() const {
+ return Type::FUCHSIA_HANDLE;
+}
+
+} // namespace internal
+} // namespace IPC
diff --git a/chromium/ipc/handle_attachment_fuchsia.h b/chromium/ipc/handle_attachment_fuchsia.h
new file mode 100644
index 00000000000..a01c8028174
--- /dev/null
+++ b/chromium/ipc/handle_attachment_fuchsia.h
@@ -0,0 +1,59 @@
+// Copyright 2017 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 IPC_HANDLE_ATTACHMENT_FUCHSIA_H_
+#define IPC_HANDLE_ATTACHMENT_FUCHSIA_H_
+
+#include <stdint.h>
+
+#include "base/process/process_handle.h"
+#include "ipc/handle_fuchsia.h"
+#include "ipc/ipc_export.h"
+#include "ipc/ipc_message_attachment.h"
+
+namespace IPC {
+namespace internal {
+
+// This class represents a Fuchsia mx_handle_t attached to a Chrome IPC message.
+class IPC_EXPORT HandleAttachmentFuchsia : public MessageAttachment {
+ public:
+ // This constructor makes a copy of |handle| and takes ownership of the
+ // result. Should only be called by the sender of a Chrome IPC message.
+ HandleAttachmentFuchsia(const mx_handle_t& handle,
+ HandleFuchsia::Permissions permissions);
+
+ enum FromWire {
+ FROM_WIRE,
+ };
+ // This constructor takes ownership of |handle|. Should only be called by the
+ // receiver of a Chrome IPC message.
+ HandleAttachmentFuchsia(const mx_handle_t& handle, FromWire from_wire);
+
+ Type GetType() const override;
+
+ mx_handle_t get_handle() const { return handle_; }
+
+ // The caller of this method has taken ownership of |handle_|.
+ void reset_handle_ownership() {
+ owns_handle_ = false;
+ handle_ = MX_HANDLE_INVALID;
+ }
+
+ private:
+ ~HandleAttachmentFuchsia() override;
+ mx_handle_t handle_;
+ HandleFuchsia::Permissions permissions_;
+
+ // In the sender process, the attachment owns the mx_handle_t of a newly
+ // created message. The attachment broker will eventually take ownership, and
+ // set this member to |false|. In the destination process, the attachment owns
+ // the handle until a call to ParamTraits<HandleFuchsia>::Read() takes
+ // ownership.
+ bool owns_handle_;
+};
+
+} // namespace internal
+} // namespace IPC
+
+#endif // IPC_HANDLE_ATTACHMENT_FUCHSIA_H_
diff --git a/chromium/ipc/handle_fuchsia.cc b/chromium/ipc/handle_fuchsia.cc
new file mode 100644
index 00000000000..8b3cc5154d3
--- /dev/null
+++ b/chromium/ipc/handle_fuchsia.cc
@@ -0,0 +1,57 @@
+// Copyright 2017 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 "ipc/handle_fuchsia.h"
+
+#include <utility>
+
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+#include "ipc/handle_attachment_fuchsia.h"
+#include "ipc/ipc_message.h"
+
+namespace IPC {
+
+HandleFuchsia::HandleFuchsia()
+ : handle_(MX_HANDLE_INVALID), permissions_(INVALID) {}
+
+HandleFuchsia::HandleFuchsia(const mx_handle_t& handle, Permissions permissions)
+ : handle_(handle), permissions_(permissions) {}
+
+// static
+void ParamTraits<HandleFuchsia>::Write(base::Pickle* m, const param_type& p) {
+ scoped_refptr<IPC::internal::HandleAttachmentFuchsia> attachment(
+ new IPC::internal::HandleAttachmentFuchsia(p.get_handle(),
+ p.get_permissions()));
+ if (!m->WriteAttachment(std::move(attachment)))
+ NOTREACHED();
+}
+
+// static
+bool ParamTraits<HandleFuchsia>::Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r) {
+ scoped_refptr<base::Pickle::Attachment> base_attachment;
+ if (!m->ReadAttachment(iter, &base_attachment))
+ return false;
+ MessageAttachment* attachment =
+ static_cast<MessageAttachment*>(base_attachment.get());
+ if (attachment->GetType() != MessageAttachment::Type::FUCHSIA_HANDLE)
+ return false;
+ IPC::internal::HandleAttachmentFuchsia* handle_attachment =
+ static_cast<IPC::internal::HandleAttachmentFuchsia*>(attachment);
+ r->set_handle(handle_attachment->get_handle());
+ handle_attachment->reset_handle_ownership();
+ return true;
+}
+
+// static
+void ParamTraits<HandleFuchsia>::Log(const param_type& p, std::string* l) {
+ l->append(base::StringPrintf("0x%x", p.get_handle()));
+ l->append(base::IntToString(p.get_permissions()));
+}
+
+} // namespace IPC
diff --git a/chromium/ipc/handle_fuchsia.h b/chromium/ipc/handle_fuchsia.h
new file mode 100644
index 00000000000..2ff6b53927d
--- /dev/null
+++ b/chromium/ipc/handle_fuchsia.h
@@ -0,0 +1,61 @@
+// Copyright 2017 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 IPC_HANDLE_FUCHSIA_H_
+#define IPC_HANDLE_FUCHSIA_H_
+
+#include <magenta/types.h>
+
+#include <string>
+
+#include "ipc/ipc_export.h"
+#include "ipc/ipc_param_traits.h"
+
+namespace base {
+class Pickle;
+class PickleIterator;
+} // namespace base
+
+namespace IPC {
+
+class IPC_EXPORT HandleFuchsia {
+ public:
+ enum Permissions {
+ // A placeholder value to be used by the receiving IPC channel, since the
+ // permissions information is only used by the broker process.
+ INVALID,
+ // The new mx_handle_t will have the same permissions as the old
+ // mx_handle_t.
+ DUPLICATE,
+ // The new mx_handle_t will have file read and write permissions.
+ FILE_READ_WRITE,
+ MAX_PERMISSIONS = FILE_READ_WRITE
+ };
+
+ // Default constructor makes an invalid mx_handle_t.
+ HandleFuchsia();
+ HandleFuchsia(const mx_handle_t& handle, Permissions permissions);
+
+ mx_handle_t get_handle() const { return handle_; }
+ void set_handle(mx_handle_t handle) { handle_ = handle; }
+ Permissions get_permissions() const { return permissions_; }
+
+ private:
+ mx_handle_t handle_;
+ Permissions permissions_;
+};
+
+template <>
+struct IPC_EXPORT ParamTraits<HandleFuchsia> {
+ typedef HandleFuchsia param_type;
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* p);
+ static void Log(const param_type& p, std::string* l);
+};
+
+} // namespace IPC
+
+#endif // IPC_HANDLE_FUCHSIA_H_
diff --git a/chromium/ipc/ipc.mojom b/chromium/ipc/ipc.mojom
index 0a4fcfa84e6..f986c470d58 100644
--- a/chromium/ipc/ipc.mojom
+++ b/chromium/ipc/ipc.mojom
@@ -15,6 +15,7 @@ struct SerializedHandle {
PLATFORM_FILE,
WIN_HANDLE,
MACH_PORT,
+ FUCHSIA_HANDLE,
};
Type type;
diff --git a/chromium/ipc/ipc_channel.cc b/chromium/ipc/ipc_channel.cc
index 2d510478cc3..177b967601b 100644
--- a/chromium/ipc/ipc_channel.cc
+++ b/chromium/ipc/ipc_channel.cc
@@ -17,7 +17,7 @@
namespace {
// Global atomic used to guarantee channel IDs are unique.
-base::StaticAtomicSequenceNumber g_last_id;
+base::AtomicSequenceNumber g_last_id;
} // namespace
diff --git a/chromium/ipc/ipc_channel_mojo_unittest.cc b/chromium/ipc/ipc_channel_mojo_unittest.cc
index f3499b794c1..f0fc0c307ef 100644
--- a/chromium/ipc/ipc_channel_mojo_unittest.cc
+++ b/chromium/ipc/ipc_channel_mojo_unittest.cc
@@ -244,15 +244,14 @@ class HandleSendingHelper {
mojo::ScopedMessagePipeHandle pipe;
EXPECT_TRUE(
IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe));
- std::string content(GetSendingFileContent().size(), ' ');
+ std::vector<uint8_t> content;
- uint32_t num_bytes = static_cast<uint32_t>(content.size());
ASSERT_EQ(MOJO_RESULT_OK,
mojo::Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE));
EXPECT_EQ(MOJO_RESULT_OK,
- mojo::ReadMessageRaw(pipe.get(), &content[0], &num_bytes, nullptr,
- nullptr, 0));
- EXPECT_EQ(content, GetSendingFileContent());
+ mojo::ReadMessageRaw(pipe.get(), &content, nullptr, 0));
+ EXPECT_EQ(std::string(content.begin(), content.end()),
+ GetSendingFileContent());
}
#if defined(OS_POSIX)
@@ -354,13 +353,11 @@ DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient) {
}
void ReadOK(mojo::MessagePipeHandle pipe) {
- std::string should_be_ok("xx");
- uint32_t num_bytes = static_cast<uint32_t>(should_be_ok.size());
+ std::vector<uint8_t> should_be_ok;
CHECK_EQ(MOJO_RESULT_OK, mojo::Wait(pipe, MOJO_HANDLE_SIGNAL_READABLE));
CHECK_EQ(MOJO_RESULT_OK,
- mojo::ReadMessageRaw(pipe, &should_be_ok[0], &num_bytes, nullptr,
- nullptr, 0));
- EXPECT_EQ(should_be_ok, std::string("OK"));
+ mojo::ReadMessageRaw(pipe, &should_be_ok, nullptr, 0));
+ EXPECT_EQ("OK", std::string(should_be_ok.begin(), should_be_ok.end()));
}
void WriteOK(mojo::MessagePipeHandle pipe) {
@@ -548,18 +545,16 @@ class ListenerWithSimpleAssociatedInterface
next_expected_value_ = value;
}
- void GetExpectedValue(const GetExpectedValueCallback& callback) override {
+ void GetExpectedValue(GetExpectedValueCallback callback) override {
NOTREACHED();
}
- void RequestValue(const RequestValueCallback& callback) override {
- NOTREACHED();
- }
+ void RequestValue(RequestValueCallback callback) override { NOTREACHED(); }
- void RequestQuit(const RequestQuitCallback& callback) override {
+ void RequestQuit(RequestQuitCallback callback) override {
EXPECT_EQ(kNumMessages, num_messages_received_);
received_quit_ = true;
- callback.Run();
+ std::move(callback).Run();
base::MessageLoop::current()->QuitWhenIdle();
}
@@ -738,17 +733,15 @@ class ListenerWithSimpleProxyAssociatedInterface
next_expected_value_ = value;
}
- void GetExpectedValue(const GetExpectedValueCallback& callback) override {
- callback.Run(next_expected_value_);
+ void GetExpectedValue(GetExpectedValueCallback callback) override {
+ std::move(callback).Run(next_expected_value_);
}
- void RequestValue(const RequestValueCallback& callback) override {
- NOTREACHED();
- }
+ void RequestValue(RequestValueCallback callback) override { NOTREACHED(); }
- void RequestQuit(const RequestQuitCallback& callback) override {
+ void RequestQuit(RequestQuitCallback callback) override {
received_quit_ = true;
- callback.Run();
+ std::move(callback).Run();
binding_.Close();
base::MessageLoop::current()->QuitWhenIdle();
}
@@ -871,8 +864,8 @@ class ListenerWithIndirectProxyAssociatedInterface
}
// IPC::mojom::PingReceiver:
- void Ping(const PingCallback& callback) override {
- callback.Run();
+ void Ping(PingCallback callback) override {
+ std::move(callback).Run();
ping_handler_.Run();
}
@@ -953,17 +946,17 @@ class ListenerWithSyncAssociatedInterface
next_expected_value_ = value;
}
- void GetExpectedValue(const GetExpectedValueCallback& callback) override {
- callback.Run(next_expected_value_);
+ void GetExpectedValue(GetExpectedValueCallback callback) override {
+ std::move(callback).Run(next_expected_value_);
}
- void RequestValue(const RequestValueCallback& callback) override {
- callback.Run(response_value_);
+ void RequestValue(RequestValueCallback callback) override {
+ std::move(callback).Run(response_value_);
}
- void RequestQuit(const RequestQuitCallback& callback) override {
+ void RequestQuit(RequestQuitCallback callback) override {
quit_closure_.Run();
- callback.Run();
+ std::move(callback).Run();
}
// IPC::Listener:
@@ -1080,7 +1073,7 @@ class SimpleTestClientImpl : public IPC::mojom::SimpleTestClient,
private:
// IPC::mojom::SimpleTestClient:
- void RequestValue(const RequestValueCallback& callback) override {
+ void RequestValue(RequestValueCallback callback) override {
int32_t response = 0;
if (use_sync_sender_) {
std::unique_ptr<IPC::SyncMessage> reply(new IPC::SyncMessage(
@@ -1091,7 +1084,7 @@ class SimpleTestClientImpl : public IPC::mojom::SimpleTestClient,
EXPECT_TRUE(driver_->RequestValue(&response));
}
- callback.Run(response);
+ std::move(callback).Run(response);
DCHECK(run_loop_);
run_loop_->Quit();
diff --git a/chromium/ipc/ipc_channel_proxy.cc b/chromium/ipc/ipc_channel_proxy.cc
index 616a99404cc..f48e44ce2c0 100644
--- a/chromium/ipc/ipc_channel_proxy.cc
+++ b/chromium/ipc/ipc_channel_proxy.cc
@@ -439,7 +439,7 @@ ChannelProxy::ChannelProxy(
}
ChannelProxy::~ChannelProxy() {
- DCHECK(CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Close();
}
@@ -463,7 +463,7 @@ void ChannelProxy::Init(const IPC::ChannelHandle& channel_handle,
void ChannelProxy::Init(std::unique_ptr<ChannelFactory> factory,
bool create_pipe_now) {
- DCHECK(CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!did_init_);
if (create_pipe_now) {
@@ -503,7 +503,7 @@ void ChannelProxy::Flush() {
}
void ChannelProxy::Close() {
- DCHECK(CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Clear the backpointer to the listener so that any pending calls to
// Context::OnDispatchMessage or OnDispatchError will be ignored. It is
@@ -517,6 +517,12 @@ void ChannelProxy::Close() {
}
bool ChannelProxy::Send(Message* message) {
+ DCHECK(!message->is_sync()) << "Need to use IPC::SyncChannel";
+ SendInternal(message);
+ return true;
+}
+
+void ChannelProxy::SendInternal(Message* message) {
DCHECK(did_init_);
// TODO(alexeypa): add DCHECK(CalledOnValidThread()) here. Currently there are
@@ -535,17 +541,16 @@ bool ChannelProxy::Send(Message* message) {
#endif
context_->Send(message);
- return true;
}
void ChannelProxy::AddFilter(MessageFilter* filter) {
- DCHECK(CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
context_->AddFilter(filter);
}
void ChannelProxy::RemoveFilter(MessageFilter* filter) {
- DCHECK(CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
context_->ipc_task_runner()->PostTask(
FROM_HERE, base::Bind(&Context::OnRemoveFilter, context_,
@@ -567,7 +572,7 @@ void ChannelProxy::GetGenericRemoteAssociatedInterface(
}
void ChannelProxy::ClearIPCTaskRunner() {
- DCHECK(CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
context()->ClearIPCTaskRunner();
}
diff --git a/chromium/ipc/ipc_channel_proxy.h b/chromium/ipc/ipc_channel_proxy.h
index 2825226e9c7..f95e4dde1e0 100644
--- a/chromium/ipc/ipc_channel_proxy.h
+++ b/chromium/ipc/ipc_channel_proxy.h
@@ -14,8 +14,8 @@
#include "base/callback.h"
#include "base/memory/ref_counted.h"
+#include "base/sequence_checker.h"
#include "base/synchronization/lock.h"
-#include "base/threading/non_thread_safe.h"
#include "build/build_config.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_channel_handle.h"
@@ -72,7 +72,7 @@ class MessageFilterRouter;
// |channel_lifetime_lock_| is used to protect it. The locking overhead is only
// paid if the underlying channel supports thread-safe |Send|.
//
-class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe {
+class IPC_EXPORT ChannelProxy : public Sender {
public:
#if defined(ENABLE_IPC_FUZZER)
// Interface for a filter to be imposed on outgoing messages which can
@@ -377,9 +377,11 @@ class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe {
}
#endif
- protected:
bool did_init() const { return did_init_; }
+ // A Send() which doesn't DCHECK if the message is synchronous.
+ void SendInternal(Message* message);
+
private:
friend class IpcSecurityTestUtil;
@@ -404,6 +406,8 @@ class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe {
#if defined(ENABLE_IPC_FUZZER)
OutgoingMessageFilter* outgoing_message_filter_;
#endif
+
+ SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace IPC
diff --git a/chromium/ipc/ipc_channel_proxy_unittest.cc b/chromium/ipc/ipc_channel_proxy_unittest.cc
index f0590999e82..01b895582cb 100644
--- a/chromium/ipc/ipc_channel_proxy_unittest.cc
+++ b/chromium/ipc/ipc_channel_proxy_unittest.cc
@@ -90,7 +90,7 @@ class ChannelReflectorListener : public IPC::Listener {
IPC_BEGIN_MESSAGE_MAP(ChannelReflectorListener, message)
IPC_MESSAGE_HANDLER(TestMsg_Bounce, OnTestBounce)
IPC_MESSAGE_HANDLER(TestMsg_SendBadMessage, OnSendBadMessage)
- IPC_MESSAGE_HANDLER(UtilityMsg_Bounce, OnUtilityBounce)
+ IPC_MESSAGE_HANDLER(AutomationMsg_Bounce, OnAutomationBounce)
IPC_MESSAGE_HANDLER(WorkerMsg_Bounce, OnBounce)
IPC_MESSAGE_HANDLER(WorkerMsg_Quit, OnQuit)
IPC_END_MESSAGE_MAP()
@@ -105,9 +105,7 @@ class ChannelReflectorListener : public IPC::Listener {
channel_->Send(new TestMsg_BadMessage(BadType()));
}
- void OnUtilityBounce() {
- channel_->Send(new UtilityMsg_Bounce());
- }
+ void OnAutomationBounce() { channel_->Send(new AutomationMsg_Bounce()); }
void OnBounce() {
channel_->Send(new WorkerMsg_Bounce());
@@ -282,17 +280,17 @@ class IPCChannelProxyTest : public IPCChannelMojoTestBase {
TEST_F(IPCChannelProxyTest, MessageClassFilters) {
// Construct a filter per message class.
- std::vector<scoped_refptr<MessageCountFilter> > class_filters;
- class_filters.push_back(make_scoped_refptr(
- new MessageCountFilter(TestMsgStart)));
- class_filters.push_back(make_scoped_refptr(
- new MessageCountFilter(UtilityMsgStart)));
+ std::vector<scoped_refptr<MessageCountFilter>> class_filters;
+ class_filters.push_back(
+ make_scoped_refptr(new MessageCountFilter(TestMsgStart)));
+ class_filters.push_back(
+ make_scoped_refptr(new MessageCountFilter(AutomationMsgStart)));
for (size_t i = 0; i < class_filters.size(); ++i)
channel_proxy()->AddFilter(class_filters[i].get());
// Send a message for each class; each filter should receive just one message.
- sender()->Send(new TestMsg_Bounce());
- sender()->Send(new UtilityMsg_Bounce());
+ sender()->Send(new TestMsg_Bounce);
+ sender()->Send(new AutomationMsg_Bounce);
// Send some messages not assigned to a specific or valid message class.
sender()->Send(new WorkerMsg_Bounce);
@@ -320,7 +318,7 @@ TEST_F(IPCChannelProxyTest, GlobalAndMessageClassFilters) {
sender()->Send(new TestMsg_Bounce);
// A message of a different class should be seen only by the global filter.
- sender()->Send(new UtilityMsg_Bounce);
+ sender()->Send(new AutomationMsg_Bounce);
// Flush all messages.
SendQuitMessageAndWaitForIdle();
@@ -347,7 +345,7 @@ TEST_F(IPCChannelProxyTest, FilterRemoval) {
// Send some messages; they should not be seen by either filter.
sender()->Send(new TestMsg_Bounce);
- sender()->Send(new UtilityMsg_Bounce);
+ sender()->Send(new AutomationMsg_Bounce);
// Ensure that the filters were removed and did not receive any messages.
SendQuitMessageAndWaitForIdle();
diff --git a/chromium/ipc/ipc_channel_proxy_unittest_messages.h b/chromium/ipc/ipc_channel_proxy_unittest_messages.h
index 288ce5353d3..ae4505982b7 100644
--- a/chromium/ipc/ipc_channel_proxy_unittest_messages.h
+++ b/chromium/ipc/ipc_channel_proxy_unittest_messages.h
@@ -30,15 +30,15 @@ struct ParamTraits<BadType> {
#endif // IPC_CHANNEL_PROXY_UNITTEST_MESSAGES_H_
-
+#undef IPC_MESSAGE_START
#define IPC_MESSAGE_START TestMsgStart
IPC_MESSAGE_CONTROL0(TestMsg_Bounce)
IPC_MESSAGE_CONTROL0(TestMsg_SendBadMessage)
IPC_MESSAGE_CONTROL1(TestMsg_BadMessage, BadType)
#undef IPC_MESSAGE_START
-#define IPC_MESSAGE_START UtilityMsgStart
-IPC_MESSAGE_CONTROL0(UtilityMsg_Bounce)
+#define IPC_MESSAGE_START AutomationMsgStart
+IPC_MESSAGE_CONTROL0(AutomationMsg_Bounce)
#undef IPC_MESSAGE_START
#define IPC_MESSAGE_START WorkerMsgStart
diff --git a/chromium/ipc/ipc_descriptors.h b/chromium/ipc/ipc_descriptors.h
deleted file mode 100644
index 7a4a7b19a5c..00000000000
--- a/chromium/ipc/ipc_descriptors.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2009 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 IPC_IPC_DESCRIPTORS_H_
-#define IPC_IPC_DESCRIPTORS_H_
-
-// This is a list of global descriptor keys to be used with the
-// base::GlobalDescriptors object (see base/posix/global_descriptors.h)
-enum {
- // The first key that can be use to register descriptors.
- kIPCDescriptorMax = 0
-};
-
-#endif // IPC_IPC_DESCRIPTORS_H_
diff --git a/chromium/ipc/ipc_fuzzing_tests.cc b/chromium/ipc/ipc_fuzzing_tests.cc
index 8e385bc34fe..5744135c56a 100644
--- a/chromium/ipc/ipc_fuzzing_tests.cc
+++ b/chromium/ipc/ipc_fuzzing_tests.cc
@@ -126,6 +126,20 @@ TEST(IPCMessageIntegrity, ReadVectorTooLarge2) {
EXPECT_FALSE(ReadParam(&m, &iter, &vec));
}
+// This test needs ~20 seconds in Debug mode, or ~4 seconds in Release mode.
+// See http://crbug.com/741866 for details.
+TEST(IPCMessageIntegrity, DISABLED_ReadVectorTooLarge3) {
+ base::Pickle pickle;
+ IPC::WriteParam(&pickle, 256 * 1024 * 1024);
+ IPC::WriteParam(&pickle, 0);
+ IPC::WriteParam(&pickle, 1);
+ IPC::WriteParam(&pickle, 2);
+
+ base::PickleIterator iter(pickle);
+ std::vector<int> vec;
+ EXPECT_FALSE(IPC::ReadParam(&pickle, &iter, &vec));
+}
+
class SimpleListener : public IPC::Listener {
public:
SimpleListener() : other_(NULL) {
diff --git a/chromium/ipc/ipc_message.cc b/chromium/ipc/ipc_message.cc
index f66b4fe882c..8f408eaf51f 100644
--- a/chromium/ipc/ipc_message.cc
+++ b/chromium/ipc/ipc_message.cc
@@ -21,7 +21,7 @@
namespace {
-base::StaticAtomicSequenceNumber g_ref_num;
+base::AtomicSequenceNumber g_ref_num;
// Create a reference number for identifying IPC messages in traces. The return
// values has the reference number stored in the upper 24 bits, leaving the low
diff --git a/chromium/ipc/ipc_message_attachment_set.cc b/chromium/ipc/ipc_message_attachment_set.cc
index b9a990da8bb..58dd6cae4a1 100644
--- a/chromium/ipc/ipc_message_attachment_set.cc
+++ b/chromium/ipc/ipc_message_attachment_set.cc
@@ -75,6 +75,7 @@ bool MessageAttachmentSet::AddAttachment(
case MessageAttachment::Type::MOJO_HANDLE:
case MessageAttachment::Type::WIN_HANDLE:
case MessageAttachment::Type::MACH_PORT:
+ case MessageAttachment::Type::FUCHSIA_HANDLE:
attachments_.push_back(attachment);
*index = attachments_.size() - 1;
return true;
diff --git a/chromium/ipc/ipc_message_pipe_reader.h b/chromium/ipc/ipc_message_pipe_reader.h
index b441960e3e1..ceb62feec76 100644
--- a/chromium/ipc/ipc_message_pipe_reader.h
+++ b/chromium/ipc/ipc_message_pipe_reader.h
@@ -74,7 +74,7 @@ class IPC_EXPORT MessagePipeReader : public NON_EXPORTED_BASE(mojom::Channel) {
void Close();
// Return true if the MessagePipe is alive.
- bool IsValid() { return sender_; }
+ bool IsValid() { return sender_.is_bound(); }
// Sends an IPC::Message to the other end of the pipe. Safe to call from any
// thread.
diff --git a/chromium/ipc/ipc_message_protobuf_utils.h b/chromium/ipc/ipc_message_protobuf_utils.h
new file mode 100644
index 00000000000..8cacfe8d933
--- /dev/null
+++ b/chromium/ipc/ipc_message_protobuf_utils.h
@@ -0,0 +1,72 @@
+// Copyright 2017 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 IPC_IPC_MESSAGE_PROTOBUF_UTILS_H_
+#define IPC_IPC_MESSAGE_PROTOBUF_UTILS_H_
+
+#include "build/build_config.h"
+
+#if defined(OS_NACL_NONSFI)
+static_assert(false,
+ "ipc_message_protobuf_utils is not able to work with "
+ "nacl_nonsfi configuration.");
+#endif
+
+#include "base/pickle.h"
+#include "ipc/ipc_param_traits.h"
+#include "ipc/ipc_message_utils.h"
+#include "third_party/protobuf/src/google/protobuf/repeated_field.h"
+
+namespace IPC {
+
+template <class RepeatedFieldLike, class StorageType>
+struct RepeatedFieldParamTraits {
+ typedef RepeatedFieldLike param_type;
+ static void GetSize(base::PickleSizer* sizer, const param_type& p) {
+ GetParamSize(sizer, p.size());
+ for (int i = 0; i < p.size(); i++)
+ GetParamSize(sizer, p.Get(i));
+ }
+ static void Write(base::Pickle* m, const param_type& p) {
+ WriteParam(m, p.size());
+ for (int i = 0; i < p.size(); i++)
+ WriteParam(m, p.Get(i));
+ }
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r) {
+ int size;
+ // ReadLength() checks for < 0 itself.
+ if (!iter->ReadLength(&size))
+ return false;
+ // Avoid integer overflow / assertion failure in Reserve() function.
+ if (INT_MAX / sizeof(StorageType) <= static_cast<size_t>(size))
+ return false;
+ r->Reserve(size);
+ for (int i = 0; i < size; i++) {
+ if (!ReadParam(m, iter, r->Add()))
+ return false;
+ }
+ return true;
+ }
+ static void Log(const param_type& p, std::string* l) {
+ for (int i = 0; i < p.size(); ++i) {
+ if (i != 0)
+ l->append(" ");
+ LogParam(p.Get(i), l);
+ }
+ }
+};
+
+template <class P>
+struct ParamTraits<google::protobuf::RepeatedField<P>> :
+ RepeatedFieldParamTraits<google::protobuf::RepeatedField<P>, P> {};
+
+template <class P>
+struct ParamTraits<google::protobuf::RepeatedPtrField<P>> :
+ RepeatedFieldParamTraits<google::protobuf::RepeatedPtrField<P>, void*> {};
+
+} // namespace IPC
+
+#endif // IPC_IPC_MESSAGE_PROTOBUF_UTILS_H_
diff --git a/chromium/ipc/ipc_message_protobuf_utils_unittest.cc b/chromium/ipc/ipc_message_protobuf_utils_unittest.cc
new file mode 100644
index 00000000000..5c01a7f1e09
--- /dev/null
+++ b/chromium/ipc/ipc_message_protobuf_utils_unittest.cc
@@ -0,0 +1,193 @@
+// Copyright 2017 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 "build/build_config.h"
+
+#if defined(OS_NACL_NONSFI)
+static_assert(false,
+ "ipc_message_protobuf_utils is not able to work with nacl_nonsfi "
+ "configuration.");
+#endif
+
+#include "ipc/ipc_message_protobuf_utils.h"
+
+#include <initializer_list>
+
+#include "ipc/test_proto.pb.h"
+#include "ipc/ipc_message.h"
+#include "ipc/ipc_message_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace IPC {
+
+template <>
+struct ParamTraits<ipc_message_utils_test::TestMessage1> {
+ typedef ipc_message_utils_test::TestMessage1 param_type;
+ static void GetSize(base::PickleSizer* sizer, const param_type& p) {
+ GetParamSize(sizer, p.number());
+ }
+ static void Write(base::Pickle* m, const param_type& p) {
+ WriteParam(m, p.number());
+ }
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r) {
+ int number;
+ if (!iter->ReadInt(&number))
+ return false;
+ r->set_number(number);
+ return true;
+ }
+};
+
+template <>
+struct ParamTraits<ipc_message_utils_test::TestMessage2> {
+ typedef ipc_message_utils_test::TestMessage2 param_type;
+ static void GetSize(base::PickleSizer* sizer, const param_type& p) {
+ GetParamSize(sizer, p.numbers());
+ GetParamSize(sizer, p.strings());
+ GetParamSize(sizer, p.messages());
+ }
+ static void Write(base::Pickle* m, const param_type& p) {
+ WriteParam(m, p.numbers());
+ WriteParam(m, p.strings());
+ WriteParam(m, p.messages());
+ }
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r) {
+ return ReadParam(m, iter, r->mutable_numbers()) &&
+ ReadParam(m, iter, r->mutable_strings()) &&
+ ReadParam(m, iter, r->mutable_messages());
+ }
+};
+
+namespace {
+
+template <class P1, class P2>
+void AssertEqual(const P1& left, const P2& right) {
+ ASSERT_EQ(left, right);
+}
+
+template<>
+void AssertEqual(const int& left,
+ const ipc_message_utils_test::TestMessage1& right) {
+ ASSERT_EQ(left, right.number());
+}
+
+template <template<class> class RepeatedFieldLike, class P1, class P2>
+void AssertRepeatedFieldEquals(std::initializer_list<P1> expected,
+ const RepeatedFieldLike<P2>& fields) {
+ ASSERT_EQ(static_cast<int>(expected.size()), fields.size());
+ auto it = expected.begin();
+ int i = 0;
+ for (; it != expected.end(); it++, i++) {
+ AssertEqual(*it, fields.Get(i));
+ }
+}
+
+TEST(IPCMessageRepeatedFieldUtilsTest, RepeatedFieldShouldBeSerialized) {
+ ipc_message_utils_test::TestMessage2 message;
+ message.add_numbers(1);
+ message.add_numbers(100);
+ message.add_strings("abc");
+ message.add_strings("def");
+ message.add_messages()->set_number(1000);
+ message.add_messages()->set_number(10000);
+
+ base::Pickle pickle;
+ IPC::WriteParam(&pickle, message);
+
+ base::PickleSizer sizer;
+ IPC::GetParamSize(&sizer, message);
+
+ ASSERT_EQ(sizer.payload_size(), pickle.payload_size());
+
+ base::PickleIterator iter(pickle);
+ ipc_message_utils_test::TestMessage2 output;
+ ASSERT_TRUE(IPC::ReadParam(&pickle, &iter, &output));
+
+ AssertRepeatedFieldEquals({1, 100}, output.numbers());
+ AssertRepeatedFieldEquals({"abc", "def"}, output.strings());
+ AssertRepeatedFieldEquals({1000, 10000}, output.messages());
+}
+
+TEST(IPCMessageRepeatedFieldUtilsTest,
+ PartialEmptyRepeatedFieldShouldBeSerialized) {
+ ipc_message_utils_test::TestMessage2 message;
+ message.add_numbers(1);
+ message.add_numbers(100);
+ message.add_messages()->set_number(1000);
+ message.add_messages()->set_number(10000);
+
+ base::Pickle pickle;
+ IPC::WriteParam(&pickle, message);
+
+ base::PickleSizer sizer;
+ IPC::GetParamSize(&sizer, message);
+
+ ASSERT_EQ(sizer.payload_size(), pickle.payload_size());
+
+ base::PickleIterator iter(pickle);
+ ipc_message_utils_test::TestMessage2 output;
+ ASSERT_TRUE(IPC::ReadParam(&pickle, &iter, &output));
+
+ AssertRepeatedFieldEquals({1, 100}, output.numbers());
+ ASSERT_EQ(0, output.strings_size());
+ AssertRepeatedFieldEquals({1000, 10000}, output.messages());
+}
+
+TEST(IPCMessageRepeatedFieldUtilsTest, EmptyRepeatedFieldShouldBeSerialized) {
+ ipc_message_utils_test::TestMessage2 message;
+
+ base::Pickle pickle;
+ IPC::WriteParam(&pickle, message);
+
+ base::PickleSizer sizer;
+ IPC::GetParamSize(&sizer, message);
+
+ ASSERT_EQ(sizer.payload_size(), pickle.payload_size());
+
+ base::PickleIterator iter(pickle);
+ ipc_message_utils_test::TestMessage2 output;
+ ASSERT_TRUE(IPC::ReadParam(&pickle, &iter, &output));
+
+ ASSERT_EQ(0, output.numbers_size());
+ ASSERT_EQ(0, output.strings_size());
+ ASSERT_EQ(0, output.messages_size());
+}
+
+TEST(IPCMessageRepeatedFieldUtilsTest,
+ InvalidPickleShouldNotCrashRepeatedFieldDeserialization) {
+ base::Pickle pickle;
+ IPC::WriteParam(&pickle, INT_MAX);
+ IPC::WriteParam(&pickle, 0);
+ IPC::WriteParam(&pickle, INT_MAX);
+ IPC::WriteParam(&pickle, std::string());
+ IPC::WriteParam(&pickle, 0);
+
+ base::PickleIterator iter(pickle);
+ ipc_message_utils_test::TestMessage2 output;
+ ASSERT_FALSE(IPC::ReadParam(&pickle, &iter, &output));
+}
+
+// This test needs ~20 seconds in Debug mode, or ~4 seconds in Release mode.
+// See http://crbug.com/741866 for details.
+TEST(IPCMessageRepeatedFieldUtilsTest,
+ DISABLED_InvalidPickleShouldNotCrashRepeatedFieldDeserialization2) {
+ base::Pickle pickle;
+ IPC::WriteParam(&pickle, 256 * 1024 * 1024);
+ IPC::WriteParam(&pickle, 0);
+ IPC::WriteParam(&pickle, INT_MAX);
+ IPC::WriteParam(&pickle, std::string());
+ IPC::WriteParam(&pickle, 0);
+
+ base::PickleIterator iter(pickle);
+ ipc_message_utils_test::TestMessage2 output;
+ ASSERT_FALSE(IPC::ReadParam(&pickle, &iter, &output));
+}
+
+} // namespace
+
+} // namespace IPC
diff --git a/chromium/ipc/ipc_message_start.h b/chromium/ipc/ipc_message_start.h
index e3fda0e957c..dba1acb4202 100644
--- a/chromium/ipc/ipc_message_start.h
+++ b/chromium/ipc/ipc_message_start.h
@@ -19,7 +19,6 @@ enum IPCMessageStart {
DevToolsMsgStart,
WorkerMsgStart,
NaClMsgStart,
- UtilityMsgStart,
GpuChannelMsgStart,
MediaMsgStart,
ServiceMsgStart,
@@ -90,7 +89,6 @@ enum IPCMessageStart {
ChromeUtilityExtensionsMsgStart,
PlatformNotificationMsgStart,
PDFMsgStart,
- ManifestManagerMsgStart,
LayoutTestMsgStart,
NetworkHintsMsgStart,
BluetoothMsgStart,
diff --git a/chromium/ipc/ipc_message_unittest.cc b/chromium/ipc/ipc_message_unittest.cc
index 8e59e00c859..4e5bf07a23b 100644
--- a/chromium/ipc/ipc_message_unittest.cc
+++ b/chromium/ipc/ipc_message_unittest.cc
@@ -10,6 +10,7 @@
#include <limits>
#include <memory>
+#include <utility>
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -89,21 +90,21 @@ TEST(IPCMessageTest, ListValue) {
TEST(IPCMessageTest, DictionaryValue) {
base::DictionaryValue input;
input.Set("null", base::MakeUnique<base::Value>());
- input.Set("bool", new base::Value(true));
- input.Set("int", new base::Value(42));
+ input.SetBoolean("bool", true);
+ input.SetInteger("int", 42);
input.SetIntegerWithoutPathExpansion("int.with.dot", 43);
- std::unique_ptr<base::DictionaryValue> subdict(new base::DictionaryValue());
- subdict->Set("str", new base::Value("forty two"));
- subdict->Set("bool", new base::Value(false));
+ auto subdict = base::MakeUnique<base::DictionaryValue>();
+ subdict->SetString("str", "forty two");
+ subdict->SetBoolean("bool", false);
- std::unique_ptr<base::ListValue> sublist(new base::ListValue());
+ auto sublist = base::MakeUnique<base::ListValue>();
sublist->AppendDouble(42.42);
sublist->AppendString("forty");
sublist->AppendString("two");
- subdict->Set("list", sublist.release());
+ subdict->Set("list", std::move(sublist));
- input.Set("dict", subdict.release());
+ input.Set("dict", std::move(subdict));
IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
IPC::WriteParam(&msg, input);
diff --git a/chromium/ipc/ipc_message_utils.cc b/chromium/ipc/ipc_message_utils.cc
index 8179cd4dfb2..c851d8a599e 100644
--- a/chromium/ipc/ipc_message_utils.cc
+++ b/chromium/ipc/ipc_message_utils.cc
@@ -38,6 +38,10 @@
#include "ipc/ipc_platform_file.h"
#endif
+#if defined(OS_FUCHSIA)
+#include "ipc/handle_fuchsia.h"
+#endif
+
namespace IPC {
namespace {
@@ -419,7 +423,7 @@ void ParamTraits<unsigned int>::Log(const param_type& p, std::string* l) {
l->append(base::UintToString(p));
}
-#if defined(OS_WIN) || defined(OS_LINUX) || \
+#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_FUCHSIA) || \
(defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
void ParamTraits<long>::Log(const param_type& p, std::string* l) {
l->append(base::Int64ToString(static_cast<int64_t>(p)));
@@ -753,6 +757,10 @@ bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
HandleWin handle_win;
if (!ReadParam(m, iter, &handle_win))
return false;
+#elif defined(OS_FUCHSIA)
+ HandleFuchsia handle_fuchsia;
+ if (!ReadParam(m, iter, &handle_fuchsia))
+ return false;
#else
scoped_refptr<base::Pickle::Attachment> attachment;
if (!m->ReadAttachment(iter, &attachment))
@@ -776,6 +784,9 @@ bool ParamTraits<base::SharedMemoryHandle>::Read(const base::Pickle* m,
#elif defined(OS_WIN)
*r = base::SharedMemoryHandle(handle_win.get_handle(),
static_cast<size_t>(size), guid);
+#elif defined(OS_FUCHSIA)
+ *r = base::SharedMemoryHandle(handle_fuchsia.get_handle(),
+ static_cast<size_t>(size), guid);
#else
*r = base::SharedMemoryHandle(
base::FileDescriptor(
diff --git a/chromium/ipc/ipc_message_utils.h b/chromium/ipc/ipc_message_utils.h
index 84324ebaf41..348ff7eb61a 100644
--- a/chromium/ipc/ipc_message_utils.h
+++ b/chromium/ipc/ipc_message_utils.h
@@ -208,10 +208,10 @@ struct ParamTraits<unsigned int> {
// very few IPCs that cross this boundary.
// 2) We also need to keep it for Linux for two reasons: int64_t is typedef'd
// to long, and gfx::PluginWindow is long and is used in one GPU IPC.
-// 3) Android 64 bit also has int64_t typedef'd to long.
+// 3) Android 64 bit and Fuchsia also have int64_t typedef'd to long.
// Since we want to support Android 32<>64 bit IPC, as long as we don't have
// these traits for 32 bit ARM then that'll catch any errors.
-#if defined(OS_WIN) || defined(OS_LINUX) || \
+#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_FUCHSIA) || \
(defined(OS_ANDROID) && defined(ARCH_CPU_64_BITS))
template <>
struct ParamTraits<long> {
@@ -724,149 +724,63 @@ struct ParamTraits<std::tuple<>> {
}
};
-template <class A>
-struct ParamTraits<std::tuple<A>> {
- typedef std::tuple<A> param_type;
- static void GetSize(base::PickleSizer* sizer, const param_type& p) {
- GetParamSize(sizer, std::get<0>(p));
- }
- static void Write(base::Pickle* m, const param_type& p) {
- WriteParam(m, std::get<0>(p));
- }
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- return ReadParam(m, iter, &std::get<0>(*r));
- }
- static void Log(const param_type& p, std::string* l) {
- LogParam(std::get<0>(p), l);
- }
-};
+template <typename T, int index, int count>
+struct TupleParamTraitsHelper {
+ using Next = TupleParamTraitsHelper<T, index + 1, count>;
-template <class A, class B>
-struct ParamTraits<std::tuple<A, B>> {
- typedef std::tuple<A, B> param_type;
- static void GetSize(base::PickleSizer* sizer, const param_type& p) {
- GetParamSize(sizer, std::get<0>(p));
- GetParamSize(sizer, std::get<1>(p));
- }
- static void Write(base::Pickle* m, const param_type& p) {
- WriteParam(m, std::get<0>(p));
- WriteParam(m, std::get<1>(p));
+ static void GetSize(base::PickleSizer* sizer, const T& p) {
+ GetParamSize(sizer, std::get<index>(p));
+ Next::GetSize(sizer, p);
}
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- return (ReadParam(m, iter, &std::get<0>(*r)) &&
- ReadParam(m, iter, &std::get<1>(*r)));
- }
- static void Log(const param_type& p, std::string* l) {
- LogParam(std::get<0>(p), l);
- l->append(", ");
- LogParam(std::get<1>(p), l);
- }
-};
-template <class A, class B, class C>
-struct ParamTraits<std::tuple<A, B, C>> {
- typedef std::tuple<A, B, C> param_type;
- static void GetSize(base::PickleSizer* sizer, const param_type& p) {
- GetParamSize(sizer, std::get<0>(p));
- GetParamSize(sizer, std::get<1>(p));
- GetParamSize(sizer, std::get<2>(p));
- }
- static void Write(base::Pickle* m, const param_type& p) {
- WriteParam(m, std::get<0>(p));
- WriteParam(m, std::get<1>(p));
- WriteParam(m, std::get<2>(p));
+ static void Write(base::Pickle* m, const T& p) {
+ WriteParam(m, std::get<index>(p));
+ Next::Write(m, p);
}
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- return (ReadParam(m, iter, &std::get<0>(*r)) &&
- ReadParam(m, iter, &std::get<1>(*r)) &&
- ReadParam(m, iter, &std::get<2>(*r)));
+
+ static bool Read(const base::Pickle* m, base::PickleIterator* iter, T* r) {
+ return ReadParam(m, iter, &std::get<index>(*r)) && Next::Read(m, iter, r);
}
- static void Log(const param_type& p, std::string* l) {
- LogParam(std::get<0>(p), l);
- l->append(", ");
- LogParam(std::get<1>(p), l);
- l->append(", ");
- LogParam(std::get<2>(p), l);
+
+ static void Log(const T& p, std::string* l) {
+ LogParam(std::get<index>(p), l);
+ if (index < count - 1)
+ l->append(", ");
+ Next::Log(p, l);
}
};
-template <class A, class B, class C, class D>
-struct ParamTraits<std::tuple<A, B, C, D>> {
- typedef std::tuple<A, B, C, D> param_type;
- static void GetSize(base::PickleSizer* sizer, const param_type& p) {
- GetParamSize(sizer, std::get<0>(p));
- GetParamSize(sizer, std::get<1>(p));
- GetParamSize(sizer, std::get<2>(p));
- GetParamSize(sizer, std::get<3>(p));
- }
- static void Write(base::Pickle* m, const param_type& p) {
- WriteParam(m, std::get<0>(p));
- WriteParam(m, std::get<1>(p));
- WriteParam(m, std::get<2>(p));
- WriteParam(m, std::get<3>(p));
- }
- static bool Read(const base::Pickle* m,
- base::PickleIterator* iter,
- param_type* r) {
- return (ReadParam(m, iter, &std::get<0>(*r)) &&
- ReadParam(m, iter, &std::get<1>(*r)) &&
- ReadParam(m, iter, &std::get<2>(*r)) &&
- ReadParam(m, iter, &std::get<3>(*r)));
- }
- static void Log(const param_type& p, std::string* l) {
- LogParam(std::get<0>(p), l);
- l->append(", ");
- LogParam(std::get<1>(p), l);
- l->append(", ");
- LogParam(std::get<2>(p), l);
- l->append(", ");
- LogParam(std::get<3>(p), l);
+template <typename T, int index>
+struct TupleParamTraitsHelper<T, index, index> {
+ static void GetSize(base::PickleSizer* sizer, const T& p) {}
+ static void Write(base::Pickle* m, const T& p) {}
+ static bool Read(const base::Pickle* m, base::PickleIterator* iter, T* r) {
+ return true;
}
+ static void Log(const T& p, std::string* l) {}
};
-template <class A, class B, class C, class D, class E>
-struct ParamTraits<std::tuple<A, B, C, D, E>> {
- typedef std::tuple<A, B, C, D, E> param_type;
+template <typename... Args>
+struct ParamTraits<std::tuple<Args...>> {
+ using param_type = std::tuple<Args...>;
+ using Helper =
+ TupleParamTraitsHelper<param_type, 0, std::tuple_size<param_type>::value>;
+
static void GetSize(base::PickleSizer* sizer, const param_type& p) {
- GetParamSize(sizer, std::get<0>(p));
- GetParamSize(sizer, std::get<1>(p));
- GetParamSize(sizer, std::get<2>(p));
- GetParamSize(sizer, std::get<3>(p));
- GetParamSize(sizer, std::get<4>(p));
+ Helper::GetSize(sizer, p);
}
+
static void Write(base::Pickle* m, const param_type& p) {
- WriteParam(m, std::get<0>(p));
- WriteParam(m, std::get<1>(p));
- WriteParam(m, std::get<2>(p));
- WriteParam(m, std::get<3>(p));
- WriteParam(m, std::get<4>(p));
+ Helper::Write(m, p);
}
+
static bool Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* r) {
- return (ReadParam(m, iter, &std::get<0>(*r)) &&
- ReadParam(m, iter, &std::get<1>(*r)) &&
- ReadParam(m, iter, &std::get<2>(*r)) &&
- ReadParam(m, iter, &std::get<3>(*r)) &&
- ReadParam(m, iter, &std::get<4>(*r)));
- }
- static void Log(const param_type& p, std::string* l) {
- LogParam(std::get<0>(p), l);
- l->append(", ");
- LogParam(std::get<1>(p), l);
- l->append(", ");
- LogParam(std::get<2>(p), l);
- l->append(", ");
- LogParam(std::get<3>(p), l);
- l->append(", ");
- LogParam(std::get<4>(p), l);
+ return Helper::Read(m, iter, r);
}
+
+ static void Log(const param_type& p, std::string* l) { Helper::Log(p, l); }
};
template <class P, size_t stack_capacity>
diff --git a/chromium/ipc/ipc_mojo_bootstrap.cc b/chromium/ipc/ipc_mojo_bootstrap.cc
index 5361d8e0bff..afd0e3cc075 100644
--- a/chromium/ipc/ipc_mojo_bootstrap.cc
+++ b/chromium/ipc/ipc_mojo_bootstrap.cc
@@ -18,6 +18,7 @@
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
+#include "base/threading/thread_checker.h"
#include "base/threading/thread_task_runner_handle.h"
#include "mojo/public/cpp/bindings/associated_group.h"
#include "mojo/public/cpp/bindings/associated_group_controller.h"
@@ -208,7 +209,7 @@ class ChannelAssociatedGroupController
mojo::InterfaceEndpointController* AttachEndpointClient(
const mojo::ScopedInterfaceEndpointHandle& handle,
mojo::InterfaceEndpointClient* client,
- scoped_refptr<base::SingleThreadTaskRunner> runner) override {
+ scoped_refptr<base::SequencedTaskRunner> runner) override {
const mojo::InterfaceId id = handle.id();
DCHECK(mojo::IsValidInterfaceId(id));
@@ -249,6 +250,8 @@ class ChannelAssociatedGroupController
}
}
+ bool PrefersSerializedMessages() override { return true; }
+
private:
class Endpoint;
class ControlMessageProxyThunk;
@@ -343,7 +346,7 @@ class ChannelAssociatedGroupController
disconnect_reason_ = disconnect_reason;
}
- base::SingleThreadTaskRunner* task_runner() const {
+ base::SequencedTaskRunner* task_runner() const {
return task_runner_.get();
}
@@ -353,11 +356,11 @@ class ChannelAssociatedGroupController
}
void AttachClient(mojo::InterfaceEndpointClient* client,
- scoped_refptr<base::SingleThreadTaskRunner> runner) {
+ scoped_refptr<base::SequencedTaskRunner> runner) {
controller_->lock_.AssertAcquired();
DCHECK(!client_);
DCHECK(!closed_);
- DCHECK(runner->BelongsToCurrentThread());
+ DCHECK(runner->RunsTasksInCurrentSequence());
task_runner_ = std::move(runner);
client_ = client;
@@ -366,7 +369,7 @@ class ChannelAssociatedGroupController
void DetachClient() {
controller_->lock_.AssertAcquired();
DCHECK(client_);
- DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
DCHECK(!closed_);
task_runner_ = nullptr;
@@ -400,20 +403,20 @@ class ChannelAssociatedGroupController
// mojo::InterfaceEndpointController:
bool SendMessage(mojo::Message* message) override {
- DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
message->set_interface_id(id_);
return controller_->SendMessage(message);
}
void AllowWokenUpBySyncWatchOnSameThread() override {
- DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
EnsureSyncWatcherExists();
sync_watcher_->AllowWokenUpBySyncWatchOnSameThread();
}
bool SyncWatch(const bool* should_stop) override {
- DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
// It's not legal to make sync calls from the master endpoint's thread,
// and in fact they must only happen from the proxy task runner.
@@ -436,7 +439,7 @@ class ChannelAssociatedGroupController
}
void OnSyncMessageEventReady() {
- DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
scoped_refptr<Endpoint> keepalive(this);
scoped_refptr<AssociatedGroupController> controller_keepalive(
@@ -483,7 +486,7 @@ class ChannelAssociatedGroupController
}
void EnsureSyncWatcherExists() {
- DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (sync_watcher_)
return;
@@ -519,7 +522,7 @@ class ChannelAssociatedGroupController
bool handle_created_ = false;
base::Optional<mojo::DisconnectReason> disconnect_reason_;
mojo::InterfaceEndpointClient* client_ = nullptr;
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
std::unique_ptr<mojo::SyncEventWatcher> sync_watcher_;
std::unique_ptr<base::WaitableEvent> sync_message_event_;
std::queue<std::pair<uint32_t, MessageWrapper>> sync_messages_;
@@ -626,7 +629,7 @@ class ChannelAssociatedGroupController
void NotifyEndpointOfError(Endpoint* endpoint, bool force_async) {
lock_.AssertAcquired();
DCHECK(endpoint->task_runner() && endpoint->client());
- if (endpoint->task_runner()->BelongsToCurrentThread() && !force_async) {
+ if (endpoint->task_runner()->RunsTasksInCurrentSequence() && !force_async) {
mojo::InterfaceEndpointClient* client = endpoint->client();
base::Optional<mojo::DisconnectReason> reason(
endpoint->disconnect_reason());
@@ -636,9 +639,9 @@ class ChannelAssociatedGroupController
} else {
endpoint->task_runner()->PostTask(
FROM_HERE,
- base::Bind(&ChannelAssociatedGroupController
- ::NotifyEndpointOfErrorOnEndpointThread, this, endpoint->id(),
- endpoint));
+ base::Bind(&ChannelAssociatedGroupController::
+ NotifyEndpointOfErrorOnEndpointThread,
+ this, endpoint->id(), base::Unretained(endpoint)));
}
}
@@ -651,7 +654,7 @@ class ChannelAssociatedGroupController
if (!endpoint->client())
return;
- DCHECK(endpoint->task_runner()->BelongsToCurrentThread());
+ DCHECK(endpoint->task_runner()->RunsTasksInCurrentSequence());
NotifyEndpointOfError(endpoint, false /* force_async */);
}
@@ -709,7 +712,7 @@ class ChannelAssociatedGroupController
return true;
mojo::InterfaceEndpointClient* client = endpoint->client();
- if (!client || !endpoint->task_runner()->BelongsToCurrentThread()) {
+ if (!client || !endpoint->task_runner()->RunsTasksInCurrentSequence()) {
// No client has been bound yet or the client runs tasks on another
// thread. We assume the other thread must always be the one on which
// |proxy_task_runner_| runs tasks, since that's the only valid scenario.
@@ -765,7 +768,7 @@ class ChannelAssociatedGroupController
if (!client)
return;
- DCHECK(endpoint->task_runner()->BelongsToCurrentThread());
+ DCHECK(endpoint->task_runner()->RunsTasksInCurrentSequence());
// Sync messages should never make their way to this method.
DCHECK(!message.has_flag(mojo::Message::kFlagIsSync));
@@ -794,7 +797,7 @@ class ChannelAssociatedGroupController
if (!client)
return;
- DCHECK(endpoint->task_runner()->BelongsToCurrentThread());
+ DCHECK(endpoint->task_runner()->RunsTasksInCurrentSequence());
MessageWrapper message_wrapper = endpoint->PopSyncMessage(message_id);
// The message must have already been dequeued by the endpoint waking up
diff --git a/chromium/ipc/ipc_mojo_perftest.cc b/chromium/ipc/ipc_mojo_perftest.cc
index d02acda9760..8513e08b286 100644
--- a/chromium/ipc/ipc_mojo_perftest.cc
+++ b/chromium/ipc/ipc_mojo_perftest.cc
@@ -10,11 +10,13 @@
#include "base/process/process_metrics.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
+#include "base/synchronization/waitable_event.h"
#include "base/test/perf_time_logger.h"
#include "base/test/test_io_thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "ipc/ipc_channel_mojo.h"
+#include "ipc/ipc_sync_channel.h"
#include "ipc/ipc_test.mojom.h"
#include "ipc/ipc_test_base.h"
#include "mojo/edk/embedder/embedder.h"
@@ -24,52 +26,18 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/message_pipe.h"
-namespace IPC {
-namespace {
-
-// This class simply collects stats about abstract "events" (each of which has a
-// start time and an end time).
-class EventTimeTracker {
- public:
- explicit EventTimeTracker(const char* name)
- : name_(name),
- count_(0) {
- }
-
- void AddEvent(const base::TimeTicks& start, const base::TimeTicks& end) {
- DCHECK(end >= start);
- count_++;
- base::TimeDelta duration = end - start;
- total_duration_ += duration;
- max_duration_ = std::max(max_duration_, duration);
- }
-
- void ShowResults() const {
- VLOG(1) << name_ << " count: " << count_;
- VLOG(1) << name_ << " total duration: "
- << total_duration_.InMillisecondsF() << " ms";
- VLOG(1) << name_ << " average duration: "
- << (total_duration_.InMillisecondsF() / static_cast<double>(count_))
- << " ms";
- VLOG(1) << name_ << " maximum duration: "
- << max_duration_.InMillisecondsF() << " ms";
- }
+#define IPC_MESSAGE_IMPL
+#include "ipc/ipc_message_macros.h"
- void Reset() {
- count_ = 0;
- total_duration_ = base::TimeDelta();
- max_duration_ = base::TimeDelta();
- }
-
- private:
- const std::string name_;
+#define IPC_MESSAGE_START TestMsgStart
- uint64_t count_;
- base::TimeDelta total_duration_;
- base::TimeDelta max_duration_;
+IPC_MESSAGE_CONTROL0(TestMsg_Hello)
+IPC_MESSAGE_CONTROL0(TestMsg_Quit)
+IPC_MESSAGE_CONTROL1(TestMsg_Ping, std::string)
+IPC_SYNC_MESSAGE_CONTROL1_1(TestMsg_SyncPing, std::string, std::string)
- DISALLOW_COPY_AND_ASSIGN(EventTimeTracker);
-};
+namespace IPC {
+namespace {
class PerformanceChannelListener : public Listener {
public:
@@ -78,14 +46,12 @@ class PerformanceChannelListener : public Listener {
sender_(NULL),
msg_count_(0),
msg_size_(0),
- count_down_(0),
- latency_tracker_("Server messages") {
+ sync_(false),
+ count_down_(0) {
VLOG(1) << "Server listener up";
}
- ~PerformanceChannelListener() override {
- VLOG(1) << "Server listener down";
- }
+ ~PerformanceChannelListener() override { VLOG(1) << "Server listener down"; }
void Init(Sender* sender) {
DCHECK(!sender_);
@@ -93,10 +59,11 @@ class PerformanceChannelListener : public Listener {
}
// Call this before running the message loop.
- void SetTestParams(int msg_count, size_t msg_size) {
+ void SetTestParams(int msg_count, size_t msg_size, bool sync) {
DCHECK_EQ(0, count_down_);
msg_count_ = msg_count;
msg_size_ = msg_size;
+ sync_ = sync;
count_down_ = msg_count_;
payload_ = std::string(msg_size_, 'a');
}
@@ -104,60 +71,61 @@ class PerformanceChannelListener : public Listener {
bool OnMessageReceived(const Message& message) override {
CHECK(sender_);
- base::PickleIterator iter(message);
- int64_t time_internal;
- EXPECT_TRUE(iter.ReadInt64(&time_internal));
- int msgid;
- EXPECT_TRUE(iter.ReadInt(&msgid));
- std::string reflected_payload;
- EXPECT_TRUE(iter.ReadString(&reflected_payload));
-
- // Include message deserialization in latency.
- base::TimeTicks now = base::TimeTicks::Now();
-
- if (reflected_payload == "hello") {
- // Start timing on hello.
- latency_tracker_.Reset();
- DCHECK(!perf_logger_.get());
- std::string test_name =
- base::StringPrintf("IPC_%s_Perf_%dx_%u",
- label_.c_str(),
- msg_count_,
- static_cast<unsigned>(msg_size_));
- perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(PerformanceChannelListener, message)
+ IPC_MESSAGE_HANDLER(TestMsg_Hello, OnHello)
+ IPC_MESSAGE_HANDLER(TestMsg_Ping, OnPing)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+ }
+
+ void OnHello() {
+ // Start timing on hello.
+ DCHECK(!perf_logger_.get());
+ std::string test_name =
+ base::StringPrintf("IPC_%s_Perf_%dx_%u", label_.c_str(), msg_count_,
+ static_cast<unsigned>(msg_size_));
+ perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));
+ if (sync_) {
+ for (int i = 0; i < count_down_; ++i) {
+ std::string response;
+ sender_->Send(new TestMsg_SyncPing(payload_, &response));
+ DCHECK_EQ(response, payload_);
+ }
+ perf_logger_.reset();
+ base::MessageLoop::current()->QuitWhenIdle();
} else {
- DCHECK_EQ(payload_.size(), reflected_payload.size());
+ SendPong();
+ }
+ }
- latency_tracker_.AddEvent(
- base::TimeTicks::FromInternalValue(time_internal), now);
+ void OnPing(const std::string& payload) {
+ // Include message deserialization in latency.
+ DCHECK_EQ(payload_.size(), payload.size());
- CHECK(count_down_ > 0);
- count_down_--;
- if (count_down_ == 0) {
- perf_logger_.reset(); // Stop the perf timer now.
- latency_tracker_.ShowResults();
- base::MessageLoop::current()->QuitWhenIdle();
- return true;
- }
+ CHECK(count_down_ > 0);
+ count_down_--;
+ if (count_down_ == 0) {
+ perf_logger_.reset(); // Stop the perf timer now.
+ base::MessageLoop::current()->QuitWhenIdle();
+ return;
}
- Message* msg = new Message(0, 2, Message::PRIORITY_NORMAL);
- msg->WriteInt64(base::TimeTicks::Now().ToInternalValue());
- msg->WriteInt(count_down_);
- msg->WriteString(payload_);
- sender_->Send(msg);
- return true;
+ SendPong();
}
+ void SendPong() { sender_->Send(new TestMsg_Ping(payload_)); }
+
private:
std::string label_;
Sender* sender_;
int msg_count_;
size_t msg_size_;
+ bool sync_;
int count_down_;
std::string payload_;
- EventTimeTracker latency_tracker_;
std::unique_ptr<base::PerfTimeLogger> perf_logger_;
};
@@ -166,59 +134,46 @@ class PerformanceChannelListener : public Listener {
// "quit" is sent, it will exit.
class ChannelReflectorListener : public Listener {
public:
- ChannelReflectorListener()
- : channel_(NULL),
- latency_tracker_("Client messages") {
+ ChannelReflectorListener() : channel_(NULL) {
VLOG(1) << "Client listener up";
}
- ~ChannelReflectorListener() override {
- VLOG(1) << "Client listener down";
- latency_tracker_.ShowResults();
- }
+ ~ChannelReflectorListener() override { VLOG(1) << "Client listener down"; }
- void Init(Channel* channel) {
+ void Init(Sender* channel) {
DCHECK(!channel_);
channel_ = channel;
}
bool OnMessageReceived(const Message& message) override {
CHECK(channel_);
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(ChannelReflectorListener, message)
+ IPC_MESSAGE_HANDLER(TestMsg_Hello, OnHello)
+ IPC_MESSAGE_HANDLER(TestMsg_Ping, OnPing)
+ IPC_MESSAGE_HANDLER(TestMsg_SyncPing, OnSyncPing)
+ IPC_MESSAGE_HANDLER(TestMsg_Quit, OnQuit)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+ }
- base::PickleIterator iter(message);
- int64_t time_internal;
- EXPECT_TRUE(iter.ReadInt64(&time_internal));
- int msgid;
- EXPECT_TRUE(iter.ReadInt(&msgid));
- base::StringPiece payload;
- EXPECT_TRUE(iter.ReadStringPiece(&payload));
-
- // Include message deserialization in latency.
- base::TimeTicks now = base::TimeTicks::Now();
+ void OnHello() { channel_->Send(new TestMsg_Hello); }
- if (payload == "hello") {
- latency_tracker_.Reset();
- } else if (payload == "quit") {
- latency_tracker_.ShowResults();
- base::MessageLoop::current()->QuitWhenIdle();
- return true;
- } else {
- // Don't track hello and quit messages.
- latency_tracker_.AddEvent(
- base::TimeTicks::FromInternalValue(time_internal), now);
- }
+ void OnPing(const std::string& payload) {
+ channel_->Send(new TestMsg_Ping(payload));
+ }
- Message* msg = new Message(0, 2, Message::PRIORITY_NORMAL);
- msg->WriteInt64(base::TimeTicks::Now().ToInternalValue());
- msg->WriteInt(msgid);
- msg->WriteString(payload);
- channel_->Send(msg);
- return true;
+ void OnSyncPing(const std::string& payload, std::string* response) {
+ *response = payload;
}
+ void OnQuit() { base::MessageLoop::current()->QuitWhenIdle(); }
+
+ void Send(IPC::Message* message) { channel_->Send(message); }
+
private:
- Channel* channel_;
- EventTimeTracker latency_tracker_;
+ Sender* channel_;
};
// This class locks the current thread to a particular CPU core. This is
@@ -273,8 +228,7 @@ class LockThreadAffinity {
class PingPongTestParams {
public:
PingPongTestParams(size_t size, int count)
- : message_size_(size), message_count_(count) {
- }
+ : message_size_(size), message_count_(count) {}
size_t message_size() const { return message_size_; }
int message_count() const { return message_count_; }
@@ -285,8 +239,8 @@ class PingPongTestParams {
};
std::vector<PingPongTestParams> GetDefaultTestParams() {
- // Test several sizes. We use 12^N for message size, and limit the message
- // count to keep the test duration reasonable.
+// Test several sizes. We use 12^N for message size, and limit the message
+// count to keep the test duration reasonable.
#ifdef NDEBUG
const int kMultiplier = 100;
#else
@@ -311,79 +265,70 @@ class MojoChannelPerfTest : public IPCChannelMojoTestBase {
MojoChannelPerfTest() = default;
~MojoChannelPerfTest() override = default;
- void RunTestChannelPingPong() {
+ void RunTestChannelProxyPingPong() {
+ io_thread_.reset(new base::TestIOThread(base::TestIOThread::kAutoStart));
+
Init("MojoPerfTestClient");
// Set up IPC channel and start client.
- PerformanceChannelListener listener("Channel");
- CreateChannel(&listener);
- listener.Init(channel());
- ASSERT_TRUE(ConnectChannel());
+ PerformanceChannelListener listener("ChannelProxy");
+ auto channel_proxy = IPC::ChannelProxy::Create(
+ TakeHandle().release(), IPC::Channel::MODE_SERVER, &listener,
+ io_thread_->task_runner());
+ listener.Init(channel_proxy.get());
LockThreadAffinity thread_locker(kSharedCore);
std::vector<PingPongTestParams> params = GetDefaultTestParams();
for (size_t i = 0; i < params.size(); i++) {
listener.SetTestParams(params[i].message_count(),
- params[i].message_size());
+ params[i].message_size(), false);
// This initial message will kick-start the ping-pong of messages.
- Message* message =
- new Message(0, 2, Message::PRIORITY_NORMAL);
- message->WriteInt64(base::TimeTicks::Now().ToInternalValue());
- message->WriteInt(-1);
- message->WriteString("hello");
- sender()->Send(message);
+ channel_proxy->Send(new TestMsg_Hello);
// Run message loop.
base::RunLoop().Run();
}
// Send quit message.
- Message* message = new Message(0, 2, Message::PRIORITY_NORMAL);
- message->WriteInt64(base::TimeTicks::Now().ToInternalValue());
- message->WriteInt(-1);
- message->WriteString("quit");
- sender()->Send(message);
+ channel_proxy->Send(new TestMsg_Quit);
EXPECT_TRUE(WaitForClientShutdown());
- DestroyChannel();
-}
+ channel_proxy.reset();
- void RunTestChannelProxyPingPong() {
+ io_thread_.reset();
+ }
+
+ void RunTestChannelProxySyncPing() {
io_thread_.reset(new base::TestIOThread(base::TestIOThread::kAutoStart));
Init("MojoPerfTestClient");
// Set up IPC channel and start client.
PerformanceChannelListener listener("ChannelProxy");
- auto channel_proxy = IPC::ChannelProxy::Create(
+ base::WaitableEvent shutdown_event(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
+ auto channel_proxy = IPC::SyncChannel::Create(
TakeHandle().release(), IPC::Channel::MODE_SERVER, &listener,
- io_thread_->task_runner());
+ io_thread_->task_runner(), false, &shutdown_event);
listener.Init(channel_proxy.get());
LockThreadAffinity thread_locker(kSharedCore);
std::vector<PingPongTestParams> params = GetDefaultTestParams();
for (size_t i = 0; i < params.size(); i++) {
listener.SetTestParams(params[i].message_count(),
- params[i].message_size());
+ params[i].message_size(), true);
// This initial message will kick-start the ping-pong of messages.
- Message* message = new Message(0, 2, Message::PRIORITY_NORMAL);
- message->WriteInt64(base::TimeTicks::Now().ToInternalValue());
- message->WriteInt(-1);
- message->WriteString("hello");
- channel_proxy->Send(message);
+ channel_proxy->Send(new TestMsg_Hello);
// Run message loop.
base::RunLoop().Run();
}
// Send quit message.
- Message* message = new Message(0, 2, Message::PRIORITY_NORMAL);
- message->WriteInt64(base::TimeTicks::Now().ToInternalValue());
- message->WriteInt(-1);
- message->WriteString("quit");
- channel_proxy->Send(message);
+ channel_proxy->Send(new TestMsg_Quit);
EXPECT_TRUE(WaitForClientShutdown());
channel_proxy.reset();
@@ -401,13 +346,6 @@ class MojoChannelPerfTest : public IPCChannelMojoTestBase {
std::unique_ptr<base::TestIOThread> io_thread_;
};
-TEST_F(MojoChannelPerfTest, ChannelPingPong) {
- RunTestChannelPingPong();
-
- base::RunLoop run_loop;
- run_loop.RunUntilIdle();
-}
-
TEST_F(MojoChannelPerfTest, ChannelProxyPingPong) {
RunTestChannelProxyPingPong();
@@ -415,24 +353,16 @@ TEST_F(MojoChannelPerfTest, ChannelProxyPingPong) {
run_loop.RunUntilIdle();
}
-// Test to see how many channels we can create.
-TEST_F(MojoChannelPerfTest, DISABLED_MaxChannelCount) {
-#if defined(OS_POSIX)
- LOG(INFO) << "base::GetMaxFds " << base::GetMaxFds();
- base::SetFdLimit(20000);
-#endif
+TEST_F(MojoChannelPerfTest, ChannelProxySyncPing) {
+ RunTestChannelProxySyncPing();
- std::vector<mojo::edk::PlatformChannelPair*> channels;
- for (size_t i = 0; i < 10000; ++i) {
- LOG(INFO) << "channels size: " << channels.size();
- channels.push_back(new mojo::edk::PlatformChannelPair());
- }
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
}
class MojoPerfTestClient {
public:
- MojoPerfTestClient()
- : listener_(new ChannelReflectorListener()) {
+ MojoPerfTestClient() : listener_(new ChannelReflectorListener()) {
mojo::edk::test::MultiprocessTestHelper::ChildSetup();
}
@@ -441,17 +371,19 @@ class MojoPerfTestClient {
int Run(MojoHandle handle) {
handle_ = mojo::MakeScopedHandle(mojo::MessagePipeHandle(handle));
LockThreadAffinity thread_locker(kSharedCore);
- std::unique_ptr<Channel> channel = ChannelMojo::Create(
- std::move(handle_), Channel::MODE_CLIENT, listener_.get());
+ base::TestIOThread io_thread(base::TestIOThread::kAutoStart);
+
+ std::unique_ptr<ChannelProxy> channel =
+ IPC::ChannelProxy::Create(handle_.release(), Channel::MODE_CLIENT,
+ listener_.get(), io_thread.task_runner());
listener_->Init(channel.get());
- CHECK(channel->Connect());
base::RunLoop().Run();
return 0;
}
private:
- base::MessageLoopForIO main_message_loop_;
+ base::MessageLoop main_message_loop_;
std::unique_ptr<ChannelReflectorListener> listener_;
std::unique_ptr<Channel> channel_;
mojo::ScopedMessagePipeHandle handle_;
@@ -479,14 +411,16 @@ class ReflectorImpl : public IPC::mojom::Reflector {
private:
// IPC::mojom::Reflector:
- void Ping(const std::string& value, const PingCallback& callback) override {
- callback.Run(value);
+ void Ping(const std::string& value, PingCallback callback) override {
+ std::move(callback).Run(value);
}
- void Quit() override {
- base::MessageLoop::current()->QuitWhenIdle();
+ void SyncPing(const std::string& value, PingCallback callback) override {
+ std::move(callback).Run(value);
}
+ void Quit() override { base::MessageLoop::current()->QuitWhenIdle(); }
+
mojo::Binding<IPC::mojom::Reflector> binding_;
};
@@ -500,15 +434,13 @@ class MojoInterfacePerfTest : public mojo::edk::test::MojoTestBase {
mojo::MessagePipeHandle mp_handle(mp);
mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);
- ping_receiver_.Bind(IPC::mojom::ReflectorPtrInfo(
- std::move(scoped_mp), 0u));
+ ping_receiver_.Bind(IPC::mojom::ReflectorPtrInfo(std::move(scoped_mp), 0u));
LockThreadAffinity thread_locker(kSharedCore);
std::vector<PingPongTestParams> params = GetDefaultTestParams();
for (size_t i = 0; i < params.size(); i++) {
- ping_receiver_->Ping(
- "hello",
- base::Bind(&MojoInterfacePerfTest::OnPong, base::Unretained(this)));
+ ping_receiver_->Ping("hello", base::Bind(&MojoInterfacePerfTest::OnPong,
+ base::Unretained(this)));
message_count_ = count_down_ = params[i].message_count();
payload_ = std::string(params[i].message_size(), 'a');
@@ -524,10 +456,8 @@ class MojoInterfacePerfTest : public mojo::edk::test::MojoTestBase {
if (value == "hello") {
DCHECK(!perf_logger_.get());
std::string test_name =
- base::StringPrintf("IPC_%s_Perf_%dx_%zu",
- label_.c_str(),
- message_count_,
- payload_.size());
+ base::StringPrintf("IPC_%s_Perf_%dx_%zu", label_.c_str(),
+ message_count_, payload_.size());
perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));
} else {
DCHECK_EQ(payload_.size(), value.size());
@@ -541,9 +471,18 @@ class MojoInterfacePerfTest : public mojo::edk::test::MojoTestBase {
}
}
- ping_receiver_->Ping(
- payload_,
- base::Bind(&MojoInterfacePerfTest::OnPong, base::Unretained(this)));
+ if (sync_) {
+ for (int i = 0; i < count_down_; ++i) {
+ std::string response;
+ ping_receiver_->SyncPing(payload_, &response);
+ DCHECK_EQ(response, payload_);
+ }
+ perf_logger_.reset();
+ base::MessageLoop::current()->QuitWhenIdle();
+ } else {
+ ping_receiver_->Ping(payload_, base::Bind(&MojoInterfacePerfTest::OnPong,
+ base::Unretained(this)));
+ }
}
static int RunPingPongClient(MojoHandle mp) {
@@ -562,6 +501,8 @@ class MojoInterfacePerfTest : public mojo::edk::test::MojoTestBase {
return 0;
}
+ bool sync_ = false;
+
private:
int message_count_;
int count_down_;
@@ -573,6 +514,31 @@ class MojoInterfacePerfTest : public mojo::edk::test::MojoTestBase {
DISALLOW_COPY_AND_ASSIGN(MojoInterfacePerfTest);
};
+enum class InProcessMessageMode {
+ kSerialized,
+ kUnserialized,
+};
+
+class MojoInProcessInterfacePerfTest
+ : public MojoInterfacePerfTest,
+ public testing::WithParamInterface<InProcessMessageMode> {
+ public:
+ MojoInProcessInterfacePerfTest() {
+ switch (GetParam()) {
+ case InProcessMessageMode::kSerialized:
+ mojo::Connector::OverrideDefaultSerializationBehaviorForTesting(
+ mojo::Connector::OutgoingSerializationMode::kEager,
+ mojo::Connector::IncomingSerializationMode::kDispatchAsIs);
+ break;
+ case InProcessMessageMode::kUnserialized:
+ mojo::Connector::OverrideDefaultSerializationBehaviorForTesting(
+ mojo::Connector::OutgoingSerializationMode::kLazy,
+ mojo::Connector::IncomingSerializationMode::kDispatchAsIs);
+ break;
+ }
+ }
+};
+
DEFINE_TEST_CLIENT_WITH_PIPE(PingPongClient, MojoInterfacePerfTest, h) {
base::MessageLoop main_message_loop;
return RunPingPongClient(h);
@@ -581,14 +547,22 @@ DEFINE_TEST_CLIENT_WITH_PIPE(PingPongClient, MojoInterfacePerfTest, h) {
// Similar to MojoChannelPerfTest above, but uses a Mojo interface instead of
// raw IPC::Messages.
TEST_F(MojoInterfacePerfTest, MultiprocessPingPong) {
- RUN_CHILD_ON_PIPE(PingPongClient, h)
+ RunTestClient("PingPongClient", [&](MojoHandle h) {
+ base::MessageLoop main_message_loop;
+ RunPingPongServer(h, "Multiprocess");
+ });
+}
+
+TEST_F(MojoInterfacePerfTest, MultiprocessSyncPing) {
+ sync_ = true;
+ RunTestClient("PingPongClient", [&](MojoHandle h) {
base::MessageLoop main_message_loop;
- RunPingPongServer(h, "MultiProcess");
- END_CHILD()
+ RunPingPongServer(h, "MultiprocessSync");
+ });
}
// A single process version of the above test.
-TEST_F(MojoInterfacePerfTest, SingleProcessMultiThreadPingPong) {
+TEST_P(MojoInProcessInterfacePerfTest, MultiThreadPingPong) {
MojoHandle server_handle, client_handle;
CreateMessagePipe(&server_handle, &client_handle);
@@ -602,7 +576,7 @@ TEST_F(MojoInterfacePerfTest, SingleProcessMultiThreadPingPong) {
RunPingPongServer(server_handle, "SingleProcess");
}
-TEST_F(MojoInterfacePerfTest, SingleProcessSingleThreadPingPong) {
+TEST_P(MojoInProcessInterfacePerfTest, SingleThreadPingPong) {
MojoHandle server_handle, client_handle;
CreateMessagePipe(&server_handle, &client_handle);
@@ -615,6 +589,11 @@ TEST_F(MojoInterfacePerfTest, SingleProcessSingleThreadPingPong) {
RunPingPongServer(server_handle, "SingleProcess");
}
+INSTANTIATE_TEST_CASE_P(,
+ MojoInProcessInterfacePerfTest,
+ testing::Values(InProcessMessageMode::kSerialized,
+ InProcessMessageMode::kUnserialized));
+
class CallbackPerfTest : public testing::Test {
public:
CallbackPerfTest()
@@ -641,8 +620,7 @@ class CallbackPerfTest : public testing::Test {
void Ping(const std::string& value) {
main_message_loop_.task_runner()->PostTask(
FROM_HERE,
- base::Bind(&CallbackPerfTest::OnPong, base::Unretained(this),
- value));
+ base::Bind(&CallbackPerfTest::OnPong, base::Unretained(this), value));
}
void OnPong(const std::string& value) {
@@ -650,8 +628,7 @@ class CallbackPerfTest : public testing::Test {
DCHECK(!perf_logger_.get());
std::string test_name =
base::StringPrintf("Callback_MultiProcess_Perf_%dx_%zu",
- message_count_,
- payload_.size());
+ message_count_, payload_.size());
perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));
} else {
DCHECK_EQ(payload_.size(), value.size());
@@ -674,15 +651,14 @@ class CallbackPerfTest : public testing::Test {
LockThreadAffinity thread_locker(kSharedCore);
std::vector<PingPongTestParams> params = GetDefaultTestParams();
base::Callback<void(const std::string&,
- const base::Callback<void(const std::string&)>&)> ping =
- base::Bind(&CallbackPerfTest::SingleThreadPingNoPostTask,
- base::Unretained(this));
+ const base::Callback<void(const std::string&)>&)>
+ ping = base::Bind(&CallbackPerfTest::SingleThreadPingNoPostTask,
+ base::Unretained(this));
for (size_t i = 0; i < params.size(); i++) {
payload_ = std::string(params[i].message_size(), 'a');
std::string test_name =
base::StringPrintf("Callback_SingleThreadPostTask_Perf_%dx_%zu",
- params[i].message_count(),
- payload_.size());
+ params[i].message_count(), payload_.size());
perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));
for (int j = 0; j < params[i].message_count(); ++j) {
ping.Run(payload_,
@@ -693,13 +669,13 @@ class CallbackPerfTest : public testing::Test {
}
}
- void SingleThreadPingNoPostTask(const std::string& value,
- const base::Callback<void(const std::string&)>& pong) {
+ void SingleThreadPingNoPostTask(
+ const std::string& value,
+ const base::Callback<void(const std::string&)>& pong) {
pong.Run(value);
}
- void SingleThreadPongNoPostTask(const std::string& value) {
- }
+ void SingleThreadPongNoPostTask(const std::string& value) {}
void RunSingleThreadPostTaskPingPongServer() {
LockThreadAffinity thread_locker(kSharedCore);
@@ -707,9 +683,8 @@ class CallbackPerfTest : public testing::Test {
for (size_t i = 0; i < params.size(); i++) {
std::string hello("hello");
base::MessageLoop::current()->task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&CallbackPerfTest::SingleThreadPingPostTask,
- base::Unretained(this), hello));
+ FROM_HERE, base::Bind(&CallbackPerfTest::SingleThreadPingPostTask,
+ base::Unretained(this), hello));
message_count_ = count_down_ = params[i].message_count();
payload_ = std::string(params[i].message_size(), 'a');
@@ -719,10 +694,8 @@ class CallbackPerfTest : public testing::Test {
void SingleThreadPingPostTask(const std::string& value) {
base::MessageLoop::current()->task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&CallbackPerfTest::SingleThreadPongPostTask,
- base::Unretained(this),
- value));
+ FROM_HERE, base::Bind(&CallbackPerfTest::SingleThreadPongPostTask,
+ base::Unretained(this), value));
}
void SingleThreadPongPostTask(const std::string& value) {
@@ -730,8 +703,7 @@ class CallbackPerfTest : public testing::Test {
DCHECK(!perf_logger_.get());
std::string test_name =
base::StringPrintf("Callback_SingleThreadNoPostTask_Perf_%dx_%zu",
- message_count_,
- payload_.size());
+ message_count_, payload_.size());
perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str()));
} else {
DCHECK_EQ(payload_.size(), value.size());
@@ -746,9 +718,8 @@ class CallbackPerfTest : public testing::Test {
}
base::MessageLoop::current()->task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&CallbackPerfTest::SingleThreadPingPostTask,
- base::Unretained(this), payload_));
+ FROM_HERE, base::Bind(&CallbackPerfTest::SingleThreadPingPostTask,
+ base::Unretained(this), payload_));
}
private:
diff --git a/chromium/ipc/ipc_param_traits.h b/chromium/ipc/ipc_param_traits.h
index 45e975c30a7..9aaeb5e506b 100644
--- a/chromium/ipc/ipc_param_traits.h
+++ b/chromium/ipc/ipc_param_traits.h
@@ -9,8 +9,19 @@
// a data type is read, written and logged in the IPC system.
namespace IPC {
+namespace internal {
+
+template <typename T>
+struct AlwaysFalse {
+ static const bool value = false;
+};
+
+} // namespace internal
template <class P> struct ParamTraits {
+ static_assert(internal::AlwaysFalse<P>::value,
+ "Cannot find the IPC::ParamTraits specialization. Did you "
+ "forget to include the corresponding header file?");
};
template <class P>
diff --git a/chromium/ipc/ipc_sync_channel.cc b/chromium/ipc/ipc_sync_channel.cc
index 36effbca032..05272a1ae91 100644
--- a/chromium/ipc/ipc_sync_channel.cc
+++ b/chromium/ipc/ipc_sync_channel.cc
@@ -599,7 +599,7 @@ bool SyncChannel::Send(Message* message) {
"line", IPC_MESSAGE_ID_LINE(message->type()));
#endif
if (!message->is_sync()) {
- ChannelProxy::Send(message);
+ ChannelProxy::SendInternal(message);
return true;
}
@@ -614,7 +614,7 @@ bool SyncChannel::Send(Message* message) {
return false;
}
- ChannelProxy::Send(message);
+ ChannelProxy::SendInternal(message);
// Wait for reply, or for any other incoming synchronous messages.
// |this| might get deleted, so only call static functions at this point.
@@ -646,15 +646,14 @@ void SyncChannel::WaitForReply(mojo::SyncHandleRegistry* registry,
bool dispatch = false;
bool send_done = false;
bool should_pump_messages = false;
- bool registered = registry->RegisterEvent(
- context->GetSendDoneEvent(), base::Bind(&OnEventReady, &send_done));
- DCHECK(registered);
+ base::Closure on_send_done_callback = base::Bind(&OnEventReady, &send_done);
+ registry->RegisterEvent(context->GetSendDoneEvent(), on_send_done_callback);
+ base::Closure on_pump_messages_callback;
if (pump_messages_event) {
- registered = registry->RegisterEvent(
- pump_messages_event,
- base::Bind(&OnEventReady, &should_pump_messages));
- DCHECK(registered);
+ on_pump_messages_callback =
+ base::Bind(&OnEventReady, &should_pump_messages);
+ registry->RegisterEvent(pump_messages_event, on_pump_messages_callback);
}
const bool* stop_flags[] = { &dispatch, &send_done, &should_pump_messages };
@@ -662,9 +661,10 @@ void SyncChannel::WaitForReply(mojo::SyncHandleRegistry* registry,
registry->Wait(stop_flags, 3);
context->received_sync_msgs()->UnblockDispatch();
- registry->UnregisterEvent(context->GetSendDoneEvent());
+ registry->UnregisterEvent(context->GetSendDoneEvent(),
+ on_send_done_callback);
if (pump_messages_event)
- registry->UnregisterEvent(pump_messages_event);
+ registry->UnregisterEvent(pump_messages_event, on_pump_messages_callback);
if (dispatch) {
// We're waiting for a reply, but we received a blocking synchronous call.
diff --git a/chromium/ipc/ipc_sync_channel_unittest.cc b/chromium/ipc/ipc_sync_channel_unittest.cc
index 63d5e464219..5d6588fceed 100644
--- a/chromium/ipc/ipc_sync_channel_unittest.cc
+++ b/chromium/ipc/ipc_sync_channel_unittest.cc
@@ -81,8 +81,6 @@ class Worker : public Listener, public Sender {
// Shutdown() must be called before destruction.
CHECK(is_shutdown_);
}
- void AddRef() { }
- void Release() { }
bool Send(Message* msg) override { return channel_->Send(msg); }
void WaitForChannelCreation() { channel_created_->Wait(); }
void CloseChannel() {
@@ -92,7 +90,7 @@ class Worker : public Listener, public Sender {
void Start() {
StartThread(&listener_thread_, base::MessageLoop::TYPE_DEFAULT);
ListenerThread()->task_runner()->PostTask(
- FROM_HERE, base::Bind(&Worker::OnStart, this));
+ FROM_HERE, base::Bind(&Worker::OnStart, base::Unretained(this)));
}
void Shutdown() {
// The IPC thread needs to outlive SyncChannel. We can't do this in
@@ -104,8 +102,9 @@ class Worker : public Listener, public Sender {
ipc_done(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
ListenerThread()->task_runner()->PostTask(
- FROM_HERE, base::Bind(&Worker::OnListenerThreadShutdown1, this,
- &listener_done, &ipc_done));
+ FROM_HERE,
+ base::Bind(&Worker::OnListenerThreadShutdown1, base::Unretained(this),
+ &listener_done, &ipc_done));
listener_done.Wait();
ipc_done.Wait();
ipc_thread_.Stop();
@@ -207,8 +206,9 @@ class Worker : public Listener, public Sender {
base::RunLoop().RunUntilIdle();
ipc_thread_.task_runner()->PostTask(
- FROM_HERE, base::Bind(&Worker::OnIPCThreadShutdown, this,
- listener_event, ipc_event));
+ FROM_HERE,
+ base::Bind(&Worker::OnIPCThreadShutdown, base::Unretained(this),
+ listener_event, ipc_event));
}
void OnIPCThreadShutdown(WaitableEvent* listener_event,
@@ -217,8 +217,8 @@ class Worker : public Listener, public Sender {
ipc_event->Signal();
listener_thread_.task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&Worker::OnListenerThreadShutdown2, this, listener_event));
+ FROM_HERE, base::Bind(&Worker::OnListenerThreadShutdown2,
+ base::Unretained(this), listener_event));
}
void OnListenerThreadShutdown2(WaitableEvent* listener_event) {
@@ -1018,7 +1018,7 @@ class DoneEventRaceServer : public Worker {
void Run() override {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&NestedCallback, this));
+ FROM_HERE, base::Bind(&NestedCallback, base::Unretained(this)));
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, base::Bind(&TimeoutCallback),
base::TimeDelta::FromSeconds(9));
@@ -1117,8 +1117,9 @@ class ServerSendAfterClose : public Worker {
bool SendDummy() {
ListenerThread()->task_runner()->PostTask(
- FROM_HERE, base::Bind(base::IgnoreResult(&ServerSendAfterClose::Send),
- this, new SyncChannelTestMsg_NoArgs));
+ FROM_HERE,
+ base::Bind(base::IgnoreResult(&ServerSendAfterClose::Send),
+ base::Unretained(this), new SyncChannelTestMsg_NoArgs));
return true;
}
@@ -1186,7 +1187,8 @@ class RestrictedDispatchServer : public Worker {
// Signal the event after the message has been sent on the channel, on the
// IPC thread.
ipc_thread().task_runner()->PostTask(
- FROM_HERE, base::Bind(&RestrictedDispatchServer::OnPingSent, this));
+ FROM_HERE, base::Bind(&RestrictedDispatchServer::OnPingSent,
+ base::Unretained(this)));
}
void OnPingTTL(int ping, int* out) {
@@ -1267,7 +1269,8 @@ class RestrictedDispatchClient : public Worker {
channel()->SetRestrictDispatchChannelGroup(1);
server_->ListenerThread()->task_runner()->PostTask(
- FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing, server_, 1));
+ FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing,
+ base::Unretained(server_), 1));
sent_ping_event_->Wait();
Send(new SyncChannelTestMsg_NoArgs);
if (ping_ == 1)
@@ -1280,7 +1283,8 @@ class RestrictedDispatchClient : public Worker {
this, ipc_thread().task_runner(), true, shutdown_event());
server_->ListenerThread()->task_runner()->PostTask(
- FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing, server_, 2));
+ FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing,
+ base::Unretained(server_), 2));
sent_ping_event_->Wait();
// Check that the incoming message is *not* dispatched when sending on the
// non restricted channel.
@@ -1305,8 +1309,8 @@ class RestrictedDispatchClient : public Worker {
// Check that the incoming message on the non-restricted channel is
// dispatched when sending on the restricted channel.
server2_->ListenerThread()->task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&NonRestrictedDispatchServer::OnDoPingTTL, server2_, 3));
+ FROM_HERE, base::Bind(&NonRestrictedDispatchServer::OnDoPingTTL,
+ base::Unretained(server2_), 3));
int value = 0;
Send(new SyncChannelTestMsg_PingTTL(4, &value));
if (ping_ == 3 && value == 4)
@@ -1539,11 +1543,12 @@ class RestrictedDispatchDeadlockClient1 : public Worker {
void Run() override {
server_ready_event_->Wait();
server_->ListenerThread()->task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&RestrictedDispatchDeadlockServer::OnDoServerTask, server_));
+ FROM_HERE, base::Bind(&RestrictedDispatchDeadlockServer::OnDoServerTask,
+ base::Unretained(server_)));
peer_->ListenerThread()->task_runner()->PostTask(
FROM_HERE,
- base::Bind(&RestrictedDispatchDeadlockClient2::OnDoClient2Task, peer_));
+ base::Bind(&RestrictedDispatchDeadlockClient2::OnDoClient2Task,
+ base::Unretained(peer_)));
events_[0]->Wait();
events_[1]->Wait();
DCHECK(received_msg_ == false);
diff --git a/chromium/ipc/ipc_sync_message.cc b/chromium/ipc/ipc_sync_message.cc
index ba87de8f22e..34cb875db2f 100644
--- a/chromium/ipc/ipc_sync_message.cc
+++ b/chromium/ipc/ipc_sync_message.cc
@@ -14,7 +14,7 @@
namespace {
-base::StaticAtomicSequenceNumber g_next_id;
+base::AtomicSequenceNumber g_next_id;
} // namespace
diff --git a/chromium/ipc/ipc_sync_message_filter.cc b/chromium/ipc/ipc_sync_message_filter.cc
index 15ffdbc6ff7..86d4ce11df5 100644
--- a/chromium/ipc/ipc_sync_message_filter.cc
+++ b/chromium/ipc/ipc_sync_message_filter.cc
@@ -73,9 +73,10 @@ bool SyncMessageFilter::Send(Message* message) {
bool shutdown = false;
scoped_refptr<mojo::SyncHandleRegistry> registry =
mojo::SyncHandleRegistry::current();
- registry->RegisterEvent(shutdown_event_,
- base::Bind(&OnEventReady, &shutdown));
- registry->RegisterEvent(&done_event, base::Bind(&OnEventReady, &done));
+ auto on_shutdown_callback = base::Bind(&OnEventReady, &shutdown);
+ auto on_done_callback = base::Bind(&OnEventReady, &done);
+ registry->RegisterEvent(shutdown_event_, on_shutdown_callback);
+ registry->RegisterEvent(&done_event, on_done_callback);
const bool* stop_flags[] = { &done, &shutdown };
registry->Wait(stop_flags, 2);
@@ -84,8 +85,8 @@ bool SyncMessageFilter::Send(Message* message) {
"SyncMessageFilter::Send", &done_event);
}
- registry->UnregisterEvent(shutdown_event_);
- registry->UnregisterEvent(&done_event);
+ registry->UnregisterEvent(shutdown_event_, on_shutdown_callback);
+ registry->UnregisterEvent(&done_event, on_done_callback);
{
base::AutoLock auto_lock(lock_);
diff --git a/chromium/ipc/ipc_test.mojom b/chromium/ipc/ipc_test.mojom
index 8af397a3a42..33181b82659 100644
--- a/chromium/ipc/ipc_test.mojom
+++ b/chromium/ipc/ipc_test.mojom
@@ -31,6 +31,8 @@ interface IndirectTestDriver {
interface Reflector {
Ping(string value) => (string value);
+ [Sync]
+ SyncPing(string value) => (string response);
Quit();
};
diff --git a/chromium/ipc/test_proto.proto b/chromium/ipc/test_proto.proto
new file mode 100644
index 00000000000..98525edee21
--- /dev/null
+++ b/chromium/ipc/test_proto.proto
@@ -0,0 +1,20 @@
+// Copyright 2017 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.
+
+syntax = "proto2";
+option optimize_for = LITE_RUNTIME;
+package ipc_message_utils_test;
+
+// This is a simple dummy protocol buffer that is used for testing handling of
+// protocol buffers in ipc_message_utils.
+
+message TestMessage1 {
+ optional int32 number = 1;
+}
+
+message TestMessage2 {
+ repeated int32 numbers = 1;
+ repeated string strings = 2;
+ repeated TestMessage1 messages = 3;
+}