diff options
author | morrita <morrita@chromium.org> | 2015-06-23 15:29:36 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-06-23 22:31:20 +0000 |
commit | 17137e6622afddeaabcf911d6a118233383b5f77 (patch) | |
tree | 5f11d87310cdce863df31c34615dfabe6bd8adc2 /ipc | |
parent | 542b71e372426c2547be0a689c2d7053b1ffdeff (diff) | |
download | chromium_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.cc | 8 | ||||
-rw-r--r-- | ipc/mojo/ipc_channel_mojo.h | 3 | ||||
-rw-r--r-- | ipc/mojo/ipc_channel_mojo_unittest.cc | 49 |
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: |