diff options
author | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-23 17:56:25 +0000 |
---|---|---|
committer | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-23 17:56:25 +0000 |
commit | 052fd4554b97d509ac2dba629bff9372a49a4e97 (patch) | |
tree | 7611171c279d8e342a229c7469de62ea2a941698 /ipc | |
parent | 2099006be6b45f5dd976728b2c866666434aeea0 (diff) | |
download | chromium_src-052fd4554b97d509ac2dba629bff9372a49a4e97.zip chromium_src-052fd4554b97d509ac2dba629bff9372a49a4e97.tar.gz chromium_src-052fd4554b97d509ac2dba629bff9372a49a4e97.tar.bz2 |
IPC & LibEvent fix
* Allow IPC::Listeners to send a message on OnChannelConnected.
* Fix a bug in MessagePumpLibevent::WatchFileDescriptor causing a read-after-free.
BUG=22451
Review URL: http://codereview.chromium.org/209061
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26946 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/ipc_channel_posix.cc | 2 | ||||
-rw-r--r-- | ipc/ipc_tests.cc | 67 |
2 files changed, 67 insertions, 2 deletions
diff --git a/ipc/ipc_channel_posix.cc b/ipc/ipc_channel_posix.cc index c1f4564..24d11f4 100644 --- a/ipc/ipc_channel_posix.cc +++ b/ipc/ipc_channel_posix.cc @@ -913,8 +913,6 @@ void Channel::ChannelImpl::OnFileCanReadWithoutBlocking(int fd) { // This gives us a chance to kill the client if the incoming handshake // is invalid. if (send_server_hello_msg) { - // This should be our first write so there's no chance we can block here... - DCHECK(is_blocked_on_write_ == false); ProcessOutgoingMessages(); } } diff --git a/ipc/ipc_tests.cc b/ipc/ipc_tests.cc index 7094308..43a368c 100644 --- a/ipc/ipc_tests.cc +++ b/ipc/ipc_tests.cc @@ -286,6 +286,73 @@ TEST_F(IPCChannelTest, ChannelProxyTest) { thread.Stop(); } +class ChannelListenerWithOnConnectedSend : public IPC::Channel::Listener { + public: + virtual void OnChannelConnected(int32 peer_pid) { + SendNextMessage(); + } + + virtual void OnMessageReceived(const IPC::Message& message) { + IPC::MessageIterator iter(message); + + iter.NextInt(); + const std::string data = iter.NextString(); + const std::string big_string = iter.NextString(); + EXPECT_EQ(kLongMessageStringNumBytes - 1, big_string.length()); + SendNextMessage(); + } + + virtual void OnChannelError() { + // There is a race when closing the channel so the last message may be lost. + EXPECT_LE(messages_left_, 1); + MessageLoop::current()->Quit(); + } + + void Init(IPC::Message::Sender* s) { + sender_ = s; + messages_left_ = 50; + } + + private: + void SendNextMessage() { + if (--messages_left_ == 0) { + MessageLoop::current()->Quit(); + } else { + Send(sender_, "Foo"); + } + } + + IPC::Message::Sender* sender_; + int messages_left_; +}; + +TEST_F(IPCChannelTest, SendMessageInChannelConnected) { + // This tests the case of a listener sending back an event in it's + // OnChannelConnected handler. + + ChannelListenerWithOnConnectedSend channel_listener; + // Setup IPC channel. + IPC::Channel channel(kTestClientChannel, IPC::Channel::MODE_SERVER, + &channel_listener); + channel_listener.Init(&channel); + channel.Connect(); + + base::ProcessHandle process_handle = SpawnChild(TEST_CLIENT, &channel); + ASSERT_TRUE(process_handle); + + Send(&channel, "hello from parent"); + + // Run message loop. + MessageLoop::current()->Run(); + + // Close Channel so client gets its OnChannelError() callback fired. + channel.Close(); + + // Cleanup child process. + EXPECT_TRUE(base::WaitForSingleProcess(process_handle, 5000)); + base::CloseProcessHandle(process_handle); +} + MULTIPROCESS_TEST_MAIN(RunTestClient) { MessageLoopForIO main_message_loop; MyChannelListener channel_listener; |