summaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorjeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-23 17:56:25 +0000
committerjeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-23 17:56:25 +0000
commit052fd4554b97d509ac2dba629bff9372a49a4e97 (patch)
tree7611171c279d8e342a229c7469de62ea2a941698 /ipc
parent2099006be6b45f5dd976728b2c866666434aeea0 (diff)
downloadchromium_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.cc2
-rw-r--r--ipc/ipc_tests.cc67
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;