summaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authortsergeant <tsergeant@chromium.org>2016-03-09 19:51:33 -0800
committerCommit bot <commit-bot@chromium.org>2016-03-10 03:53:03 +0000
commit896012863947ba511c55ce7c65aa1002cd3894eb (patch)
tree81614102d853a7d1fc16e207083905ece2ae14e3 /ipc
parent4819f8b1cfab20b5598d5426ff48dbeae1b1955a (diff)
downloadchromium_src-896012863947ba511c55ce7c65aa1002cd3894eb.zip
chromium_src-896012863947ba511c55ce7c65aa1002cd3894eb.tar.gz
chromium_src-896012863947ba511c55ce7c65aa1002cd3894eb.tar.bz2
Revert of Fix failing tests with ChannelMojo enabled. (patchset #3 id:300001 of https://codereview.chromium.org/1768903002/ )
Reason for revert: This CL is causing failures in ipc_mojo_unittests. See: https://build.chromium.org/p/chromium.linux/builders/Linux%20Tests%20%28dbg%29%281%29/builds/52715 https://build.chromium.org/p/chromium.linux/builders/Linux%20Tests%20%28dbg%29%281%29%2832%29/builds/26588 Original issue's description: > Fix failing tests with ChannelMojo enabled. > > This ChannelMojo to: > - take a ScopedMessagePipeHandle instead of a string token so an > in-process renderer can be passed the message pipe directly; > - send brokered attachments as mojo handles; and > - offer messages to AttachmentBroker. > > This also fixes and re-enables ipc_channel_mojo_unittest.cc. > > BUG=579813 > > Committed: https://crrev.com/013cfed7ecf91b0700bec7147631d4fbedb6b64e > Cr-Commit-Position: refs/heads/master@{#380294} TBR=rockot@chromium.org,tsepez@chromium.org,ben@chromium.org,sammc@chromium.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=579813 Review URL: https://codereview.chromium.org/1784773002 Cr-Commit-Position: refs/heads/master@{#380325}
Diffstat (limited to 'ipc')
-rw-r--r--ipc/handle_attachment_win.cc4
-rw-r--r--ipc/handle_attachment_win.h7
-rw-r--r--ipc/mach_port_attachment_mac.cc3
-rw-r--r--ipc/mach_port_attachment_mac.h7
-rw-r--r--ipc/mojo/BUILD.gn5
-rw-r--r--ipc/mojo/ipc.mojom14
-rw-r--r--ipc/mojo/ipc_channel_mojo.cc286
-rw-r--r--ipc/mojo/ipc_channel_mojo.h29
-rw-r--r--ipc/mojo/ipc_channel_mojo_unittest.cc404
-rw-r--r--ipc/mojo/ipc_message_pipe_reader.cc3
-rw-r--r--ipc/mojo/ipc_message_pipe_reader.h4
-rw-r--r--ipc/mojo/ipc_mojo.gyp5
-rw-r--r--ipc/mojo/ipc_mojo_bootstrap.cc23
-rw-r--r--ipc/mojo/ipc_mojo_bootstrap.h12
-rw-r--r--ipc/mojo/ipc_mojo_bootstrap_unittest.cc14
-rw-r--r--ipc/mojo/ipc_mojo_handle_attachment.cc3
-rw-r--r--ipc/mojo/ipc_mojo_perftest.cc45
17 files changed, 428 insertions, 440 deletions
diff --git a/ipc/handle_attachment_win.cc b/ipc/handle_attachment_win.cc
index cb6a7ba..39c4ef7 100644
--- a/ipc/handle_attachment_win.cc
+++ b/ipc/handle_attachment_win.cc
@@ -24,10 +24,6 @@ HandleAttachmentWin::HandleAttachmentWin(const HANDLE& handle,
}
}
-HandleAttachmentWin::HandleAttachmentWin(const HANDLE& handle,
- FromWire from_wire)
- : handle_(handle), permissions_(HandleWin::INVALID), owns_handle_(true) {}
-
HandleAttachmentWin::HandleAttachmentWin(const WireFormat& wire_format)
: BrokerableAttachment(wire_format.attachment_id),
handle_(LongToHandle(wire_format.handle)),
diff --git a/ipc/handle_attachment_win.h b/ipc/handle_attachment_win.h
index ff0ce91..5e04bdb 100644
--- a/ipc/handle_attachment_win.h
+++ b/ipc/handle_attachment_win.h
@@ -58,13 +58,6 @@ class IPC_EXPORT HandleAttachmentWin : public BrokerableAttachment {
// result. Should only be called by the sender of a Chrome IPC message.
HandleAttachmentWin(const HANDLE& handle, HandleWin::Permissions permissions);
- enum FromWire {
- FROM_WIRE,
- };
- // This constructor takes ownership of |handle|. Should only be called by the
- // receiver of a Chrome IPC message.
- HandleAttachmentWin(const HANDLE& handle, FromWire from_wire);
-
// This constructor takes ownership of |wire_format.handle| without making a
// copy. Should only be called by the receiver of a Chrome IPC message.
explicit HandleAttachmentWin(const WireFormat& wire_format);
diff --git a/ipc/mach_port_attachment_mac.cc b/ipc/mach_port_attachment_mac.cc
index 47fd4e9..65baa34 100644
--- a/ipc/mach_port_attachment_mac.cc
+++ b/ipc/mach_port_attachment_mac.cc
@@ -20,9 +20,6 @@ MachPortAttachmentMac::MachPortAttachmentMac(mach_port_t mach_port)
<< "MachPortAttachmentMac mach_port_mod_refs";
}
}
-MachPortAttachmentMac::MachPortAttachmentMac(mach_port_t mach_port,
- FromWire from_wire)
- : mach_port_(mach_port), owns_mach_port_(true) {}
MachPortAttachmentMac::MachPortAttachmentMac(const WireFormat& wire_format)
: BrokerableAttachment(wire_format.attachment_id),
diff --git a/ipc/mach_port_attachment_mac.h b/ipc/mach_port_attachment_mac.h
index 658cff4..244014e 100644
--- a/ipc/mach_port_attachment_mac.h
+++ b/ipc/mach_port_attachment_mac.h
@@ -51,13 +51,6 @@ class IPC_EXPORT MachPortAttachmentMac : public BrokerableAttachment {
// IPC message.
explicit MachPortAttachmentMac(mach_port_t mach_port);
- enum FromWire {
- FROM_WIRE,
- };
- // This constructor takes ownership of |mach_port|, but does not modify its
- // ref count. Should only be called by the receiver of a Chrome IPC message.
- MachPortAttachmentMac(mach_port_t mach_port, FromWire from_wire);
-
// This constructor takes ownership of |wire_format.mach_port|, but does not
// modify its ref count. Should only be called by the receiver of a Chrome IPC
// message.
diff --git a/ipc/mojo/BUILD.gn b/ipc/mojo/BUILD.gn
index 22f063a..9804845 100644
--- a/ipc/mojo/BUILD.gn
+++ b/ipc/mojo/BUILD.gn
@@ -43,7 +43,10 @@ component("mojo") {
test("ipc_mojo_unittests") {
sources = [
- "ipc_channel_mojo_unittest.cc",
+ # TODO(rockot): Re-enable these when we're ready to start using ChannelMojo
+ # again. They need to be updated to support multiprocess testing with the
+ # current Mojo EDK implementation.
+ #"ipc_channel_mojo_unittest.cc",
"ipc_mojo_bootstrap_unittest.cc",
"run_all_unittests.cc",
]
diff --git a/ipc/mojo/ipc.mojom b/ipc/mojo/ipc.mojom
index 6b69ced..dfc5770 100644
--- a/ipc/mojo/ipc.mojom
+++ b/ipc/mojo/ipc.mojom
@@ -4,21 +4,9 @@
module IPC.mojom;
-struct SerializedHandle {
- handle the_handle;
-
- enum Type {
- MOJO_HANDLE,
- WIN_HANDLE,
- MACH_PORT,
- };
-
- Type type;
-};
-
struct Message {
array<uint8> data;
- array<SerializedHandle>? handles;
+ array<handle>? handles;
};
interface Channel {
diff --git a/ipc/mojo/ipc_channel_mojo.cc b/ipc/mojo/ipc_channel_mojo.cc
index 8832d8d..6993648 100644
--- a/ipc/mojo/ipc_channel_mojo.cc
+++ b/ipc/mojo/ipc_channel_mojo.cc
@@ -29,59 +29,30 @@
#include "ipc/ipc_platform_file_attachment_posix.h"
#endif
-#if defined(OS_MACOSX)
-#include "ipc/mach_port_attachment_mac.h"
-#endif
-
-#if defined(OS_WIN)
-#include "ipc/handle_attachment_win.h"
-#endif
-
namespace IPC {
namespace {
class MojoChannelFactory : public ChannelFactory {
public:
- MojoChannelFactory(mojo::ScopedMessagePipeHandle handle, Channel::Mode mode)
- : handle_(std::move(handle)), mode_(mode) {}
+ MojoChannelFactory(const std::string& token, Channel::Mode mode)
+ : token_(token), mode_(mode) {}
- std::string GetName() const override { return ""; }
+ std::string GetName() const override {
+ return token_;
+ }
scoped_ptr<Channel> BuildChannel(Listener* listener) override {
- return ChannelMojo::Create(std::move(handle_), mode_, listener);
+ return ChannelMojo::Create(token_, mode_, listener);
}
private:
- mojo::ScopedMessagePipeHandle handle_;
+ const std::string token_;
const Channel::Mode mode_;
DISALLOW_COPY_AND_ASSIGN(MojoChannelFactory);
};
-mojom::SerializedHandlePtr CreateSerializedHandle(
- mojo::ScopedHandle handle,
- mojom::SerializedHandle::Type type) {
- mojom::SerializedHandlePtr serialized_handle = mojom::SerializedHandle::New();
- serialized_handle->the_handle = std::move(handle);
- serialized_handle->type = type;
- return serialized_handle;
-}
-
-MojoResult WrapPlatformHandle(mojo::edk::ScopedPlatformHandle handle,
- mojom::SerializedHandle::Type type,
- mojom::SerializedHandlePtr* serialized) {
- MojoHandle wrapped_handle;
- MojoResult wrap_result = mojo::edk::CreatePlatformHandleWrapper(
- std::move(handle), &wrapped_handle);
- if (wrap_result != MOJO_RESULT_OK)
- return wrap_result;
-
- *serialized = CreateSerializedHandle(
- mojo::MakeScopedHandle(mojo::Handle(wrapped_handle)), type);
- return MOJO_RESULT_OK;
-}
-
#if defined(OS_POSIX) && !defined(OS_NACL)
base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) {
@@ -91,109 +62,6 @@ base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) {
#endif
-MojoResult WrapAttachmentImpl(MessageAttachment* attachment,
- mojom::SerializedHandlePtr* serialized) {
- if (attachment->GetType() == MessageAttachment::TYPE_MOJO_HANDLE) {
- *serialized = CreateSerializedHandle(
- static_cast<internal::MojoHandleAttachment&>(*attachment).TakeHandle(),
- mojom::SerializedHandle::Type::MOJO_HANDLE);
- return MOJO_RESULT_OK;
- }
-#if defined(OS_POSIX) && !defined(OS_NACL)
- if (attachment->GetType() == MessageAttachment::TYPE_PLATFORM_FILE) {
- // We dup() the handles in IPC::Message to transmit.
- // IPC::MessageAttachmentSet has intricate lifecycle semantics
- // of FDs, so just to dup()-and-own them is the safest option.
- base::ScopedFD file = TakeOrDupFile(
- static_cast<IPC::internal::PlatformFileAttachment*>(attachment));
- if (!file.is_valid()) {
- DPLOG(WARNING) << "Failed to dup FD to transmit.";
- return MOJO_RESULT_UNKNOWN;
- }
-
- return WrapPlatformHandle(mojo::edk::ScopedPlatformHandle(
- mojo::edk::PlatformHandle(file.release())),
- mojom::SerializedHandle::Type::MOJO_HANDLE,
- serialized);
- }
-#endif
-#if defined(OS_MACOSX)
- DCHECK_EQ(attachment->GetType(),
- MessageAttachment::TYPE_BROKERABLE_ATTACHMENT);
- DCHECK_EQ(static_cast<BrokerableAttachment&>(*attachment).GetBrokerableType(),
- BrokerableAttachment::MACH_PORT);
- internal::MachPortAttachmentMac& mach_port_attachment =
- static_cast<internal::MachPortAttachmentMac&>(*attachment);
- MojoResult result = WrapPlatformHandle(
- mojo::edk::ScopedPlatformHandle(
- mojo::edk::PlatformHandle(mach_port_attachment.get_mach_port())),
- mojom::SerializedHandle::Type::MACH_PORT, serialized);
- mach_port_attachment.reset_mach_port_ownership();
- return result;
-#elif defined(OS_WIN)
- DCHECK_EQ(attachment->GetType(),
- MessageAttachment::TYPE_BROKERABLE_ATTACHMENT);
- DCHECK_EQ(static_cast<BrokerableAttachment&>(*attachment).GetBrokerableType(),
- BrokerableAttachment::WIN_HANDLE);
- internal::HandleAttachmentWin& handle_attachment =
- static_cast<internal::HandleAttachmentWin&>(*attachment);
- MojoResult result = WrapPlatformHandle(
- mojo::edk::ScopedPlatformHandle(
- mojo::edk::PlatformHandle(handle_attachment.get_handle())),
- mojom::SerializedHandle::Type::WIN_HANDLE, serialized);
- handle_attachment.reset_handle_ownership();
- return result;
-#else
- NOTREACHED();
- return MOJO_RESULT_UNKNOWN;
-#endif // defined(OS_MACOSX)
-}
-
-MojoResult WrapAttachment(MessageAttachment* attachment,
- mojo::Array<mojom::SerializedHandlePtr>* handles) {
- mojom::SerializedHandlePtr serialized_handle;
- MojoResult wrap_result = WrapAttachmentImpl(attachment, &serialized_handle);
- if (wrap_result != MOJO_RESULT_OK) {
- LOG(WARNING) << "Pipe failed to wrap handles. Closing: " << wrap_result;
- return wrap_result;
- }
- handles->push_back(std::move(serialized_handle));
- return MOJO_RESULT_OK;
-}
-
-MojoResult UnwrapAttachment(mojom::SerializedHandlePtr handle,
- scoped_refptr<MessageAttachment>* attachment) {
- if (handle->type == mojom::SerializedHandle::Type::MOJO_HANDLE) {
- *attachment =
- new IPC::internal::MojoHandleAttachment(std::move(handle->the_handle));
- return MOJO_RESULT_OK;
- }
- mojo::edk::ScopedPlatformHandle platform_handle;
- MojoResult unwrap_result = mojo::edk::PassWrappedPlatformHandle(
- handle->the_handle.release().value(), &platform_handle);
- if (unwrap_result != MOJO_RESULT_OK)
- return unwrap_result;
-#if defined(OS_MACOSX)
- if (handle->type == mojom::SerializedHandle::Type::MACH_PORT &&
- platform_handle.get().type == mojo::edk::PlatformHandle::Type::MACH) {
- *attachment = new internal::MachPortAttachmentMac(
- platform_handle.release().port,
- internal::MachPortAttachmentMac::FROM_WIRE);
- return MOJO_RESULT_OK;
- }
-#endif // defined(OS_MACOSX)
-#if defined(OS_WIN)
- if (handle->type == mojom::SerializedHandle::Type::WIN_HANDLE) {
- *attachment = new internal::HandleAttachmentWin(
- platform_handle.release().handle,
- internal::HandleAttachmentWin::FROM_WIRE);
- return MOJO_RESULT_OK;
- }
-#endif // defined(OS_WIN)
- NOTREACHED();
- return MOJO_RESULT_UNKNOWN;
-}
-
} // namespace
//------------------------------------------------------------------------------
@@ -206,40 +74,53 @@ bool ChannelMojo::ShouldBeUsed() {
}
// static
-scoped_ptr<ChannelMojo> ChannelMojo::Create(
- mojo::ScopedMessagePipeHandle handle,
- Mode mode,
- Listener* listener) {
- return make_scoped_ptr(new ChannelMojo(std::move(handle), mode, listener));
+scoped_ptr<ChannelMojo> ChannelMojo::Create(const std::string& token,
+ Mode mode,
+ Listener* listener) {
+ return make_scoped_ptr(
+ new ChannelMojo(token, mode, listener));
}
// static
scoped_ptr<ChannelFactory> ChannelMojo::CreateServerFactory(
- mojo::ScopedMessagePipeHandle handle) {
+ const std::string& token) {
return make_scoped_ptr(
- new MojoChannelFactory(std::move(handle), Channel::MODE_SERVER));
+ new MojoChannelFactory(token, Channel::MODE_SERVER));
}
// static
scoped_ptr<ChannelFactory> ChannelMojo::CreateClientFactory(
- mojo::ScopedMessagePipeHandle handle) {
+ const std::string& token) {
return make_scoped_ptr(
- new MojoChannelFactory(std::move(handle), Channel::MODE_CLIENT));
+ new MojoChannelFactory(token, Channel::MODE_CLIENT));
}
-ChannelMojo::ChannelMojo(mojo::ScopedMessagePipeHandle handle,
+ChannelMojo::ChannelMojo(const std::string& token,
Mode mode,
Listener* listener)
- : listener_(listener), waiting_connect_(true), weak_factory_(this) {
+ : listener_(listener),
+ peer_pid_(base::kNullProcessId),
+ waiting_connect_(true),
+ weak_factory_(this) {
// Create MojoBootstrap after all members are set as it touches
// ChannelMojo from a different thread.
- bootstrap_ = MojoBootstrap::Create(std::move(handle), mode, this);
+ bootstrap_ = MojoBootstrap::Create(token, mode, this);
}
ChannelMojo::~ChannelMojo() {
Close();
}
+scoped_ptr<internal::MessagePipeReader, ChannelMojo::ReaderDeleter>
+ChannelMojo::CreateMessageReader(mojom::ChannelAssociatedPtrInfo sender,
+ mojom::ChannelAssociatedRequest receiver) {
+ mojom::ChannelAssociatedPtr sender_ptr;
+ sender_ptr.Bind(std::move(sender));
+ return scoped_ptr<internal::MessagePipeReader, ChannelMojo::ReaderDeleter>(
+ new internal::MessagePipeReader(std::move(sender_ptr),
+ std::move(receiver), this));
+}
+
bool ChannelMojo::Connect() {
DCHECK(!message_reader_);
bootstrap_->Connect();
@@ -257,8 +138,8 @@ void ChannelMojo::OnPipesAvailable(
mojom::ChannelAssociatedPtrInfo send_channel,
mojom::ChannelAssociatedRequest receive_channel,
int32_t peer_pid) {
- InitMessageReader(std::move(send_channel), std::move(receive_channel),
- peer_pid);
+ set_peer_pid(peer_pid);
+ InitMessageReader(std::move(send_channel), std::move(receive_channel));
}
void ChannelMojo::OnBootstrapError() {
@@ -266,13 +147,9 @@ void ChannelMojo::OnBootstrapError() {
}
void ChannelMojo::InitMessageReader(mojom::ChannelAssociatedPtrInfo sender,
- mojom::ChannelAssociatedRequest receiver,
- base::ProcessId peer_pid) {
- mojom::ChannelAssociatedPtr sender_ptr;
- sender_ptr.Bind(std::move(sender));
- scoped_ptr<internal::MessagePipeReader, ChannelMojo::ReaderDeleter> reader(
- new internal::MessagePipeReader(std::move(sender_ptr),
- std::move(receiver), peer_pid, this));
+ mojom::ChannelAssociatedRequest receiver) {
+ scoped_ptr<internal::MessagePipeReader, ChannelMojo::ReaderDeleter> reader =
+ CreateMessageReader(std::move(sender), std::move(receiver));
for (size_t i = 0; i < pending_messages_.size(); ++i) {
bool sent = reader->Send(std::move(pending_messages_[i]));
@@ -315,10 +192,7 @@ bool ChannelMojo::Send(Message* message) {
}
base::ProcessId ChannelMojo::GetPeerPID() const {
- if (!message_reader_)
- return base::kNullProcessId;
-
- return message_reader_->GetPeerPid();
+ return peer_pid_;
}
base::ProcessId ChannelMojo::GetSelfPID() const {
@@ -329,10 +203,6 @@ void ChannelMojo::OnMessageReceived(const Message& message) {
TRACE_EVENT2("ipc,toplevel", "ChannelMojo::OnMessageReceived",
"class", IPC_MESSAGE_ID_CLASS(message.type()),
"line", IPC_MESSAGE_ID_LINE(message.type()));
- if (AttachmentBroker* broker = AttachmentBroker::GetGlobal()) {
- if (broker->OnMessageReceived(message))
- return;
- }
listener_->OnMessageReceived(message);
if (message.dispatch_error())
listener_->OnBadMessageReceived(message);
@@ -351,53 +221,81 @@ base::ScopedFD ChannelMojo::TakeClientFileDescriptor() {
// static
MojoResult ChannelMojo::ReadFromMessageAttachmentSet(
Message* message,
- mojo::Array<mojom::SerializedHandlePtr>* handles) {
+ mojo::Array<mojo::ScopedHandle>* handles) {
+ // We dup() the handles in IPC::Message to transmit.
+ // IPC::MessageAttachmentSet has intricate lifecycle semantics
+ // of FDs, so just to dup()-and-own them is the safest option.
if (message->HasAttachments()) {
MessageAttachmentSet* set = message->attachment_set();
for (unsigned i = 0; i < set->num_non_brokerable_attachments(); ++i) {
- MojoResult result = WrapAttachment(
- set->GetNonBrokerableAttachmentAt(i).get(), handles);
- if (result != MOJO_RESULT_OK) {
- set->CommitAllDescriptors();
- return result;
- }
- }
- for (unsigned i = 0; i < set->num_brokerable_attachments(); ++i) {
- MojoResult result =
- WrapAttachment(set->GetBrokerableAttachmentAt(i).get(), handles);
- if (result != MOJO_RESULT_OK) {
- set->CommitAllDescriptors();
- return result;
+ scoped_refptr<MessageAttachment> attachment =
+ set->GetNonBrokerableAttachmentAt(i);
+ switch (attachment->GetType()) {
+ case MessageAttachment::TYPE_PLATFORM_FILE:
+#if defined(OS_POSIX) && !defined(OS_NACL)
+ {
+ base::ScopedFD file =
+ TakeOrDupFile(static_cast<IPC::internal::PlatformFileAttachment*>(
+ attachment.get()));
+ if (!file.is_valid()) {
+ DPLOG(WARNING) << "Failed to dup FD to transmit.";
+ set->CommitAllDescriptors();
+ return MOJO_RESULT_UNKNOWN;
+ }
+
+ MojoHandle wrapped_handle;
+ MojoResult wrap_result = mojo::edk::CreatePlatformHandleWrapper(
+ mojo::edk::ScopedPlatformHandle(
+ mojo::edk::PlatformHandle(file.release())),
+ &wrapped_handle);
+ if (MOJO_RESULT_OK != wrap_result) {
+ LOG(WARNING) << "Pipe failed to wrap handles. Closing: "
+ << wrap_result;
+ set->CommitAllDescriptors();
+ return wrap_result;
+ }
+
+ handles->push_back(
+ mojo::MakeScopedHandle(mojo::Handle(wrapped_handle)));
+ }
+#else
+ NOTREACHED();
+#endif // defined(OS_POSIX) && !defined(OS_NACL)
+ break;
+ case MessageAttachment::TYPE_MOJO_HANDLE: {
+ mojo::ScopedHandle handle =
+ static_cast<IPC::internal::MojoHandleAttachment*>(
+ attachment.get())->TakeHandle();
+ handles->push_back(std::move(handle));
+ } break;
+ case MessageAttachment::TYPE_BROKERABLE_ATTACHMENT:
+ // Brokerable attachments are handled by the AttachmentBroker so
+ // there's no need to do anything here.
+ NOTREACHED();
+ break;
}
}
+
set->CommitAllDescriptors();
}
+
return MOJO_RESULT_OK;
}
// static
MojoResult ChannelMojo::WriteToMessageAttachmentSet(
- mojo::Array<mojom::SerializedHandlePtr> handle_buffer,
+ mojo::Array<mojo::ScopedHandle> handle_buffer,
Message* message) {
for (size_t i = 0; i < handle_buffer.size(); ++i) {
- scoped_refptr<MessageAttachment> unwrapped_attachment;
- MojoResult unwrap_result = UnwrapAttachment(std::move(handle_buffer[i]),
- &unwrapped_attachment);
- if (unwrap_result != MOJO_RESULT_OK) {
- LOG(WARNING) << "Pipe failed to unwrap handles. Closing: "
- << unwrap_result;
- return unwrap_result;
- }
- DCHECK(unwrapped_attachment);
-
bool ok = message->attachment_set()->AddAttachment(
- std::move(unwrapped_attachment));
+ new IPC::internal::MojoHandleAttachment(std::move(handle_buffer[i])));
DCHECK(ok);
if (!ok) {
LOG(ERROR) << "Failed to add new Mojo handle.";
return MOJO_RESULT_UNKNOWN;
}
}
+
return MOJO_RESULT_OK;
}
diff --git a/ipc/mojo/ipc_channel_mojo.h b/ipc/mojo/ipc_channel_mojo.h
index c1b659a..a996790 100644
--- a/ipc/mojo/ipc_channel_mojo.h
+++ b/ipc/mojo/ipc_channel_mojo.h
@@ -26,9 +26,8 @@ namespace IPC {
// Mojo-based IPC::Channel implementation over a Mojo message pipe.
//
-// ChannelMojo builds a Mojo MessagePipe using the provided message pipe
-// |handle| and builds an associated interface for each direction on the
-// channel.
+// ChannelMojo builds a Mojo MessagePipe using the provided token and builds an
+// associated interface for each direction on the channel.
//
// TODO(morrita): Add APIs to create extra MessagePipes to let
// Mojo-based objects talk over this Channel.
@@ -41,8 +40,8 @@ class IPC_MOJO_EXPORT ChannelMojo
// True if ChannelMojo should be used regardless of the flag.
static bool ShouldBeUsed();
- // Creates a ChannelMojo.
- static scoped_ptr<ChannelMojo> Create(mojo::ScopedMessagePipeHandle handle,
+ // Create ChannelMojo. A bootstrap channel is created as well.
+ static scoped_ptr<ChannelMojo> Create(const std::string& token,
Mode mode,
Listener* listener);
@@ -50,10 +49,10 @@ class IPC_MOJO_EXPORT ChannelMojo
// The factory is used to create Mojo-based ChannelProxy family.
// |host| must not be null.
static scoped_ptr<ChannelFactory> CreateServerFactory(
- mojo::ScopedMessagePipeHandle handle);
+ const std::string& token);
static scoped_ptr<ChannelFactory> CreateClientFactory(
- mojo::ScopedMessagePipeHandle handle);
+ const std::string& token);
~ChannelMojo() override;
@@ -72,11 +71,11 @@ class IPC_MOJO_EXPORT ChannelMojo
// These access protected API of IPC::Message, which has ChannelMojo
// as a friend class.
static MojoResult WriteToMessageAttachmentSet(
- mojo::Array<mojom::SerializedHandlePtr> handle_buffer,
+ mojo::Array<mojo::ScopedHandle> handle_buffer,
Message* message);
static MojoResult ReadFromMessageAttachmentSet(
Message* message,
- mojo::Array<mojom::SerializedHandlePtr>* handles);
+ mojo::Array<mojo::ScopedHandle>* handles);
// MojoBootstrapDelegate implementation
void OnPipesAvailable(mojom::ChannelAssociatedPtrInfo send_channel,
@@ -90,21 +89,27 @@ class IPC_MOJO_EXPORT ChannelMojo
void OnPipeError(internal::MessagePipeReader* reader) override;
private:
- ChannelMojo(mojo::ScopedMessagePipeHandle handle,
+ ChannelMojo(const std::string& token,
Mode mode,
Listener* listener);
void InitMessageReader(mojom::ChannelAssociatedPtrInfo sender,
- mojom::ChannelAssociatedRequest receiver,
- base::ProcessId peer_pid);
+ mojom::ChannelAssociatedRequest receiver);
+
+ void set_peer_pid(base::ProcessId pid) { peer_pid_ = pid; }
// ChannelMojo needs to kill its MessagePipeReader in delayed manner
// because the channel wants to kill these readers during the
// notifications invoked by them.
typedef internal::MessagePipeReader::DelayedDeleter ReaderDeleter;
+ scoped_ptr<internal::MessagePipeReader, ReaderDeleter> CreateMessageReader(
+ mojom::ChannelAssociatedPtrInfo sender,
+ mojom::ChannelAssociatedRequest receiver);
+
scoped_ptr<MojoBootstrap> bootstrap_;
Listener* listener_;
+ base::ProcessId peer_pid_;
scoped_ptr<internal::MessagePipeReader, ReaderDeleter> message_reader_;
std::vector<scoped_ptr<Message>> pending_messages_;
diff --git a/ipc/mojo/ipc_channel_mojo_unittest.cc b/ipc/mojo/ipc_channel_mojo_unittest.cc
index ac09ac3..ec5efa6 100644
--- a/ipc/mojo/ipc_channel_mojo_unittest.cc
+++ b/ipc/mojo/ipc_channel_mojo_unittest.cc
@@ -15,7 +15,6 @@
#include "base/pickle.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
-#include "base/test/test_io_thread.h"
#include "base/test/test_timeouts.h"
#include "base/thread_task_runner_handle.h"
#include "base/threading/thread.h"
@@ -23,45 +22,21 @@
#include "ipc/ipc_message.h"
#include "ipc/ipc_test_base.h"
#include "ipc/ipc_test_channel_listener.h"
-#include "ipc/mojo/ipc_channel_mojo.h"
#include "ipc/mojo/ipc_mojo_handle_attachment.h"
#include "ipc/mojo/ipc_mojo_message_helper.h"
#include "ipc/mojo/ipc_mojo_param_traits.h"
-#include "mojo/edk/test/mojo_test_base.h"
-#include "mojo/edk/test/multiprocess_test_helper.h"
-#include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_POSIX)
#include "base/file_descriptor_posix.h"
#include "ipc/ipc_platform_file_attachment_posix.h"
#endif
-#define DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(client_name, test_base) \
- class client_name##_MainFixture : public test_base { \
- public: \
- void Main(); \
- }; \
- MULTIPROCESS_TEST_MAIN_WITH_SETUP( \
- client_name##TestChildMain, \
- ::mojo::edk::test::MultiprocessTestHelper::ChildSetup) { \
- CHECK(!mojo::edk::test::MultiprocessTestHelper::primordial_pipe_token \
- .empty()); \
- client_name##_MainFixture test; \
- test.Init(mojo::edk::CreateChildMessagePipe( \
- mojo::edk::test::MultiprocessTestHelper::primordial_pipe_token)); \
- test.Main(); \
- return (::testing::Test::HasFatalFailure() || \
- ::testing::Test::HasNonfatalFailure()) \
- ? 1 \
- : 0; \
- } \
- void client_name##_MainFixture::Main()
-
namespace {
class ListenerThatExpectsOK : public IPC::Listener {
public:
- ListenerThatExpectsOK() : received_ok_(false) {}
+ ListenerThatExpectsOK()
+ : received_ok_(false) {}
~ListenerThatExpectsOK() override {}
@@ -83,8 +58,8 @@ class ListenerThatExpectsOK : public IPC::Listener {
}
static void SendOK(IPC::Sender* sender) {
- IPC::Message* message =
- new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL);
+ IPC::Message* message = new IPC::Message(
+ 0, 2, IPC::Message::PRIORITY_NORMAL);
message->WriteString(std::string("OK"));
ASSERT_TRUE(sender->Send(message));
}
@@ -95,12 +70,13 @@ class ListenerThatExpectsOK : public IPC::Listener {
class ChannelClient {
public:
- void Init(mojo::ScopedMessagePipeHandle handle) {
- handle_ = std::move(handle);
- }
- void Connect(IPC::Listener* listener) {
- channel_ = IPC::ChannelMojo::Create(std::move(handle_),
+ explicit ChannelClient(IPC::Listener* listener, const char* name) {
+ channel_ = IPC::ChannelMojo::Create(main_message_loop_.task_runner(),
+ IPCTestBase::GetChannelName(name),
IPC::Channel::MODE_CLIENT, listener);
+ }
+
+ void Connect() {
CHECK(channel_->Connect());
}
@@ -117,46 +93,48 @@ class ChannelClient {
private:
base::MessageLoopForIO main_message_loop_;
- mojo::ScopedMessagePipeHandle handle_;
scoped_ptr<IPC::ChannelMojo> channel_;
};
-class IPCChannelMojoTest : public testing::Test {
+class IPCChannelMojoTestBase : public IPCTestBase {
public:
- IPCChannelMojoTest() : io_thread_(base::TestIOThread::Mode::kAutoStart) {}
-
- void TearDown() override { base::RunLoop().RunUntilIdle(); }
-
void InitWithMojo(const std::string& test_client_name) {
- handle_ = helper_.StartChild(test_client_name);
- }
-
- void CreateChannel(IPC::Listener* listener) {
- channel_ = IPC::ChannelMojo::Create(std::move(handle_),
- IPC::Channel::MODE_SERVER, listener);
+ Init(test_client_name);
}
- bool ConnectChannel() { return channel_->Connect(); }
-
- void DestroyChannel() { channel_.reset(); }
+ void TearDown() override {
+ // Make sure Mojo IPC support is properly shutdown on the I/O loop before
+ // TearDown continues.
+ base::RunLoop run_loop;
+ task_runner()->PostTask(FROM_HERE, run_loop.QuitClosure());
+ run_loop.Run();
- bool WaitForClientShutdown() { return helper_.WaitForChildTestShutdown(); }
+ IPCTestBase::TearDown();
+ }
+};
- IPC::Sender* sender() { return channel(); }
- IPC::Channel* channel() { return channel_.get(); }
+class IPCChannelMojoTest : public IPCChannelMojoTestBase {
+ protected:
+ scoped_ptr<IPC::ChannelFactory> CreateChannelFactory(
+ const IPC::ChannelHandle& handle,
+ base::SequencedTaskRunner* runner) override {
+ return IPC::ChannelMojo::CreateServerFactory(task_runner(), handle);
+ }
- private:
- base::MessageLoop message_loop_;
- base::TestIOThread io_thread_;
- mojo::edk::test::MultiprocessTestHelper helper_;
- mojo::ScopedMessagePipeHandle handle_;
- scoped_ptr<IPC::Channel> channel_;
+ bool DidStartClient() override {
+ bool ok = IPCTestBase::DidStartClient();
+ DCHECK(ok);
+ return ok;
+ }
};
+
class TestChannelListenerWithExtraExpectations
: public IPC::TestChannelListener {
public:
- TestChannelListenerWithExtraExpectations() : is_connected_called_(false) {}
+ TestChannelListenerWithExtraExpectations()
+ : is_connected_called_(false) {
+ }
void OnChannelConnected(int32_t peer_pid) override {
IPC::TestChannelListener::OnChannelConnected(peer_pid);
@@ -171,7 +149,8 @@ class TestChannelListenerWithExtraExpectations
};
// Times out on Android; see http://crbug.com/502290
-#if defined(OS_ANDROID)
+// Times out on Linux. crbug.com/585784
+#if defined(OS_ANDROID) || defined(OS_LINUX)
#define MAYBE_ConnectedFromClient DISABLED_ConnectedFromClient
#else
#define MAYBE_ConnectedFromClient ConnectedFromClient
@@ -184,12 +163,15 @@ TEST_F(IPCChannelMojoTest, MAYBE_ConnectedFromClient) {
CreateChannel(&listener);
listener.Init(sender());
ASSERT_TRUE(ConnectChannel());
+ ASSERT_TRUE(StartClient());
- IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
+ IPC::TestChannelListener::SendOneMessage(
+ sender(), "hello from parent");
base::MessageLoop::current()->Run();
+ EXPECT_TRUE(base::kNullProcessId != this->channel()->GetPeerPID());
- channel()->Close();
+ this->channel()->Close();
EXPECT_TRUE(WaitForClientShutdown());
EXPECT_TRUE(listener.is_connected_called());
@@ -199,22 +181,28 @@ TEST_F(IPCChannelMojoTest, MAYBE_ConnectedFromClient) {
}
// A long running process that connects to us
-DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestClient, ChannelClient) {
+MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestClient) {
TestChannelListenerWithExtraExpectations listener;
- Connect(&listener);
- listener.Init(channel());
+ ChannelClient client(&listener, "IPCChannelMojoTestClient");
+ client.Connect();
+ listener.Init(client.channel());
- IPC::TestChannelListener::SendOneMessage(channel(), "hello from child");
+ IPC::TestChannelListener::SendOneMessage(
+ client.channel(), "hello from child");
base::MessageLoop::current()->Run();
EXPECT_TRUE(listener.is_connected_called());
EXPECT_TRUE(listener.HasSentAll());
- Close();
+ client.Close();
+
+ return 0;
}
class ListenerExpectingErrors : public IPC::Listener {
public:
- ListenerExpectingErrors() : has_error_(false) {}
+ ListenerExpectingErrors()
+ : has_error_(false) {
+ }
void OnChannelConnected(int32_t peer_pid) override {
base::MessageLoop::current()->QuitWhenIdle();
@@ -233,11 +221,30 @@ class ListenerExpectingErrors : public IPC::Listener {
bool has_error_;
};
+
+class IPCChannelMojoErrorTest : public IPCChannelMojoTestBase {
+ protected:
+ scoped_ptr<IPC::ChannelFactory> CreateChannelFactory(
+ const IPC::ChannelHandle& handle,
+ base::SequencedTaskRunner* runner) override {
+ return IPC::ChannelMojo::CreateServerFactory(task_runner(), handle);
+ }
+
+ bool DidStartClient() override {
+ bool ok = IPCTestBase::DidStartClient();
+ DCHECK(ok);
+ return ok;
+ }
+};
+
class ListenerThatQuits : public IPC::Listener {
public:
- ListenerThatQuits() {}
+ ListenerThatQuits() {
+ }
- bool OnMessageReceived(const IPC::Message& message) override { return true; }
+ bool OnMessageReceived(const IPC::Message& message) override {
+ return true;
+ }
void OnChannelConnected(int32_t peer_pid) override {
base::MessageLoop::current()->QuitWhenIdle();
@@ -245,23 +252,26 @@ class ListenerThatQuits : public IPC::Listener {
};
// A long running process that connects to us.
-DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoErraticTestClient,
- ChannelClient) {
+MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoErraticTestClient) {
ListenerThatQuits listener;
- Connect(&listener);
+ ChannelClient client(&listener, "IPCChannelMojoErraticTestClient");
+ client.Connect();
base::MessageLoop::current()->Run();
- Close();
+ client.Close();
+
+ return 0;
}
// Times out on Android; see http://crbug.com/502290
-#if defined(OS_ANDROID)
+// Times out on Linux. crbug.com/585784
+#if defined(OS_ANDROID) || defined(OS_LINUX)
#define MAYBE_SendFailWithPendingMessages DISABLED_SendFailWithPendingMessages
#else
#define MAYBE_SendFailWithPendingMessages SendFailWithPendingMessages
#endif
-TEST_F(IPCChannelMojoTest, MAYBE_SendFailWithPendingMessages) {
+TEST_F(IPCChannelMojoErrorTest, MAYBE_SendFailWithPendingMessages) {
InitWithMojo("IPCChannelMojoErraticTestClient");
// Set up IPC channel and start client.
@@ -274,13 +284,14 @@ TEST_F(IPCChannelMojoTest, MAYBE_SendFailWithPendingMessages) {
std::string overly_large_data(kMaxMessageNumBytes, '*');
// This messages are queued as pending.
for (size_t i = 0; i < 10; ++i) {
- IPC::TestChannelListener::SendOneMessage(sender(),
- overly_large_data.c_str());
+ IPC::TestChannelListener::SendOneMessage(
+ sender(), overly_large_data.c_str());
}
+ ASSERT_TRUE(StartClient());
base::MessageLoop::current()->Run();
- channel()->Close();
+ this->channel()->Close();
EXPECT_TRUE(WaitForClientShutdown());
EXPECT_TRUE(listener.has_error());
@@ -326,9 +337,6 @@ class HandleSendingHelper {
std::string content(GetSendingFileContent().size(), ' ');
uint32_t num_bytes = static_cast<uint32_t>(content.size());
- ASSERT_EQ(MOJO_RESULT_OK,
- mojo::Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, nullptr));
EXPECT_EQ(MOJO_RESULT_OK,
mojo::ReadMessageRaw(pipe.get(), &content[0], &num_bytes, nullptr,
nullptr, 0));
@@ -405,7 +413,8 @@ class ListenerThatExpectsMessagePipe : public IPC::Listener {
};
// Times out on Android; see http://crbug.com/502290
-#if defined(OS_ANDROID)
+// Times out on Linux. crbug.com/585784
+#if defined(OS_ANDROID) || defined(OS_LINUX)
#define MAYBE_SendMessagePipe DISABLED_SendMessagePipe
#else
#define MAYBE_SendMessagePipe SendMessagePipe
@@ -416,33 +425,34 @@ TEST_F(IPCChannelMojoTest, MAYBE_SendMessagePipe) {
ListenerThatExpectsOK listener;
CreateChannel(&listener);
ASSERT_TRUE(ConnectChannel());
+ ASSERT_TRUE(StartClient());
TestingMessagePipe pipe;
HandleSendingHelper::WritePipeThenSend(channel(), &pipe);
base::MessageLoop::current()->Run();
- channel()->Close();
+ this->channel()->Close();
EXPECT_TRUE(WaitForClientShutdown());
DestroyChannel();
}
-DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendMessagePipeClient,
- ChannelClient) {
+MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendMessagePipeClient) {
ListenerThatExpectsMessagePipe listener;
- Connect(&listener);
- listener.set_sender(channel());
+ ChannelClient client(&listener, "IPCChannelMojoTestSendMessagePipeClient");
+ client.Connect();
+ listener.set_sender(client.channel());
base::MessageLoop::current()->Run();
- Close();
+ client.Close();
+
+ return 0;
}
void ReadOK(mojo::MessagePipeHandle pipe) {
std::string should_be_ok("xx");
uint32_t num_bytes = static_cast<uint32_t>(should_be_ok.size());
- CHECK_EQ(MOJO_RESULT_OK, mojo::Wait(pipe, MOJO_HANDLE_SIGNAL_READABLE,
- MOJO_DEADLINE_INDEFINITE, nullptr));
CHECK_EQ(MOJO_RESULT_OK,
mojo::ReadMessageRaw(pipe, &should_be_ok[0], &num_bytes, nullptr,
nullptr, 0));
@@ -487,22 +497,22 @@ class ListenerThatExpectsMessagePipeUsingParamTrait : public IPC::Listener {
bool receiving_valid_;
};
-class ParamTraitMessagePipeClient : public ChannelClient {
- public:
- void RunTest(bool receiving_valid_handle) {
- ListenerThatExpectsMessagePipeUsingParamTrait listener(
- receiving_valid_handle);
- Connect(&listener);
- listener.set_sender(channel());
+void ParamTraitMessagePipeClient(bool receiving_valid_handle,
+ const char* channel_name) {
+ ListenerThatExpectsMessagePipeUsingParamTrait listener(
+ receiving_valid_handle);
+ ChannelClient client(&listener, channel_name);
+ client.Connect();
+ listener.set_sender(client.channel());
- base::MessageLoop::current()->Run();
+ base::MessageLoop::current()->Run();
- Close();
- }
-};
+ client.Close();
+}
// Times out on Android; see http://crbug.com/502290
-#if defined(OS_ANDROID)
+// Times out on Linux. crbug.com/585784
+#if defined(OS_ANDROID) || defined(OS_LINUX)
#define MAYBE_ParamTraitValidMessagePipe DISABLED_ParamTraitValidMessagePipe
#else
#define MAYBE_ParamTraitValidMessagePipe ParamTraitValidMessagePipe
@@ -513,6 +523,7 @@ TEST_F(IPCChannelMojoTest, MAYBE_ParamTraitValidMessagePipe) {
ListenerThatExpectsOK listener;
CreateChannel(&listener);
ASSERT_TRUE(ConnectChannel());
+ ASSERT_TRUE(StartClient());
TestingMessagePipe pipe;
@@ -521,21 +532,22 @@ TEST_F(IPCChannelMojoTest, MAYBE_ParamTraitValidMessagePipe) {
pipe.peer.release());
WriteOK(pipe.self.get());
- channel()->Send(message.release());
+ this->channel()->Send(message.release());
base::MessageLoop::current()->Run();
- channel()->Close();
+ this->channel()->Close();
EXPECT_TRUE(WaitForClientShutdown());
DestroyChannel();
}
-DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ParamTraitValidMessagePipeClient,
- ParamTraitMessagePipeClient) {
- RunTest(true);
+MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ParamTraitValidMessagePipeClient) {
+ ParamTraitMessagePipeClient(true, "ParamTraitValidMessagePipeClient");
+ return 0;
}
// Times out on Android; see http://crbug.com/502290
-#if defined(OS_ANDROID)
+// Times out on Linux. crbug.com/585784
+#if defined(OS_ANDROID) || defined(OS_LINUX)
#define MAYBE_ParamTraitInvalidMessagePipe DISABLED_ParamTraitInvalidMessagePipe
#else
#define MAYBE_ParamTraitInvalidMessagePipe ParamTraitInvalidMessagePipe
@@ -546,35 +558,43 @@ TEST_F(IPCChannelMojoTest, MAYBE_ParamTraitInvalidMessagePipe) {
ListenerThatExpectsOK listener;
CreateChannel(&listener);
ASSERT_TRUE(ConnectChannel());
+ ASSERT_TRUE(StartClient());
mojo::MessagePipeHandle invalid_handle;
scoped_ptr<IPC::Message> message(new IPC::Message());
IPC::ParamTraits<mojo::MessagePipeHandle>::Write(message.get(),
invalid_handle);
- channel()->Send(message.release());
+ this->channel()->Send(message.release());
base::MessageLoop::current()->Run();
- channel()->Close();
+ this->channel()->Close();
EXPECT_TRUE(WaitForClientShutdown());
DestroyChannel();
}
-DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(ParamTraitInvalidMessagePipeClient,
- ParamTraitMessagePipeClient) {
- RunTest(false);
+MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ParamTraitInvalidMessagePipeClient) {
+ ParamTraitMessagePipeClient(false, "ParamTraitInvalidMessagePipeClient");
+ return 0;
}
-TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
+// Times out on Linux. crbug.com/585784
+#if defined(OS_LINUX)
+#define MAYBE_SendFailAfterClose DISABLED_SendFailAfterClose
+#else
+#define MAYBE_SendFailAfterClose SendFailAfterClose
+#endif
+TEST_F(IPCChannelMojoTest, MAYBE_SendFailAfterClose) {
InitWithMojo("IPCChannelMojoTestSendOkClient");
ListenerThatExpectsOK listener;
CreateChannel(&listener);
ASSERT_TRUE(ConnectChannel());
+ ASSERT_TRUE(StartClient());
base::MessageLoop::current()->Run();
- channel()->Close();
- ASSERT_FALSE(channel()->Send(new IPC::Message()));
+ this->channel()->Close();
+ ASSERT_FALSE(this->channel()->Send(new IPC::Message()));
EXPECT_TRUE(WaitForClientShutdown());
DestroyChannel();
@@ -582,9 +602,12 @@ TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
class ListenerSendingOneOk : public IPC::Listener {
public:
- ListenerSendingOneOk() {}
+ ListenerSendingOneOk() {
+ }
- bool OnMessageReceived(const IPC::Message& message) override { return true; }
+ bool OnMessageReceived(const IPC::Message& message) override {
+ return true;
+ }
void OnChannelConnected(int32_t peer_pid) override {
ListenerThatExpectsOK::SendOK(sender_);
@@ -597,21 +620,86 @@ class ListenerSendingOneOk : public IPC::Listener {
IPC::Sender* sender_;
};
-DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendOkClient,
- ChannelClient) {
+MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendOkClient) {
ListenerSendingOneOk listener;
- Connect(&listener);
- listener.set_sender(channel());
+ ChannelClient client(&listener, "IPCChannelMojoTestSendOkClient");
+ client.Connect();
+ listener.set_sender(client.channel());
+
+ base::MessageLoop::current()->Run();
+
+ client.Close();
+
+ return 0;
+}
+
+#if defined(OS_WIN)
+class IPCChannelMojoDeadHandleTest : public IPCChannelMojoTestBase {
+ protected:
+ scoped_ptr<IPC::ChannelFactory> CreateChannelFactory(
+ const IPC::ChannelHandle& handle,
+ base::SequencedTaskRunner* runner) override {
+ return IPC::ChannelMojo::CreateServerFactory(task_runner(), handle);
+ }
+
+ bool DidStartClient() override {
+ IPCTestBase::DidStartClient();
+ // const base::ProcessHandle client = client_process().Handle();
+ // Forces GetFileHandleForProcess() fail. It happens occasionally
+ // in production, so we should exercise it somehow.
+ // TODO(morrita): figure out how to safely test this. See crbug.com/464109.
+ // ::CloseHandle(client);
+ return true;
+ }
+};
+
+// Times out on Linux. crbug.com/585784
+#if defined(OS_LINUX)
+#define MAYBE_InvalidClientHandle DISABLED_InvalidClientHandle
+#else
+#define MAYBE_InvalidClientHandle InvalidClientHandle
+#endif
+TEST_F(IPCChannelMojoDeadHandleTest, MAYBE_InvalidClientHandle) {
+ // Any client type is fine as it is going to be killed anyway.
+ InitWithMojo("IPCChannelMojoTestDoNothingClient");
+
+ // Set up IPC channel and start client.
+ ListenerExpectingErrors listener;
+ CreateChannel(&listener);
+ ASSERT_TRUE(ConnectChannel());
+ ASSERT_TRUE(StartClient());
base::MessageLoop::current()->Run();
- Close();
+ this->channel()->Close();
+
+ // TODO(morrita): We need CloseHandle() call in DidStartClient(),
+ // which has been disabled since crrev.com/843113003, to
+ // make this fail. See crbug.com/464109.
+ // EXPECT_FALSE(WaitForClientShutdown());
+ WaitForClientShutdown();
+ EXPECT_TRUE(listener.has_error());
+
+ DestroyChannel();
+}
+
+MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestDoNothingClient) {
+ ListenerThatQuits listener;
+ ChannelClient client(&listener, "IPCChannelMojoTestDoNothingClient");
+ client.Connect();
+
+ // Quits without running the message loop as this client won't
+ // receive any messages from the server.
+
+ return 0;
}
+#endif
#if defined(OS_POSIX)
class ListenerThatExpectsFile : public IPC::Listener {
public:
- ListenerThatExpectsFile() : sender_(NULL) {}
+ ListenerThatExpectsFile()
+ : sender_(NULL) {}
~ListenerThatExpectsFile() override {}
@@ -623,7 +711,9 @@ class ListenerThatExpectsFile : public IPC::Listener {
return true;
}
- void OnChannelError() override { NOTREACHED(); }
+ void OnChannelError() override {
+ NOTREACHED();
+ }
void set_sender(IPC::Sender* sender) { sender_ = sender; }
@@ -632,7 +722,8 @@ class ListenerThatExpectsFile : public IPC::Listener {
};
// Times out on Android; see http://crbug.com/502290
-#if defined(OS_ANDROID)
+// Times out on Linux. crbug.com/585784
+#if defined(OS_ANDROID) || defined(OS_LINUX)
#define MAYBE_SendPlatformHandle DISABLED_SendPlatformHandle
#else
#define MAYBE_SendPlatformHandle SendPlatformHandle
@@ -643,6 +734,7 @@ TEST_F(IPCChannelMojoTest, MAYBE_SendPlatformHandle) {
ListenerThatExpectsOK listener;
CreateChannel(&listener);
ASSERT_TRUE(ConnectChannel());
+ ASSERT_TRUE(StartClient());
base::File file(HandleSendingHelper::GetSendingFilePath(),
base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
@@ -650,21 +742,24 @@ TEST_F(IPCChannelMojoTest, MAYBE_SendPlatformHandle) {
HandleSendingHelper::WriteFileThenSend(channel(), file);
base::MessageLoop::current()->Run();
- channel()->Close();
+ this->channel()->Close();
EXPECT_TRUE(WaitForClientShutdown());
DestroyChannel();
}
-DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestSendPlatformHandleClient,
- ChannelClient) {
+MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendPlatformHandleClient) {
ListenerThatExpectsFile listener;
- Connect(&listener);
- listener.set_sender(channel());
+ ChannelClient client(
+ &listener, "IPCChannelMojoTestSendPlatformHandleClient");
+ client.Connect();
+ listener.set_sender(client.channel());
base::MessageLoop::current()->Run();
- Close();
+ client.Close();
+
+ return 0;
}
class ListenerThatExpectsFileAndPipe : public IPC::Listener {
@@ -691,7 +786,8 @@ class ListenerThatExpectsFileAndPipe : public IPC::Listener {
};
// Times out on Android; see http://crbug.com/502290
-#if defined(OS_ANDROID)
+// Times out on Linux. crbug.com/585784
+#if defined(OS_ANDROID) || defined(OS_LINUX)
#define MAYBE_SendPlatformHandleAndPipe DISABLED_SendPlatformHandleAndPipe
#else
#define MAYBE_SendPlatformHandleAndPipe SendPlatformHandleAndPipe
@@ -702,6 +798,7 @@ TEST_F(IPCChannelMojoTest, MAYBE_SendPlatformHandleAndPipe) {
ListenerThatExpectsOK listener;
CreateChannel(&listener);
ASSERT_TRUE(ConnectChannel());
+ ASSERT_TRUE(StartClient());
base::File file(HandleSendingHelper::GetSendingFilePath(),
base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
@@ -710,22 +807,25 @@ TEST_F(IPCChannelMojoTest, MAYBE_SendPlatformHandleAndPipe) {
HandleSendingHelper::WriteFileAndPipeThenSend(channel(), file, &pipe);
base::MessageLoop::current()->Run();
- channel()->Close();
+ this->channel()->Close();
EXPECT_TRUE(WaitForClientShutdown());
DestroyChannel();
}
-DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(
- IPCChannelMojoTestSendPlatformHandleAndPipeClient,
- ChannelClient) {
+MULTIPROCESS_IPC_TEST_CLIENT_MAIN(
+ IPCChannelMojoTestSendPlatformHandleAndPipeClient) {
ListenerThatExpectsFileAndPipe listener;
- Connect(&listener);
- listener.set_sender(channel());
+ ChannelClient client(&listener,
+ "IPCChannelMojoTestSendPlatformHandleAndPipeClient");
+ client.Connect();
+ listener.set_sender(client.channel());
base::MessageLoop::current()->Run();
- Close();
+ client.Close();
+
+ return 0;
}
#endif
@@ -747,12 +847,19 @@ class ListenerThatVerifiesPeerPid : public IPC::Listener {
}
};
-TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
+// Times out on Linux. crbug.com/585784
+#if defined(OS_LINUX)
+#define MAYBE_VerifyGlobalPid DISABLED_VerifyGlobalPid
+#else
+#define MAYBE_VerifyGlobalPid VerifyGlobalPid
+#endif
+TEST_F(IPCChannelMojoTest, MAYBE_VerifyGlobalPid) {
InitWithMojo("IPCChannelMojoTestVerifyGlobalPidClient");
ListenerThatVerifiesPeerPid listener;
CreateChannel(&listener);
ASSERT_TRUE(ConnectChannel());
+ ASSERT_TRUE(StartClient());
base::MessageLoop::current()->Run();
channel()->Close();
@@ -761,17 +868,20 @@ TEST_F(IPCChannelMojoTest, VerifyGlobalPid) {
DestroyChannel();
}
-DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT(IPCChannelMojoTestVerifyGlobalPidClient,
- ChannelClient) {
+MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestVerifyGlobalPidClient) {
IPC::Channel::SetGlobalPid(kMagicChildId);
ListenerThatQuits listener;
- Connect(&listener);
+ ChannelClient client(&listener,
+ "IPCChannelMojoTestVerifyGlobalPidClient");
+ client.Connect();
base::MessageLoop::current()->Run();
- Close();
+ client.Close();
+
+ return 0;
}
-#endif // OS_LINUX
+#endif // OS_LINUX
} // namespace
diff --git a/ipc/mojo/ipc_message_pipe_reader.cc b/ipc/mojo/ipc_message_pipe_reader.cc
index 76e323b..ab5466e 100644
--- a/ipc/mojo/ipc_message_pipe_reader.cc
+++ b/ipc/mojo/ipc_message_pipe_reader.cc
@@ -21,10 +21,8 @@ namespace internal {
MessagePipeReader::MessagePipeReader(
mojom::ChannelAssociatedPtr sender,
mojo::AssociatedInterfaceRequest<mojom::Channel> receiver,
- base::ProcessId peer_pid,
MessagePipeReader::Delegate* delegate)
: delegate_(delegate),
- peer_pid_(peer_pid),
sender_(std::move(sender)),
binding_(this, std::move(receiver)) {
sender_.set_connection_error_handler(
@@ -80,7 +78,6 @@ void MessagePipeReader::Receive(mojom::MessagePtr ipc_message) {
? ""
: reinterpret_cast<const char*>(&ipc_message->data[0]),
static_cast<uint32_t>(ipc_message->data.size()));
- message.set_sender_pid(peer_pid_);
DVLOG(4) << "Receive " << message.type() << ": " << message.size();
MojoResult write_result = ChannelMojo::WriteToMessageAttachmentSet(
diff --git a/ipc/mojo/ipc_message_pipe_reader.h b/ipc/mojo/ipc_message_pipe_reader.h
index 75fe7ad..38ca6a8 100644
--- a/ipc/mojo/ipc_message_pipe_reader.h
+++ b/ipc/mojo/ipc_message_pipe_reader.h
@@ -71,7 +71,6 @@ class MessagePipeReader : public mojom::Channel {
// Note that MessagePipeReader doesn't delete |delegate|.
MessagePipeReader(mojom::ChannelAssociatedPtr sender,
mojo::AssociatedInterfaceRequest<mojom::Channel> receiver,
- base::ProcessId peer_pid,
Delegate* delegate);
~MessagePipeReader() override;
@@ -85,8 +84,6 @@ class MessagePipeReader : public mojom::Channel {
bool Send(scoped_ptr<Message> message);
- base::ProcessId GetPeerPid() const { return peer_pid_; }
-
protected:
void OnPipeClosed();
void OnPipeError(MojoResult error);
@@ -96,7 +93,6 @@ class MessagePipeReader : public mojom::Channel {
// |delegate_| is null once the message pipe is closed.
Delegate* delegate_;
- base::ProcessId peer_pid_;
mojom::ChannelAssociatedPtr sender_;
mojo::AssociatedBinding<mojom::Channel> binding_;
base::ThreadChecker thread_checker_;
diff --git a/ipc/mojo/ipc_mojo.gyp b/ipc/mojo/ipc_mojo.gyp
index 75c85d9..cb22889 100644
--- a/ipc/mojo/ipc_mojo.gyp
+++ b/ipc/mojo/ipc_mojo.gyp
@@ -71,7 +71,10 @@
'sources': [
'run_all_unittests.cc',
- "ipc_channel_mojo_unittest.cc",
+ # TODO(rockot): Re-enable these when we're ready to start using
+ # ChannelMojo again. They need to be updated to support multiprocess
+ # testing with the current Mojo EDK implementation.
+ #"ipc_channel_mojo_unittest.cc",
'ipc_mojo_bootstrap_unittest.cc',
],
'conditions': [
diff --git a/ipc/mojo/ipc_mojo_bootstrap.cc b/ipc/mojo/ipc_mojo_bootstrap.cc
index a80b461..6ace754 100644
--- a/ipc/mojo/ipc_mojo_bootstrap.cc
+++ b/ipc/mojo/ipc_mojo_bootstrap.cc
@@ -45,7 +45,8 @@ MojoServerBootstrap::MojoServerBootstrap() = default;
void MojoServerBootstrap::Connect() {
DCHECK_EQ(state(), STATE_INITIALIZED);
- bootstrap_.Bind(mojom::BootstrapPtrInfo(TakeHandle(), 0));
+ bootstrap_.Bind(
+ mojom::BootstrapPtrInfo(mojo::edk::CreateParentMessagePipe(token()), 0));
bootstrap_.set_connection_error_handler(
base::Bind(&MojoServerBootstrap::Fail, base::Unretained(this)));
@@ -104,7 +105,7 @@ class MojoClientBootstrap : public MojoBootstrap, public mojom::Bootstrap {
MojoClientBootstrap::MojoClientBootstrap() : binding_(this) {}
void MojoClientBootstrap::Connect() {
- binding_.Bind(TakeHandle());
+ binding_.Bind(mojo::edk::CreateChildMessagePipe(token()));
binding_.set_connection_error_handler(
base::Bind(&MojoClientBootstrap::Fail, base::Unretained(this)));
}
@@ -125,17 +126,16 @@ void MojoClientBootstrap::Init(mojom::ChannelAssociatedRequest receive_channel,
// MojoBootstrap
// static
-scoped_ptr<MojoBootstrap> MojoBootstrap::Create(
- mojo::ScopedMessagePipeHandle handle,
- Channel::Mode mode,
- Delegate* delegate) {
+scoped_ptr<MojoBootstrap> MojoBootstrap::Create(const std::string& token,
+ Channel::Mode mode,
+ Delegate* delegate) {
CHECK(mode == Channel::MODE_CLIENT || mode == Channel::MODE_SERVER);
scoped_ptr<MojoBootstrap> self =
mode == Channel::MODE_CLIENT
? scoped_ptr<MojoBootstrap>(new MojoClientBootstrap())
: scoped_ptr<MojoBootstrap>(new MojoServerBootstrap());
- self->Init(std::move(handle), delegate);
+ self->Init(token, delegate);
return self;
}
@@ -144,9 +144,8 @@ MojoBootstrap::MojoBootstrap() : delegate_(NULL), state_(STATE_INITIALIZED) {
MojoBootstrap::~MojoBootstrap() {}
-void MojoBootstrap::Init(mojo::ScopedMessagePipeHandle handle,
- Delegate* delegate) {
- handle_ = std::move(handle);
+void MojoBootstrap::Init(const std::string& token, Delegate* delegate) {
+ token_ = token;
delegate_ = delegate;
}
@@ -167,8 +166,4 @@ bool MojoBootstrap::HasFailed() const {
return state() == STATE_ERROR;
}
-mojo::ScopedMessagePipeHandle MojoBootstrap::TakeHandle() {
- return std::move(handle_);
-}
-
} // namespace IPC
diff --git a/ipc/mojo/ipc_mojo_bootstrap.h b/ipc/mojo/ipc_mojo_bootstrap.h
index 23e0e91..4c97850 100644
--- a/ipc/mojo/ipc_mojo_bootstrap.h
+++ b/ipc/mojo/ipc_mojo_bootstrap.h
@@ -38,9 +38,9 @@ class IPC_MOJO_EXPORT MojoBootstrap {
virtual void OnBootstrapError() = 0;
};
- // Create the MojoBootstrap instance, using |handle| as the message pipe, in
- // mode as specified by |mode|. The result is passed to |delegate|.
- static scoped_ptr<MojoBootstrap> Create(mojo::ScopedMessagePipeHandle handle,
+ // Create the MojoBootstrap instance, using |token| to create the message
+ // pipe, in mode as specified by |mode|. The result is passed to |delegate|.
+ static scoped_ptr<MojoBootstrap> Create(const std::string& token,
Channel::Mode mode,
Delegate* delegate);
@@ -66,12 +66,12 @@ class IPC_MOJO_EXPORT MojoBootstrap {
State state() const { return state_; }
void set_state(State state) { state_ = state; }
- mojo::ScopedMessagePipeHandle TakeHandle();
+ const std::string& token() { return token_; }
private:
- void Init(mojo::ScopedMessagePipeHandle, Delegate* delegate);
+ void Init(const std::string& token, Delegate* delegate);
- mojo::ScopedMessagePipeHandle handle_;
+ std::string token_;
Delegate* delegate_;
State state_;
diff --git a/ipc/mojo/ipc_mojo_bootstrap_unittest.cc b/ipc/mojo/ipc_mojo_bootstrap_unittest.cc
index 66ccdea..efd2b80 100644
--- a/ipc/mojo/ipc_mojo_bootstrap_unittest.cc
+++ b/ipc/mojo/ipc_mojo_bootstrap_unittest.cc
@@ -57,6 +57,8 @@ void TestingDelegate::OnBootstrapError() {
quit_callback_.Run();
}
+const char kMojoChannelToken[] = "IPCMojoBootstrapTest token";
+
// Times out on Android; see http://crbug.com/502290
#if defined(OS_ANDROID)
#define MAYBE_Connect DISABLED_Connect
@@ -67,10 +69,9 @@ TEST_F(IPCMojoBootstrapTest, MAYBE_Connect) {
base::MessageLoop message_loop;
base::RunLoop run_loop;
TestingDelegate delegate(run_loop.QuitClosure());
- RUN_CHILD_ON_PIPE(IPCMojoBootstrapTestClient, pipe)
scoped_ptr<IPC::MojoBootstrap> bootstrap = IPC::MojoBootstrap::Create(
- mojo::MakeScopedHandle(mojo::MessagePipeHandle(pipe)),
- IPC::Channel::MODE_SERVER, &delegate);
+ kMojoChannelToken, IPC::Channel::MODE_SERVER, &delegate);
+ RUN_CHILD_ON_PIPE(IPCMojoBootstrapTestClient, unused_pipe)
bootstrap->Connect();
run_loop.Run();
@@ -91,14 +92,13 @@ namespace {
// A long running process that connects to us.
DEFINE_TEST_CLIENT_TEST_WITH_PIPE(IPCMojoBootstrapTestClient,
- IPCMojoBootstrapTest,
- pipe) {
+ IPCMojoBootstrapTest,
+ unused_pipe) {
base::MessageLoop message_loop;
base::RunLoop run_loop;
TestingDelegate delegate(run_loop.QuitClosure());
scoped_ptr<IPC::MojoBootstrap> bootstrap = IPC::MojoBootstrap::Create(
- mojo::MakeScopedHandle(mojo::MessagePipeHandle(pipe)),
- IPC::Channel::MODE_CLIENT, &delegate);
+ kMojoChannelToken, IPC::Channel::MODE_CLIENT, &delegate);
bootstrap->Connect();
diff --git a/ipc/mojo/ipc_mojo_handle_attachment.cc b/ipc/mojo/ipc_mojo_handle_attachment.cc
index b2e16f1..ccce0d9 100644
--- a/ipc/mojo/ipc_mojo_handle_attachment.cc
+++ b/ipc/mojo/ipc_mojo_handle_attachment.cc
@@ -27,7 +27,8 @@ MessageAttachment::Type MojoHandleAttachment::GetType() const {
base::PlatformFile MojoHandleAttachment::TakePlatformFile() {
mojo::edk::ScopedPlatformHandle platform_handle;
MojoResult unwrap_result = mojo::edk::PassWrappedPlatformHandle(
- handle_.release().value(), &platform_handle);
+ handle_.get().value(), &platform_handle);
+ handle_.reset();
if (unwrap_result != MOJO_RESULT_OK) {
LOG(ERROR) << "Pipe failed to covert handles. Closing: " << unwrap_result;
return -1;
diff --git a/ipc/mojo/ipc_mojo_perftest.cc b/ipc/mojo/ipc_mojo_perftest.cc
index b1c6c86..92b79f8 100644
--- a/ipc/mojo/ipc_mojo_perftest.cc
+++ b/ipc/mojo/ipc_mojo_perftest.cc
@@ -17,22 +17,31 @@
namespace IPC {
namespace {
+const char kPerftestToken[] = "perftest-token";
+
class MojoChannelPerfTest : public test::IPCChannelPerfTestBase {
public:
+ MojoChannelPerfTest() { token_ = mojo::edk::GenerateRandomToken(); }
+
void TearDown() override {
- ipc_support_.reset();
+ {
+ base::AutoLock l(ipc_support_lock_);
+ ipc_support_.reset();
+ }
test::IPCChannelPerfTestBase::TearDown();
}
scoped_ptr<ChannelFactory> CreateChannelFactory(
const ChannelHandle& handle,
base::SequencedTaskRunner* runner) override {
- ipc_support_.reset(new mojo::edk::test::ScopedIPCSupport(io_task_runner()));
- return ChannelMojo::CreateServerFactory(
- helper_.StartChild("MojoPerfTestClient"));
+ EnsureIpcSupport();
+ return ChannelMojo::CreateServerFactory(token_);
}
bool StartClient() override {
+ EnsureIpcSupport();
+ helper_.StartChildWithExtraSwitch("MojoPerfTestClient", kPerftestToken,
+ token_);
return true;
}
@@ -40,7 +49,17 @@ class MojoChannelPerfTest : public test::IPCChannelPerfTestBase {
return helper_.WaitForChildTestShutdown();
}
+ void EnsureIpcSupport() {
+ base::AutoLock l(ipc_support_lock_);
+ if (!ipc_support_) {
+ ipc_support_.reset(
+ new mojo::edk::test::ScopedIPCSupport(io_task_runner()));
+ }
+ }
+
mojo::edk::test::MultiprocessTestHelper helper_;
+ std::string token_;
+ base::Lock ipc_support_lock_;
scoped_ptr<mojo::edk::test::ScopedIPCSupport> ipc_support_;
};
@@ -80,11 +99,8 @@ class MojoPerfTestClient : public test::PingPongTestClient {
scoped_ptr<Channel> CreateChannel(Listener* listener) override;
- int Run(MojoHandle handle);
-
private:
mojo::edk::test::ScopedIPCSupport ipc_support_;
- mojo::ScopedMessagePipeHandle handle_;
};
MojoPerfTestClient::MojoPerfTestClient()
@@ -93,19 +109,16 @@ MojoPerfTestClient::MojoPerfTestClient()
}
scoped_ptr<Channel> MojoPerfTestClient::CreateChannel(Listener* listener) {
- return scoped_ptr<Channel>(
- ChannelMojo::Create(std::move(handle_), Channel::MODE_CLIENT, listener));
-}
-
-int MojoPerfTestClient::Run(MojoHandle handle) {
- handle_ = mojo::MakeScopedHandle(mojo::MessagePipeHandle(handle));
- return RunMain();
+ return scoped_ptr<Channel>(ChannelMojo::Create(
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ kPerftestToken),
+ Channel::MODE_CLIENT, listener));
}
MULTIPROCESS_TEST_MAIN(MojoPerfTestClientTestChildMain) {
MojoPerfTestClient client;
- int rv = mojo::edk::test::MultiprocessTestHelper::RunClientMain(
- base::Bind(&MojoPerfTestClient::Run, base::Unretained(&client)));
+
+ int rv = client.RunMain();
base::RunLoop run_loop;
run_loop.RunUntilIdle();