Improve performance of registering font preferences
[chromium-blink-merge.git] / base / win / scoped_process_information.cc
blob4adb8d46c36520e3b71f71508fc0cf1639b35e1f
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/win/scoped_process_information.h"
7 #include "base/logging.h"
8 #include "base/win/scoped_handle.h"
10 namespace base {
11 namespace win {
13 namespace {
15 // Closes the provided handle if it is not NULL.
16 void CheckAndCloseHandle(HANDLE handle) {
17 if (!handle)
18 return;
19 if (::CloseHandle(handle))
20 return;
21 CHECK(false);
24 // Duplicates source into target, returning true upon success. |target| is
25 // guaranteed to be untouched in case of failure. Succeeds with no side-effects
26 // if source is NULL.
27 bool CheckAndDuplicateHandle(HANDLE source, HANDLE* target) {
28 if (!source)
29 return true;
31 HANDLE temp = NULL;
32 if (!::DuplicateHandle(::GetCurrentProcess(), source,
33 ::GetCurrentProcess(), &temp, 0, FALSE,
34 DUPLICATE_SAME_ACCESS)) {
35 DPLOG(ERROR) << "Failed to duplicate a handle.";
36 return false;
38 *target = temp;
39 return true;
42 } // namespace
44 ScopedProcessInformation::ScopedProcessInformation()
45 : process_information_() {
48 ScopedProcessInformation::~ScopedProcessInformation() {
49 Close();
52 PROCESS_INFORMATION* ScopedProcessInformation::Receive() {
53 DCHECK(!IsValid()) << "process_information_ must be NULL";
54 return &process_information_;
57 bool ScopedProcessInformation::IsValid() const {
58 return process_information_.hThread || process_information_.hProcess ||
59 process_information_.dwProcessId || process_information_.dwThreadId;
63 void ScopedProcessInformation::Close() {
64 CheckAndCloseHandle(process_information_.hThread);
65 CheckAndCloseHandle(process_information_.hProcess);
66 Reset();
69 void ScopedProcessInformation::Swap(ScopedProcessInformation* other) {
70 DCHECK(other);
71 PROCESS_INFORMATION temp = other->process_information_;
72 other->process_information_ = process_information_;
73 process_information_ = temp;
76 bool ScopedProcessInformation::DuplicateFrom(
77 const ScopedProcessInformation& other) {
78 DCHECK(!IsValid()) << "target ScopedProcessInformation must be NULL";
79 DCHECK(other.IsValid()) << "source ScopedProcessInformation must be valid";
81 ScopedHandle duplicate_process;
82 ScopedHandle duplicate_thread;
84 if (CheckAndDuplicateHandle(other.process_handle(),
85 duplicate_process.Receive()) &&
86 CheckAndDuplicateHandle(other.thread_handle(),
87 duplicate_thread.Receive())) {
88 process_information_.dwProcessId = other.process_id();
89 process_information_.dwThreadId = other.thread_id();
90 process_information_.hProcess = duplicate_process.Take();
91 process_information_.hThread = duplicate_thread.Take();
92 return true;
95 return false;
98 PROCESS_INFORMATION ScopedProcessInformation::Take() {
99 PROCESS_INFORMATION process_information = process_information_;
100 Reset();
101 return process_information;
104 HANDLE ScopedProcessInformation::TakeProcessHandle() {
105 HANDLE process = process_information_.hProcess;
106 process_information_.hProcess = NULL;
107 process_information_.dwProcessId = 0;
108 return process;
111 HANDLE ScopedProcessInformation::TakeThreadHandle() {
112 HANDLE thread = process_information_.hThread;
113 process_information_.hThread = NULL;
114 process_information_.dwThreadId = 0;
115 return thread;
118 void ScopedProcessInformation::Reset() {
119 process_information_.hThread = NULL;
120 process_information_.hProcess = NULL;
121 process_information_.dwProcessId = 0;
122 process_information_.dwThreadId = 0;
125 } // namespace win
126 } // namespace base