Chromium Code Reviews| Index: ipc/ipc_channel_posix_unittest.cc |
| diff --git a/ipc/ipc_channel_posix_unittest.cc b/ipc/ipc_channel_posix_unittest.cc |
| index 66ddeb2b49676444245ceab4e185a0dd84e926b8..a557ad923703a689e3dcd10b91083c99ebe05164 100644 |
| --- a/ipc/ipc_channel_posix_unittest.cc |
| +++ b/ipc/ipc_channel_posix_unittest.cc |
| @@ -41,7 +41,9 @@ class IPCChannelPosixTestListener : public IPC::Listener { |
| }; |
| IPCChannelPosixTestListener(bool quit_only_on_message) |
| - : status_(DISCONNECTED), quit_only_on_message_(quit_only_on_message) {} |
| + : status_(DISCONNECTED), |
| + quit_only_on_message_(quit_only_on_message) { |
| + } |
| virtual ~IPCChannelPosixTestListener() {} |
| @@ -83,7 +85,13 @@ class IPCChannelPosixTestListener : public IPC::Listener { |
| STATUS status() { return status_; } |
| void QuitRunLoop() { |
| - base::MessageLoopForIO::current()->QuitNow(); |
| + base::MessageLoopForIO* loop = base::MessageLoopForIO::current(); |
| + if (loop->is_running()) { |
| + loop->QuitNow(); |
| + } else { |
| + // Die as soon as Run is called. |
| + loop->PostTask(FROM_HERE, loop->QuitClosure()); |
| + } |
| } |
| private: |
| @@ -186,7 +194,7 @@ void IPCChannelPosixTest::SpinRunLoop(base::TimeDelta delay) { |
| // in the case of a bad test. Usually, the run loop will quit sooner than |
| // that because all tests use a IPCChannelPosixTestListener which quits the |
| // current run loop on any channel activity. |
| - loop->PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(), delay); |
| + loop->PostDelayedTask(FROM_HERE, loop->QuitClosure(), delay); |
| loop->Run(); |
| } |
| @@ -228,6 +236,46 @@ TEST_F(IPCChannelPosixTest, BasicConnected) { |
| ASSERT_FALSE(channel2.AcceptsConnections()); |
| } |
| +// If a connection closes right before a Send() call, we may end up closing |
| +// the connection without notifying the listener, which can cause hangs in |
| +// sync_message_filter and others. Make sure the listener is notified. |
| +TEST_F(IPCChannelPosixTest, SendHangTest) { |
| + IPCChannelPosixTestListener out_listener(true); |
| + IPCChannelPosixTestListener in_listener(true); |
| + IPC::ChannelHandle in_handle("IN"); |
| + IPC::Channel in_chan(in_handle, IPC::Channel::MODE_SERVER, &in_listener); |
| + base::FileDescriptor out_fd(in_chan.TakeClientFileDescriptor(), false); |
| + IPC::ChannelHandle out_handle("OUT", out_fd); |
| + IPC::Channel out_chan(out_handle, IPC::Channel::MODE_CLIENT, &out_listener); |
| + ASSERT_TRUE(in_chan.Connect()); |
| + ASSERT_TRUE(out_chan.Connect()); |
| + in_chan.Close(); // simulate remote process dying at an unforunate time. |
|
Scott Hess - ex-Googler
2013/11/13 21:33:22
sp "unfortunate".
hubbe
2013/11/20 20:21:22
Done.
|
| + // Send will fail, because it cannot write the message. |
| + ASSERT_FALSE(out_chan.Send(new IPC::Message( |
| + 0, // routing_id |
| + kQuitMessage, // message type |
| + IPC::Message::PRIORITY_NORMAL))); |
| + ASSERT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, out_listener.status()); |
| +} |
| + |
| +// If a connection closes right before an Connect() call, |
|
Scott Hess - ex-Googler
2013/11/13 21:33:22
"a Connect() call". Also paragraph formatting loo
hubbe
2013/11/20 20:21:22
Done.
|
| +// we may end up closing the connection without notifying the listener, |
| +// which can cause hangs in sync_message_filter and others. Make sure the |
| +// listener is notified. |
| +TEST_F(IPCChannelPosixTest, AcceptHangTest) { |
| + IPCChannelPosixTestListener out_listener(true); |
| + IPCChannelPosixTestListener in_listener(true); |
| + IPC::ChannelHandle in_handle("IN"); |
| + IPC::Channel in_chan(in_handle, IPC::Channel::MODE_SERVER, &in_listener); |
| + base::FileDescriptor out_fd(in_chan.TakeClientFileDescriptor(), false); |
| + IPC::ChannelHandle out_handle("OUT", out_fd); |
| + IPC::Channel out_chan(out_handle, IPC::Channel::MODE_CLIENT, &out_listener); |
| + ASSERT_TRUE(in_chan.Connect()); |
| + in_chan.Close(); // simulate remote process dying at an unforunate time. |
| + ASSERT_FALSE(out_chan.Connect()); |
| + ASSERT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, out_listener.status()); |
| +} |
| + |
| TEST_F(IPCChannelPosixTest, AdvancedConnected) { |
| // Test creating a connection to an external process. |
| IPCChannelPosixTestListener listener(false); |