diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-10 19:00:58 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-10 19:00:58 +0000 |
commit | cd3cf12588560bf1c1ffc780ce7fdeae044b100e (patch) | |
tree | 8ab79805aa9e50db3a2eae36e324af2f92bc13d4 /base/file_descriptor_shuffle.cc | |
parent | 2fc4c21d0b6cebaf8ebc101cc3fe20ef38407373 (diff) | |
download | chromium_src-cd3cf12588560bf1c1ffc780ce7fdeae044b100e.zip chromium_src-cd3cf12588560bf1c1ffc780ce7fdeae044b100e.tar.gz chromium_src-cd3cf12588560bf1c1ffc780ce7fdeae044b100e.tar.bz2 |
POSIX: don't allocate memory after forking.
Previously we would allocate memory in the child process. However, the
allocation might have happened while the malloc lock was held,
resulting in a deadlock.
This patch removes allocation from the child but probably makes Mac's
startup time slower until a Mac person can implement
dir_reader_posix.h.
TEST=Unittest for new code
BUG=36678
http://codereview.chromium.org/672003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41181 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/file_descriptor_shuffle.cc')
-rw-r--r-- | base/file_descriptor_shuffle.cc | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/base/file_descriptor_shuffle.cc b/base/file_descriptor_shuffle.cc index e722a29..2bb156b 100644 --- a/base/file_descriptor_shuffle.cc +++ b/base/file_descriptor_shuffle.cc @@ -12,28 +12,36 @@ namespace base { -bool PerformInjectiveMultimap(const InjectiveMultimap& m_in, - InjectionDelegate* delegate) { - InjectiveMultimap m(m_in); - std::vector<int> extra_fds; +bool PerformInjectiveMultimapDestructive( + InjectiveMultimap* m, InjectionDelegate* delegate) { + static const size_t kMaxExtraFDs = 16; + int extra_fds[kMaxExtraFDs]; + unsigned next_extra_fd = 0; - for (InjectiveMultimap::iterator i = m.begin(); i != m.end(); ++i) { + // DANGER: this function may not allocate. + + for (InjectiveMultimap::iterator i = m->begin(); i != m->end(); ++i) { int temp_fd = -1; // We DCHECK the injectiveness of the mapping. - for (InjectiveMultimap::iterator j = i + 1; j != m.end(); ++j) { + for (InjectiveMultimap::iterator j = i + 1; j != m->end(); ++j) { DCHECK(i->dest != j->dest) << "Both fd " << i->source << " and " << j->source << " map to " << i->dest; } const bool is_identity = i->source == i->dest; - for (InjectiveMultimap::iterator j = i + 1; j != m.end(); ++j) { + for (InjectiveMultimap::iterator j = i + 1; j != m->end(); ++j) { if (!is_identity && i->dest == j->source) { if (temp_fd == -1) { if (!delegate->Duplicate(&temp_fd, i->dest)) return false; - extra_fds.push_back(temp_fd); + if (next_extra_fd < kMaxExtraFDs) { + extra_fds[next_extra_fd++] = temp_fd; + } else { + RAW_LOG(ERROR, "PerformInjectiveMultimapDestructive overflowed " + "extra_fds. Leaking file descriptors!"); + } } j->source = temp_fd; @@ -58,14 +66,18 @@ bool PerformInjectiveMultimap(const InjectiveMultimap& m_in, delegate->Close(i->source); } - for (std::vector<int>::const_iterator - i = extra_fds.begin(); i != extra_fds.end(); ++i) { - delegate->Close(*i); - } + for (unsigned i = 0; i < next_extra_fd; i++) + delegate->Close(extra_fds[i]); return true; } +bool PerformInjectiveMultimap(const InjectiveMultimap& m_in, + InjectionDelegate* delegate) { + InjectiveMultimap m(m_in); + return PerformInjectiveMultimapDestructive(&m, delegate); +} + bool FileDescriptorTableInjection::Duplicate(int* result, int fd) { *result = HANDLE_EINTR(dup(fd)); return *result >= 0; |