diff options
author | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-29 17:03:11 +0000 |
---|---|---|
committer | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-29 17:03:11 +0000 |
commit | 3d1b666c35804fb6579875dce91711d490e2a812 (patch) | |
tree | 9eb707e2e437b21e3c137adbed44b4170f1f671b /chrome | |
parent | 06863722bd6272ce893ba36060a80de7390be326 (diff) | |
download | chromium_src-3d1b666c35804fb6579875dce91711d490e2a812.zip chromium_src-3d1b666c35804fb6579875dce91711d490e2a812.tar.gz chromium_src-3d1b666c35804fb6579875dce91711d490e2a812.tar.bz2 |
Fix issue 7146, sending large messages over IPC on POSIX was broken.
Review URL: http://codereview.chromium.org/19454
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8887 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/common/ipc_channel_posix.cc | 12 | ||||
-rw-r--r-- | chrome/common/ipc_tests.cc | 12 |
2 files changed, 17 insertions, 7 deletions
diff --git a/chrome/common/ipc_channel_posix.cc b/chrome/common/ipc_channel_posix.cc index 6c6f17c..a7bbb56 100644 --- a/chrome/common/ipc_channel_posix.cc +++ b/chrome/common/ipc_channel_posix.cc @@ -368,6 +368,7 @@ bool Channel::ChannelImpl::ProcessIncomingMessages() { do { bytes_read = read(pipe_, input_buf_, Channel::kReadBufferSize); } while (bytes_read == -1 && errno == EINTR); + if (bytes_read < 0) { if (errno == EAGAIN) { return true; @@ -454,6 +455,7 @@ bool Channel::ChannelImpl::ProcessOutgoingMessages() { Message* msg = output_queue_.front(); size_t amt_to_write = msg->size() - message_send_bytes_written_; + DCHECK(amt_to_write != 0); const char *out_bytes = reinterpret_cast<const char*>(msg->data()) + message_send_bytes_written_; ssize_t bytes_written = -1; @@ -461,13 +463,16 @@ bool Channel::ChannelImpl::ProcessOutgoingMessages() { bytes_written = write(pipe_, out_bytes, amt_to_write); } while (bytes_written == -1 && errno == EINTR); - if (bytes_written < 0) { + if (bytes_written < 0 && errno != EAGAIN) { LOG(ERROR) << "pipe error: " << strerror(errno); return false; } if (static_cast<size_t>(bytes_written) != amt_to_write) { - message_send_bytes_written_ += bytes_written; + if (bytes_written > 0) { + // If write() fails with EAGAIN then bytes_written will be -1. + message_send_bytes_written_ += bytes_written; + } // Tell libevent to call us back once things are unblocked. is_blocked_on_write_ = true; @@ -477,6 +482,7 @@ bool Channel::ChannelImpl::ProcessOutgoingMessages() { MessageLoopForIO::WATCH_WRITE, &write_watcher_, this); + return true; } else { message_send_bytes_written_ = 0; @@ -568,7 +574,7 @@ 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' sno chance we can block here... + // 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/chrome/common/ipc_tests.cc b/chrome/common/ipc_tests.cc index b0add18..695f0b4 100644 --- a/chrome/common/ipc_tests.cc +++ b/chrome/common/ipc_tests.cc @@ -153,8 +153,9 @@ static void Send(IPC::Message::Sender* sender, const char* text) { message->WriteInt(message_index++); message->WriteString(std::string(text)); - // make sure we can handle large messages + // Make sure we can handle large messages. char junk[50000]; + memset(junk, 'a', sizeof(junk)-1); junk[sizeof(junk)-1] = 0; message->WriteString(std::string(junk)); @@ -194,7 +195,7 @@ class MyChannelListener : public IPC::Channel::Listener { static MyChannelListener channel_listener; TEST_F(IPCChannelTest, ChannelTest) { - // setup IPC channel + // Setup IPC channel. IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER, &channel_listener); chan.Connect(); @@ -206,10 +207,13 @@ TEST_F(IPCChannelTest, ChannelTest) { Send(&chan, "hello from parent"); - // run message loop + // Run message loop. MessageLoop::current()->Run(); - // cleanup child process + // Close Channel so client gets its OnChannelError() callback fired. + chan.Close(); + + // Cleanup child process. EXPECT_TRUE(base::WaitForSingleProcess(process_handle, 5000)); } |