summaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authormorrita <morrita@chromium.org>2015-06-23 15:29:36 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-23 22:31:20 +0000
commit17137e6622afddeaabcf911d6a118233383b5f77 (patch)
tree5f11d87310cdce863df31c34615dfabe6bd8adc2 /ipc
parent542b71e372426c2547be0a689c2d7053b1ffdeff (diff)
downloadchromium_src-17137e6622afddeaabcf911d6a118233383b5f77.zip
chromium_src-17137e6622afddeaabcf911d6a118233383b5f77.tar.gz
chromium_src-17137e6622afddeaabcf911d6a118233383b5f77.tar.bz2
IPC::ChannelMojo::Send() should fail once it is closed.
This is compatible to other IPC::Channel implementations. R=agl@chromium.org,viettrungluu@chromium.org BUG=488291 Review URL: https://codereview.chromium.org/1181083003 Cr-Commit-Position: refs/heads/master@{#335780}
Diffstat (limited to 'ipc')
-rw-r--r--ipc/mojo/ipc_channel_mojo.cc8
-rw-r--r--ipc/mojo/ipc_channel_mojo.h3
-rw-r--r--ipc/mojo/ipc_channel_mojo_unittest.cc49
3 files changed, 58 insertions, 2 deletions
diff --git a/ipc/mojo/ipc_channel_mojo.cc b/ipc/mojo/ipc_channel_mojo.cc
index 4b0916d..6c3e91c 100644
--- a/ipc/mojo/ipc_channel_mojo.cc
+++ b/ipc/mojo/ipc_channel_mojo.cc
@@ -291,6 +291,7 @@ ChannelMojo::ChannelMojo(scoped_refptr<base::TaskRunner> io_runner,
peer_pid_(base::kNullProcessId),
io_runner_(io_runner),
channel_info_(nullptr, ChannelInfoDeleter(nullptr)),
+ waiting_connect_(true),
weak_factory_(this) {
// Create MojoBootstrap after all members are set as it touches
// ChannelMojo from a different thread.
@@ -368,6 +369,8 @@ void ChannelMojo::Close() {
// but the instance has to be deleted outside.
base::AutoLock l(lock_);
to_be_deleted = message_reader_.Pass();
+ // We might Close() before we Connect().
+ waiting_connect_ = false;
}
channel_info_.reset();
@@ -417,6 +420,7 @@ void ChannelMojo::InitMessageReader(mojo::ScopedMessagePipeHandle pipe,
// care. They cannot be sent anyway.
message_reader_.reset(reader.release());
pending_messages_.clear();
+ waiting_connect_ = false;
}
set_peer_pid(peer_pid);
@@ -439,7 +443,9 @@ bool ChannelMojo::Send(Message* message) {
base::AutoLock l(lock_);
if (!message_reader_) {
pending_messages_.push_back(message);
- return true;
+ // Counts as OK before the connection is established, but it's an
+ // error otherwise.
+ return waiting_connect_;
}
return message_reader_->Send(make_scoped_ptr(message));
diff --git a/ipc/mojo/ipc_channel_mojo.h b/ipc/mojo/ipc_channel_mojo.h
index 6b7d2fc..522683f 100644
--- a/ipc/mojo/ipc_channel_mojo.h
+++ b/ipc/mojo/ipc_channel_mojo.h
@@ -169,7 +169,7 @@ class IPC_MOJO_EXPORT ChannelMojo
scoped_ptr<mojo::embedder::ChannelInfo,
ChannelInfoDeleter> channel_info_;
- // Guards |message_reader_| and |pending_messages_|
+ // Guards |message_reader_|, |waiting_connect_| and |pending_messages_|
//
// * The contents of |pending_messages_| can be modified from any thread.
// * |message_reader_| is modified only from the IO thread,
@@ -177,6 +177,7 @@ class IPC_MOJO_EXPORT ChannelMojo
base::Lock lock_;
scoped_ptr<internal::MessagePipeReader, ReaderDeleter> message_reader_;
ScopedVector<Message> pending_messages_;
+ bool waiting_connect_;
scoped_ptr<ScopedIPCSupport> ipc_support_;
diff --git a/ipc/mojo/ipc_channel_mojo_unittest.cc b/ipc/mojo/ipc_channel_mojo_unittest.cc
index ef8d9a8..c82e011 100644
--- a/ipc/mojo/ipc_channel_mojo_unittest.cc
+++ b/ipc/mojo/ipc_channel_mojo_unittest.cc
@@ -570,6 +570,55 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ParamTraitInvalidMessagePipeClient) {
return 0;
}
+TEST_F(IPCChannelMojoTest, SendFailAfterClose) {
+ InitWithMojo("IPCChannelMojoTestSendOkClient");
+
+ ListenerThatExpectsOK listener;
+ CreateChannel(&listener);
+ ASSERT_TRUE(ConnectChannel());
+ ASSERT_TRUE(StartClient());
+
+ base::MessageLoop::current()->Run();
+ this->channel()->Close();
+ ASSERT_FALSE(this->channel()->Send(new IPC::Message()));
+
+ EXPECT_TRUE(WaitForClientShutdown());
+ DestroyChannel();
+}
+
+class ListenerSendingOneOk : public IPC::Listener {
+ public:
+ ListenerSendingOneOk() {
+ }
+
+ bool OnMessageReceived(const IPC::Message& message) override {
+ return true;
+ }
+
+ void OnChannelConnected(int32 peer_pid) override {
+ ListenerThatExpectsOK::SendOK(sender_);
+ base::MessageLoop::current()->Quit();
+ }
+
+ void set_sender(IPC::Sender* sender) { sender_ = sender; }
+
+ private:
+ IPC::Sender* sender_;
+};
+
+MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendOkClient) {
+ ListenerSendingOneOk listener;
+ 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: