summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorcpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-28 23:51:53 +0000
committercpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-28 23:51:53 +0000
commit568bfb01bcc9612050520f20a01d8f9395c95131 (patch)
treed07b1bfb83e19287b1ad1fd07e313ca53baf200c /base
parentbc2d32a9626d2f43f04fd03bee9cbd2ffada28fd (diff)
downloadchromium_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.cc21
-rw-r--r--base/process_win.cc27
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