diff options
author | simonjam@chromium.org <simonjam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-09 23:15:40 +0000 |
---|---|---|
committer | simonjam@chromium.org <simonjam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-09 23:15:40 +0000 |
commit | c14eda96f08f84ce1c06566aa248adf025d3ab4e (patch) | |
tree | 36439ccd67f25e91c22200c01193ecd97e33551a /base | |
parent | 485b0a6c4fb8976c12887fa1db9c782244c6dea9 (diff) | |
download | chromium_src-c14eda96f08f84ce1c06566aa248adf025d3ab4e.zip chromium_src-c14eda96f08f84ce1c06566aa248adf025d3ab4e.tar.gz chromium_src-c14eda96f08f84ce1c06566aa248adf025d3ab4e.tar.bz2 |
Limit the number of pending requests to the max number of file descriptors.
Each renderer is only allowed to use a fraction of that, so that one renderer
doesn't DOS the rest.
The limit improves behavior in edge cases and also imitates the functionality
lost when ResourceLoadScheduler was nuked in Blink. That limit was fixed at 10k, which is larger than the number of FDs we support on many platforms.
As part of this, I cleaned up the unit tests. Instead of checking in each test that we count 0 requests in flight (and missing a few tests), we just DCHECK that there are none in flight at destruction time. This exposed a bug with cross-process navigation, which I've also fixed.
BUG=226319
Review URL: https://chromiumcodereview.appspot.com/13829004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@199300 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/memory/shared_memory.h | 3 | ||||
-rw-r--r-- | base/memory/shared_memory_posix.cc | 8 | ||||
-rw-r--r-- | base/memory/shared_memory_win.cc | 7 | ||||
-rw-r--r-- | base/process_util.h | 4 | ||||
-rw-r--r-- | base/process_util_ios.mm | 18 | ||||
-rw-r--r-- | base/process_util_posix.cc | 21 |
6 files changed, 52 insertions, 9 deletions
diff --git a/base/memory/shared_memory.h b/base/memory/shared_memory.h index 0e90c6e..7f19bd7 100644 --- a/base/memory/shared_memory.h +++ b/base/memory/shared_memory.h @@ -101,6 +101,9 @@ class BASE_EXPORT SharedMemory { // Closes a shared memory handle. static void CloseHandle(const SharedMemoryHandle& handle); + // Returns the maximum number of handles that can be open at once per process. + static size_t GetHandleLimit(); + // Creates a shared memory object as described by the options struct. // Returns true on success and false on failure. bool Create(const SharedMemoryCreateOptions& options); diff --git a/base/memory/shared_memory_posix.cc b/base/memory/shared_memory_posix.cc index 7da1777..63b20f3 100644 --- a/base/memory/shared_memory_posix.cc +++ b/base/memory/shared_memory_posix.cc @@ -13,9 +13,10 @@ #include "base/file_util.h" #include "base/lazy_instance.h" #include "base/logging.h" -#include "base/threading/platform_thread.h" +#include "base/process_util.h" #include "base/safe_strerror_posix.h" #include "base/synchronization/lock.h" +#include "base/threading/platform_thread.h" #include "base/threading/thread_restrictions.h" #include "base/utf_string_conversions.h" @@ -98,6 +99,11 @@ void SharedMemory::CloseHandle(const SharedMemoryHandle& handle) { DPLOG(ERROR) << "close"; } +// static +size_t SharedMemory::GetHandleLimit() { + return base::GetMaxFds(); +} + bool SharedMemory::CreateAndMapAnonymous(size_t size) { return CreateAnonymous(size) && Map(size); } diff --git a/base/memory/shared_memory_win.cc b/base/memory/shared_memory_win.cc index ca0d00f..8f92c35 100644 --- a/base/memory/shared_memory_win.cc +++ b/base/memory/shared_memory_win.cc @@ -87,6 +87,13 @@ void SharedMemory::CloseHandle(const SharedMemoryHandle& handle) { ::CloseHandle(handle); } +// static +size_t SharedMemory::GetHandleLimit() { + // Rounded down from value reported here: + // http://blogs.technet.com/b/markrussinovich/archive/2009/09/29/3283844.aspx + return static_cast<size_t>(1 << 23); +} + bool SharedMemory::CreateAndMapAnonymous(size_t size) { return CreateAnonymous(size) && Map(size); } diff --git a/base/process_util.h b/base/process_util.h index a06f689..2eb516d 100644 --- a/base/process_util.h +++ b/base/process_util.h @@ -223,6 +223,10 @@ BASE_EXPORT extern const char kProcSelfExe[]; // Returns the ID for the parent of the given process. BASE_EXPORT ProcessId GetParentProcessId(ProcessHandle process); +// Returns the maximum number of file descriptors that can be open by a process +// at once. If the number is unavailable, a conservative best guess is returned. +size_t GetMaxFds(); + // Close all file descriptors, except those which are a destination in the // given multimap. Only call this function in a child process where you know // that there aren't any other threads. diff --git a/base/process_util_ios.mm b/base/process_util_ios.mm index 9d96990..7239ed2 100644 --- a/base/process_util_ios.mm +++ b/base/process_util_ios.mm @@ -7,6 +7,7 @@ #import <Foundation/Foundation.h> #include <mach/task.h> #include <stdio.h> +#include <sys/resource.h> #include "base/logging.h" @@ -48,6 +49,23 @@ void RaiseProcessToHighPriority() { // Impossible on iOS. Do nothing. } +size_t GetMaxFds() { + static const rlim_t kSystemDefaultMaxFds = 256; + rlim_t max_fds; + struct rlimit nofile; + if (getrlimit(RLIMIT_NOFILE, &nofile)) { + // Error case: Take a best guess. + max_fds = kSystemDefaultMaxFds; + } else { + max_fds = nofile.rlim_cur; + } + + if (max_fds > INT_MAX) + max_fds = INT_MAX; + + return static_cast<size_t>(max_fds); +} + ProcessMetrics::ProcessMetrics(ProcessHandle process) {} ProcessMetrics::~ProcessMetrics() {} diff --git a/base/process_util_posix.cc b/base/process_util_posix.cc index 98ec183..51ebc00 100644 --- a/base/process_util_posix.cc +++ b/base/process_util_posix.cc @@ -398,13 +398,9 @@ typedef scoped_ptr_malloc<DIR, ScopedDIRClose> ScopedDIR; static const char kFDDir[] = "/proc/self/fd"; #endif -void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) { - // DANGER: no calls to malloc are allowed from now on: - // http://crbug.com/36678 - - // Get the maximum number of FDs possible. - struct rlimit nofile; +size_t GetMaxFds() { rlim_t max_fds; + struct rlimit nofile; if (getrlimit(RLIMIT_NOFILE, &nofile)) { // getrlimit failed. Take a best guess. max_fds = kSystemDefaultMaxFds; @@ -416,11 +412,20 @@ void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) { if (max_fds > INT_MAX) max_fds = INT_MAX; - DirReaderPosix fd_dir(kFDDir); + return static_cast<size_t>(max_fds); +} + +void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) { + // DANGER: no calls to malloc are allowed from now on: + // http://crbug.com/36678 + + // Get the maximum number of FDs possible. + size_t max_fds = GetMaxFds(); + DirReaderPosix fd_dir(kFDDir); if (!fd_dir.IsValid()) { // Fallback case: Try every possible fd. - for (rlim_t i = 0; i < max_fds; ++i) { + for (size_t i = 0; i < max_fds; ++i) { const int fd = static_cast<int>(i); if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO) continue; |