diff options
author | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-28 23:51:53 +0000 |
---|---|---|
committer | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-28 23:51:53 +0000 |
commit | 568bfb01bcc9612050520f20a01d8f9395c95131 (patch) | |
tree | d07b1bfb83e19287b1ad1fd07e313ca53baf200c /base | |
parent | bc2d32a9626d2f43f04fd03bee9cbd2ffada28fd (diff) | |
download | chromium_src-568bfb01bcc9612050520f20a01d8f9395c95131.zip chromium_src-568bfb01bcc9612050520f20a01d8f9395c95131.tar.gz chromium_src-568bfb01bcc9612050520f20a01d8f9395c95131.tar.bz2 |
Add a more comprehensive background mode for a process.
It also lowers the priority of IO.
-Windows vista, win7 only
-Bad usage of closehandle fixed
BUG=none
TEST=unittest included
Review URL: http://codereview.chromium.org/6880265
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83447 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/process_util_unittest.cc | 21 | ||||
-rw-r--r-- | base/process_win.cc | 27 |
2 files changed, 40 insertions, 8 deletions
diff --git a/base/process_util_unittest.cc b/base/process_util_unittest.cc index 7082408..d27c491 100644 --- a/base/process_util_unittest.cc +++ b/base/process_util_unittest.cc @@ -260,8 +260,25 @@ TEST_F(ProcessUtilTest, SetProcessBackgrounded) { base::ProcessHandle handle = this->SpawnChild("SimpleChildProcess", false); base::Process process(handle); int old_priority = process.GetPriority(); - process.SetProcessBackgrounded(true); - process.SetProcessBackgrounded(false); + if (process.SetProcessBackgrounded(true)) { + EXPECT_TRUE(process.IsProcessBackgrounded()); + EXPECT_TRUE(process.SetProcessBackgrounded(false)); + EXPECT_FALSE(process.IsProcessBackgrounded()); + } + int new_priority = process.GetPriority(); + EXPECT_EQ(old_priority, new_priority); +} + +// Same as SetProcessBackgrounded but to this very process. It uses +// a different code path at least for Windows. +TEST_F(ProcessUtilTest, SetProcessBackgroundedSelf) { + base::Process process(base::Process::Current().handle()); + int old_priority = process.GetPriority(); + if (process.SetProcessBackgrounded(true)) { + EXPECT_TRUE(process.IsProcessBackgrounded()); + EXPECT_TRUE(process.SetProcessBackgrounded(false)); + EXPECT_FALSE(process.IsProcessBackgrounded()); + } int new_priority = process.GetPriority(); EXPECT_EQ(old_priority, new_priority); } diff --git a/base/process_win.cc b/base/process_win.cc index 2873d91..0a38805 100644 --- a/base/process_win.cc +++ b/base/process_win.cc @@ -6,13 +6,16 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/process_util.h" +#include "base/win/windows_version.h" namespace base { void Process::Close() { if (!process_) return; - ::CloseHandle(process_); + // Don't call CloseHandle on a pseudo-handle. + if (process_ != ::GetCurrentProcess()) + ::CloseHandle(process_); process_ = NULL; } @@ -28,14 +31,26 @@ bool Process::IsProcessBackgrounded() const { DWORD priority = GetPriority(); if (priority == 0) return false; // Failure case. - return priority == BELOW_NORMAL_PRIORITY_CLASS; + return ((priority == BELOW_NORMAL_PRIORITY_CLASS) || + (priority == IDLE_PRIORITY_CLASS)); } bool Process::SetProcessBackgrounded(bool value) { if (!process_) return false; - DWORD priority = value ? BELOW_NORMAL_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS; - return (SetPriorityClass(process_, priority) != 0); + // Vista and above introduce a real background mode, which not only + // sets the priority class on the threads but also on the IO generated + // by it. Unfortunately it can only be set for the calling process. + DWORD priority; + if ((base::win::GetVersion() >= base::win::VERSION_VISTA) && + (process_ == ::GetCurrentProcess())) { + priority = value ? PROCESS_MODE_BACKGROUND_BEGIN : + PROCESS_MODE_BACKGROUND_END; + } else { + priority = value ? BELOW_NORMAL_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS; + } + + return (::SetPriorityClass(process_, priority) != 0); } ProcessId Process::pid() const { @@ -51,12 +66,12 @@ bool Process::is_current() const { // static Process Process::Current() { - return Process(GetCurrentProcess()); + return Process(::GetCurrentProcess()); } int Process::GetPriority() const { DCHECK(process_); - return GetPriorityClass(process_); + return ::GetPriorityClass(process_); } } // namespace base |