From 3a70c6d47b3fcf722951b71f85d46da970d6473f Mon Sep 17 00:00:00 2001 From: "hubbe@chromium.org" Date: Wed, 2 Oct 2013 20:53:06 +0000 Subject: There is a bug in the mac kernel, which can cause a file descriptor to be closed when sent multiple times between processes. By delaying the close on the sender side by a few second, we can eliminate this problem. BUG=279443, 298276 Review URL: https://codereview.chromium.org/24365008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@226555 0039d316-1c4b-4281-b951-d872f2087c98 --- ipc/file_descriptor_set_posix.cc | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'ipc') diff --git a/ipc/file_descriptor_set_posix.cc b/ipc/file_descriptor_set_posix.cc index 584efec..13356b7 100644 --- a/ipc/file_descriptor_set_posix.cc +++ b/ipc/file_descriptor_set_posix.cc @@ -8,9 +8,19 @@ #include #include +#include "base/bind.h" #include "base/logging.h" +#include "base/message_loop/message_loop.h" #include "base/posix/eintr_wrapper.h" +namespace { +// Used as callback. +static void CloseFD(int fd) { + if (HANDLE_EINTR(close(fd)) < 0) + PLOG(ERROR) << "close"; +} +} // namespace + FileDescriptorSet::FileDescriptorSet() : consumed_descriptor_highwater_(0) { } @@ -118,9 +128,26 @@ bool FileDescriptorSet::ContainsDirectoryDescriptor() const { void FileDescriptorSet::CommitAll() { for (std::vector::iterator i = descriptors_.begin(); i != descriptors_.end(); ++i) { - if (i->auto_close) - if (HANDLE_EINTR(close(i->fd)) < 0) - PLOG(ERROR) << "close"; + if (i->auto_close) { +#if defined(OS_MACOSX) + // On mac, a sent file descriptor will sometimes get closed + // by a kernel garbage collector. By delaying the close by + // a few seconds, we can solve this once and for all. + // - but... + // - ONCE AND FOR ALL + // https://code.google.com/p/chromium/issues/detail?id=298276 + if (base::MessageLoop::current()) { + base::MessageLoop::current()->PostDelayedTask( + FROM_HERE, + base::Bind(&CloseFD, i->fd), + base::TimeDelta::FromSeconds(5)); + } else { + CloseFD(i->fd); + } +#else // OS_MACOSX + CloseFD(i->fd); +#endif // OS_MACOSX + } } descriptors_.clear(); consumed_descriptor_highwater_ = 0; -- cgit v1.1