OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_WIN_SCOPED_HANDLE_H_ | 5 #ifndef BASE_WIN_SCOPED_HANDLE_H_ |
6 #define BASE_WIN_SCOPED_HANDLE_H_ | 6 #define BASE_WIN_SCOPED_HANDLE_H_ |
7 | 7 |
8 #include <windows.h> | 8 #include <windows.h> |
9 | 9 |
10 #include "base/base_export.h" | 10 #include "base/base_export.h" |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
12 #include "base/location.h" | 12 #include "base/location.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/move.h" | |
14 | 15 |
15 namespace base { | 16 namespace base { |
16 namespace win { | 17 namespace win { |
17 | 18 |
18 // TODO(rvargas): remove this with the rest of the verifier. | 19 // TODO(rvargas): remove this with the rest of the verifier. |
19 #if defined(COMPILER_MSVC) | 20 #if defined(COMPILER_MSVC) |
20 // MSDN says to #include <intrin.h>, but that breaks the VS2005 build. | 21 // MSDN says to #include <intrin.h>, but that breaks the VS2005 build. |
21 extern "C" { | 22 extern "C" { |
22 void* _ReturnAddress(); | 23 void* _ReturnAddress(); |
23 } | 24 } |
24 #define BASE_WIN_GET_CALLER _ReturnAddress() | 25 #define BASE_WIN_GET_CALLER _ReturnAddress() |
25 #elif defined(COMPILER_GCC) | 26 #elif defined(COMPILER_GCC) |
26 #define BASE_WIN_GET_CALLER __builtin_extract_return_addr(\\ | 27 #define BASE_WIN_GET_CALLER __builtin_extract_return_addr(\\ |
27 __builtin_return_address(0)) | 28 __builtin_return_address(0)) |
28 #endif | 29 #endif |
29 | 30 |
30 // Generic wrapper for raw handles that takes care of closing handles | 31 // Generic wrapper for raw handles that takes care of closing handles |
31 // automatically. The class interface follows the style of | 32 // automatically. The class interface follows the style of |
32 // the ScopedStdioHandle class with a few additions: | 33 // the ScopedStdioHandle class with a few additions: |
33 // - IsValid() method can tolerate multiple invalid handle values such as NULL | 34 // - IsValid() method can tolerate multiple invalid handle values such as NULL |
34 // and INVALID_HANDLE_VALUE (-1) for Win32 handles. | 35 // and INVALID_HANDLE_VALUE (-1) for Win32 handles. |
35 // - Receive() method allows to receive a handle value from a function that | 36 // - Receive() method allows to receive a handle value from a function that |
36 // takes a raw handle pointer only. | 37 // takes a raw handle pointer only. |
37 template <class Traits, class Verifier> | 38 template <class Traits, class Verifier> |
38 class GenericScopedHandle { | 39 class GenericScopedHandle { |
40 MOVE_ONLY_TYPE_FOR_CPP_03(GenericScopedHandle, RValue) | |
41 | |
39 public: | 42 public: |
40 typedef typename Traits::Handle Handle; | 43 typedef typename Traits::Handle Handle; |
41 | 44 |
42 GenericScopedHandle() : handle_(Traits::NullHandle()) {} | 45 GenericScopedHandle() : handle_(Traits::NullHandle()) {} |
43 | 46 |
44 explicit GenericScopedHandle(Handle handle) : handle_(Traits::NullHandle()) { | 47 explicit GenericScopedHandle(Handle handle) : handle_(Traits::NullHandle()) { |
45 Set(handle); | 48 Set(handle); |
46 } | 49 } |
47 | 50 |
51 // Move constructor for C++03 move emulation of this type. | |
52 GenericScopedHandle(RValue& other) | |
53 // The type of the underlying object is GenericScopedHandle; we have to | |
54 // reinterpret_cast back to the original type for the call to release to | |
55 // be valid. (See C++11 5.2.10.7) | |
56 : handle_(reinterpret_cast<GenericScopedHandle&>(other).Take()) { | |
jar (doing other things)
2012/08/07 01:00:30
Should be a static_cast (possibly of pointers)? I
alexeypa (please no reviews)
2012/08/07 17:55:14
This code was copied from scoped_handle.h. It rein
| |
57 } | |
58 | |
48 ~GenericScopedHandle() { | 59 ~GenericScopedHandle() { |
49 Close(); | 60 Close(); |
50 } | 61 } |
51 | 62 |
52 bool IsValid() const { | 63 bool IsValid() const { |
53 return Traits::IsHandleValid(handle_); | 64 return Traits::IsHandleValid(handle_); |
54 } | 65 } |
55 | 66 |
67 // Move operator= for C++03 move emulation of this type. | |
68 GenericScopedHandle& operator=(RValue& other) { | |
jar (doing other things)
2012/08/07 01:00:30
I'm a little surprised you didn't pass in a const
alexeypa (please no reviews)
2012/08/07 17:55:14
This is copied from scoped_ptr too. |other| has to
| |
69 Swap(other); | |
70 return *this; | |
71 } | |
72 | |
56 void Set(Handle handle) { | 73 void Set(Handle handle) { |
57 if (handle_ != handle) { | 74 if (handle_ != handle) { |
58 Close(); | 75 Close(); |
59 | 76 |
60 if (Traits::IsHandleValid(handle)) { | 77 if (Traits::IsHandleValid(handle)) { |
61 handle_ = handle; | 78 handle_ = handle; |
62 Verifier::StartTracking(handle, this, BASE_WIN_GET_CALLER, | 79 Verifier::StartTracking(handle, this, BASE_WIN_GET_CALLER, |
63 tracked_objects::GetProgramCounter()); | 80 tracked_objects::GetProgramCounter()); |
64 } | 81 } |
65 } | 82 } |
66 } | 83 } |
67 | 84 |
68 Handle Get() const { | 85 Handle Get() const { |
69 return handle_; | 86 return handle_; |
70 } | 87 } |
71 | 88 |
72 operator Handle() const { | 89 operator Handle() const { |
73 return handle_; | 90 return handle_; |
74 } | 91 } |
75 | 92 |
76 Handle* Receive() { | 93 Handle* Receive() { |
77 DCHECK(!Traits::IsHandleValid(handle_)) << "Handle must be NULL"; | 94 DCHECK(!Traits::IsHandleValid(handle_)) << "Handle must be NULL"; |
78 | 95 |
79 // We cannot track this case :(. Just tell the verifier about it. | 96 // We cannot track this case :(. Just tell the verifier about it. |
80 Verifier::StartTracking(INVALID_HANDLE_VALUE, this, BASE_WIN_GET_CALLER, | 97 Verifier::StartTracking(INVALID_HANDLE_VALUE, this, BASE_WIN_GET_CALLER, |
81 tracked_objects::GetProgramCounter()); | 98 tracked_objects::GetProgramCounter()); |
82 return &handle_; | 99 return &handle_; |
83 } | 100 } |
84 | 101 |
102 void Swap(GenericScopedHandle& other) { | |
103 Handle tmp = handle_; | |
104 handle_ = other.handle_; | |
105 other.handle_ = tmp; | |
106 } | |
107 | |
85 // Transfers ownership away from this object. | 108 // Transfers ownership away from this object. |
86 Handle Take() { | 109 Handle Take() { |
87 Handle temp = handle_; | 110 Handle temp = handle_; |
88 handle_ = Traits::NullHandle(); | 111 handle_ = Traits::NullHandle(); |
89 Verifier::StopTracking(temp, this, BASE_WIN_GET_CALLER, | 112 Verifier::StopTracking(temp, this, BASE_WIN_GET_CALLER, |
90 tracked_objects::GetProgramCounter()); | 113 tracked_objects::GetProgramCounter()); |
91 return temp; | 114 return temp; |
92 } | 115 } |
93 | 116 |
94 // Explicitly closes the owned handle. | 117 // Explicitly closes the owned handle. |
95 void Close() { | 118 void Close() { |
96 if (Traits::IsHandleValid(handle_)) { | 119 if (Traits::IsHandleValid(handle_)) { |
97 Verifier::StopTracking(handle_, this, BASE_WIN_GET_CALLER, | 120 Verifier::StopTracking(handle_, this, BASE_WIN_GET_CALLER, |
98 tracked_objects::GetProgramCounter()); | 121 tracked_objects::GetProgramCounter()); |
99 | 122 |
100 if (!Traits::CloseHandle(handle_)) | 123 if (!Traits::CloseHandle(handle_)) |
101 CHECK(false); | 124 CHECK(false); |
102 | 125 |
103 handle_ = Traits::NullHandle(); | 126 handle_ = Traits::NullHandle(); |
104 } | 127 } |
105 } | 128 } |
106 | 129 |
107 private: | 130 private: |
108 Handle handle_; | 131 Handle handle_; |
109 | |
110 DISALLOW_COPY_AND_ASSIGN(GenericScopedHandle); | |
111 }; | 132 }; |
112 | 133 |
113 #undef BASE_WIN_GET_CALLER | 134 #undef BASE_WIN_GET_CALLER |
114 | 135 |
115 // The traits class for Win32 handles that can be closed via CloseHandle() API. | 136 // The traits class for Win32 handles that can be closed via CloseHandle() API. |
116 class HandleTraits { | 137 class HandleTraits { |
117 public: | 138 public: |
118 typedef HANDLE Handle; | 139 typedef HANDLE Handle; |
119 | 140 |
120 // Closes the handle. | 141 // Closes the handle. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
163 private: | 184 private: |
164 DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits); | 185 DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits); |
165 }; | 186 }; |
166 | 187 |
167 typedef GenericScopedHandle<HandleTraits, VerifierTraits> ScopedHandle; | 188 typedef GenericScopedHandle<HandleTraits, VerifierTraits> ScopedHandle; |
168 | 189 |
169 } // namespace win | 190 } // namespace win |
170 } // namespace base | 191 } // namespace base |
171 | 192 |
172 #endif // BASE_SCOPED_HANDLE_WIN_H_ | 193 #endif // BASE_SCOPED_HANDLE_WIN_H_ |
OLD | NEW |