diff options
author | dkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-22 20:01:36 +0000 |
---|---|---|
committer | dkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-22 20:01:36 +0000 |
commit | f74c89669d1c2406e6af03a84eacc18e3c775547 (patch) | |
tree | a87e2c0542f12dda1d2eb7527ebdbbfa469485b5 /base/message_loop_unittest.cc | |
parent | 5df23b5ea7e1aa9d1cc72c526200bbf212bf867f (diff) | |
download | chromium_src-f74c89669d1c2406e6af03a84eacc18e3c775547.zip chromium_src-f74c89669d1c2406e6af03a84eacc18e3c775547.tar.gz chromium_src-f74c89669d1c2406e6af03a84eacc18e3c775547.tar.bz2 |
StopWatchingFileDescriptor needs to free struct event.
Also, there's no point in using scoped_ptr for event_ anymore,
so removed that.
Should fix http://crbug.com/10503 "Crash in network layer"
Review URL: http://codereview.chromium.org/87045
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14233 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/message_loop_unittest.cc')
-rw-r--r-- | base/message_loop_unittest.cc | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/base/message_loop_unittest.cc b/base/message_loop_unittest.cc index d959659..ed7b0c1 100644 --- a/base/message_loop_unittest.cc +++ b/base/message_loop_unittest.cc @@ -13,6 +13,9 @@ #include "base/message_pump_win.h" #include "base/scoped_handle.h" #endif +#if defined(OS_POSIX) +#include "base/message_pump_libevent.h" +#endif using base::Thread; using base::Time; @@ -1381,3 +1384,75 @@ TEST(MessageLoopTest, WaitForIO) { RunTest_WaitForIO(); } #endif // defined(OS_WIN) + +#if defined(OS_POSIX) + +namespace { + +class QuitDelegate : public + base::MessagePumpLibevent::Watcher { + public: + virtual void OnFileCanWriteWithoutBlocking(int fd) { + MessageLoop::current()->Quit(); + } + virtual void OnFileCanReadWithoutBlocking(int fd) { + MessageLoop::current()->Quit(); + } +}; + +} // namespace + +TEST(MessageLoopTest, DISABLED_FileDescriptorWatcherOutlivesMessageLoop) { + // Simulate a MessageLoop that dies before an FileDescriptorWatcher. + // This could happen when people use the Singleton pattern or atexit. + // This is disabled for now because it fails (valgrind shows + // invalid reads), and it's not clear any code relies on this... + // TODO(dkegel): enable if it turns out we rely on this + + // Create a file descriptor. Doesn't need to be readable or writable, + // as we don't need to actually get any notifications. + // pipe() is just the easiest way to do it. + int pipefds[2]; + int err = pipe(pipefds); + ASSERT_TRUE(err == 0); + int fd = pipefds[1]; + { + // Arrange for controller to live longer than message loop. + base::MessagePumpLibevent::FileDescriptorWatcher controller; + { + MessageLoopForIO message_loop; + + QuitDelegate delegate; + message_loop.WatchFileDescriptor(fd, + true, MessageLoopForIO::WATCH_WRITE, &controller, &delegate); + // and don't run the message loop, just destroy it. + } + } + close(pipefds[0]); + close(pipefds[1]); +} + +TEST(MessageLoopTest, FileDescriptorWatcherDoubleStop) { + // Verify that it's ok to call StopWatchingFileDescriptor(). + // (Errors only showed up in valgrind.) + int pipefds[2]; + int err = pipe(pipefds); + ASSERT_TRUE(err == 0); + int fd = pipefds[1]; + { + // Arrange for message loop to live longer than controller. + MessageLoopForIO message_loop; + { + base::MessagePumpLibevent::FileDescriptorWatcher controller; + + QuitDelegate delegate; + message_loop.WatchFileDescriptor(fd, + true, MessageLoopForIO::WATCH_WRITE, &controller, &delegate); + controller.StopWatchingFileDescriptor(); + } + } + close(pipefds[0]); + close(pipefds[1]); +} + +#endif // defined(OS_LINUX) |